docs(P00): grill — v0.4 NFR adversarial review (G-015, G-016)

Nine-axis scorecard: 8 PASS + 1 CONDITIONAL→fixed. SHIP Phase 0 (0.84).
G-015: cross-const test MUST assert absolute 800/0 values (paired-drift
guard) — already in P1-02-01. G-016: docs-build job MUST need go-test
(firewall-gates-docs-build, no false-green) — applied to P3-01-01.
D-001 filter enforced; NFR purity gate enforceable.

---ci---
project: oy
phase: 0
milestone: v0.4
status: grill
tag_base: v0.3.x
milestone_type: nfr
---/ci---
This commit is contained in:
2026-08-17 23:28:11 +00:00
parent 5e06b14ddf
commit d88d2eaeb8
2 changed files with 71 additions and 1 deletions
+70
View File
@@ -316,3 +316,73 @@ Binding decisions: 4 (G-011..G-014)
Escalations: 0
Overall: SHIP Phase 0 with binding changes (confidence 0.80)
```
---
## Grill Review: OpenYield (oy) — v0.4 (Refinement — NFR) Phase 0
> **Reviewer**: CIAgent adversarial grill (red-team, full autonomy)
> **Date**: 2026-08-17
> **Target**: Phase 0 artifacts (PROJECT.md v0.4 section, REQUIREMENTS.md v0.4 table, ARCHITECTURE.md v0.4 section, PERSONAS.md v0.4, PLANS.md v0.4 plan, config.json) + v0.3 codebase baseline
> **Milestone**: v0.4 — Refinement (NFR)
> **Autonomy**: full (decision_confidence_threshold = 0.60)
> **Mode**: multi-project (slug `oy`)
### Methodology
Each of nine axes was scored against concrete evidence. The v0.4 scope is small (4 REQs, 12 tasks, 5 phases including P0+P4) so the grill is correspondingly focused. The central question: **is v0.4 a legitimate NFR milestone or is it a scope-creep / busywork milestone that should be a single patch or deferred?**
### Evidence baseline (verified against the actual repo)
- v0.3 milestone COMPLETE: checkpoint `milestone_complete: true`, release `v0.2.6` (id 739), HEAD on `main`. Verified.
- v0.3 forward-references for v0.4 scope: REVIEW.md P2 (A-304 cross-const), AUDIT.md §193 (P1-1/P1-2 council divergences, P2 bearers no-op), GRILL.md G-014 (lexicon helper). Verified — all four REQ-029..REQ-032 map to a real v0.3 forward-reference.
- The two synthetic self-test tables are byte-identical duplicates: `lexicon_meta_test.go:93-104` and `lexicon_meta_docs/lexicon_meta_docs_test.go:157-168`. Verified by diff — G-014 drift risk is REAL, not theoretical.
- `x/hub/types/types.go:51,56` defines `LendingCouponCapBps = uint32(800)` and `LendingCouponFloorBps = uint32(0)`; `x/bond/types/types.go:21,26` defines `CouponCapBps = 800` and `CouponFloorBps = 0`. No automated cross-check exists (only a cross-doc comment). Verified — A-304 drift risk is REAL.
- `SignalKindCount = 4` is already a locked-const test (`x/council/types/types_test.go:102`). The AUDIT P1-2 rationale (Freeholder is eligibility, Guild is council tier, Capital is committed-capital) is in AUDIT.md but NOT in ARCHITECTURE.md. Verified — the documentation gap is REAL.
- No `.github/workflows/` and no `.gitea/workflows/` directory exists. Verified — REQ-032 is net-new CI, not a modification.
### Forcing Questions and Verdicts
**1. Is v0.4 a legitimate milestone, or should these fixes be a single v0.3.x patch?**
The four fixes are independent (lexicon helper, cross-const test, lifecycle docs, CI). Bundling them into a milestone with per-phase ship (P1..P3 each ship a patch) gives each fix its own release tag and audit trail. The alternative (one v0.3.1 patch with all four) loses the per-fix release boundary. D-052 phase ordering keeps each phase independently shippable. **Verdict: legitimate milestone** — the per-phase ship cadence (D-052) is the value, not the milestone label. Confidence 0.82.
**2. Does REQ-031 violate the D-001 refinement-only filter by documenting a divergence that mentions `Proposal`/`VoteOption` (which are `feat:`-class types)?**
No. DOCUMENTING a deferred `feat:` in ARCHITECTURE.md is `docs`, not `feat:`. REQ-031 adds NO enum types and changes NO locked consts. The regression-guard test asserts the CURRENT shape (4-signal) is intentional — it does not ADD a type. The D-001 filter rejects the `feat:` (adding Proposal/VoteOption) but accepts the `docs` (documenting why they are absent). **Verdict: passes D-001**. Confidence 0.85.
**3. Does REQ-030's test-only import of `x/bond/types` into `x/hub/types` violate G-003?**
No. G-003 forbids PRODUCTION cross-module struct imports. The import is in `x/hub/types/cross_const_test.go` (a `_test.go` file). The v0.2 GRILL G-003 explicitly documented the test-import exemption (and `x/bearers/types/types_test.go:7` already imports `x/processing/types` as a test-only precedent). The plan's P1-02-01 verification includes a grep confirming no PRODUCTION `.go` file in `x/hub/types/` imports `x/bond/types`. **Verdict: G-003 intact**. Confidence 0.88.
**4. Does REQ-032 (CI workflow with mkdocs) violate G-006 (zero Go deps)?**
No. The CI workflow installs mkdocs + mkdocs-material in a SEPARATE CI job (`docs-build`), not in `go.mod`. `go.mod` is not modified by the workflow (Python deps are isolated to the CI runner). The plan's P3-99-01 verification confirms `go.mod` diff is empty. **Verdict: G-006 intact**. Confidence 0.90.
**5. Is the NFR purity gate enforceable?**
Yes. The gate is `git log --grep "^feat:" <milestone-range>` returns zero. The v0.4 plan explicitly rejects `feat:`-class work (D-050 rejects Proposal/VoteOption; D-051 rejects Pages publish as a feature). The P4 audit (P4-02-01) runs the gate. The only risk: a commit MESSAGE accidentally using `feat:` prefix — the gate checks the prefix, not the content. **Verdict: enforceable**. Confidence 0.85.
### Binding Decisions (G-015..G-016)
| ID | Binding Decision | Rationale | Confidence | Source |
|----|------------------|-----------|------------|--------|
| **G-015** | The P1-02-01 cross-const test MUST also assert the absolute mission-locked values (`LendingCouponCapBps == 800`, `LendingCouponFloorBps == 0`, `CouponCapBps == 800`, `CouponFloorBps == 0`) in addition to the cross-package equality. The cross-package equality test alone would pass if BOTH consts drifted to the same wrong value (e.g., both 900). The absolute-value assertion catches a paired drift. | The plan's P1-02-01 already includes `TestConstsAreMissionLocked800And0` (good). This binding makes it MANDATORY: the test must assert BOTH the cross-equality AND the absolute 800/0 values. Without the absolute assertion, a paired drift (both consts change to the same wrong value) is undetected. | 0.85 | PLANS.md P1-02-01 |
| **G-016** | The P3-01-01 CI workflow MUST run `go test ./...` BEFORE `mkdocs build` is allowed to proceed IF the jobs are serial, OR the `go-test` job must be a REQUIRED check (not advisory) if the jobs are parallel. The lexicon firewall (`go test ./...`) is the higher-priority check; a docs build that passes while the lexicon firewall fails is a false-green deploy. The plan's P3-01-01 runs the jobs in parallel (no dependency) — acceptable ONLY if both are required-status checks. If Gitea Actions does not support required-status on artifact-upload jobs, the jobs MUST be serial (`go-test` then `docs-build` depends-on `go-test`). | A docs build that succeeds while the lexicon firewall fails would publish (or artifact) a docs site from a repo that has a lexicon violation — a false-green. The firewall must gate the docs build. | 0.78 | PLANS.md P3-01-01 |
### Nine-Axis Scorecard (v0.4 Phase 0)
```
1. Scope — PASS (0.85) scoped to 4 v0.3 forward-refs; no scope creep
2. Feasibility — PASS (0.88) all 4 fixes are mechanical; no research risk
3. Specification — PASS (0.82) REQs clear; D-047..D-053 unambiguous
4. Decomposition — PASS (0.80) P1..P3 independent vertical slices; P4 review/ship
5. Risk — PASS (0.85) NFR scope (no behavioral change); low risk
6. Dependency — PASS (0.82) no cross-phase hard blockers; G-003 test-exempt documented
7. Testing — PASS (0.85) each fix has a verification task; NFR purity gate in P4
8. Maintainability — CONDITIONAL (0.78) → fixed by G-015 (absolute-value assertion)
9. Adversarial — PASS (0.82) D-001 filter enforced; no feat: creep
Binding decisions: 2 (G-015, G-016)
Escalations: 0
Overall: SHIP Phase 0 with binding changes (confidence 0.84)
```
### v0.4 Grill Verdict
**SHIP Phase 0** with G-015 (absolute-value const assertion in P1-02-01) and G-016 (firewall-gates-docs-build in P3-01-01) applied. The v0.4 NFR milestone is a legitimate, well-scoped refinement cycle that closes three real v0.3 forward-references (G-014, A-304, AUDIT §193) and lands the deferred docs CI (D-046). The D-001 refinement-only filter is enforced throughout; the NFR purity gate in P4 is enforceable. No escalations.
+1 -1
View File
@@ -901,7 +901,7 @@ No hard cross-phase blockers (all three execution phases are independent vertica
| Task ID | REQ | Persona | Files | Deliverable | Must-have verification | Blocked-by |
|---|---|---|---|---|---|---|
| P3-01-01 | REQ-032 | lead-developer | `.gitea/workflows/docs-build.yml` (NEW) | Gitea Actions workflow (YAML). Triggers: on push (all branches). Jobs: (1) `go-test` — setup Go 1.22, `go test ./...` (runs lexicon firewall + all x/* tests); (2) `docs-build` — setup Python, `pip install mkdocs mkdocs-material`, `mkdocs build` (produces `site/`), upload `site/` as an artifact. The two jobs run in parallel (no dependency). `go.mod` is NOT modified (Python deps are isolated to the `docs-build` job). Doc comment in the YAML references D-046 (forward-reference) and D-051 (no Pages publish). | YAML parses (validate with a YAML linter or `python -c "import yaml; yaml.safe_load(open('.gitea/workflows/docs-build.yml'))"`); `go test ./...` command matches the local green baseline; `mkdocs build` command matches the README's local build invocation; no `go.mod` change. | — |
| P3-01-01 | REQ-032 | lead-developer | `.gitea/workflows/docs-build.yml` (NEW) | Gitea Actions workflow (YAML). Triggers: on push (all branches). Jobs: (1) `go-test` — setup Go 1.22, `go test ./...` (runs lexicon firewall + all x/* tests); (2) `docs-build` — setup Python, `pip install mkdocs mkdocs-material`, `mkdocs build` (produces `site/`), upload `site/` as an artifact. **G-016 binding**: the `docs-build` job MUST depend on `go-test` (serial: `needs: go-test`), so a lexicon-firewall failure blocks the docs build (no false-green docs build from a repo with a lexicon violation). `go.mod` is NOT modified (Python deps are isolated to the `docs-build` job). Doc comment in the YAML references D-046 (forward-reference), D-051 (no Pages publish), and G-016 (firewall-gates-docs-build). | YAML parses; `go test ./...` command matches the local green baseline; `mkdocs build` command matches the README's local build invocation; `docs-build` job has `needs: go-test`; no `go.mod` change. | — |
### Wave 2 — Verification (blocked-by Wave 1)