---
id: ADR-pool.tdd-emission-and-graph-rot-remediation
status: Pool
lane: heavy
parent: GHI-160
---

# ADR-0.41.0: TDD Emission and Governance Graph Rot Remediation

## Persona

**Active persona:** `main-session` — craftsperson who writes Python the way it was meant to be written, sees modules whole before touching a line, and treats governance not as overhead but as the discipline that keeps work honest.

This ADR is authored under the "DO IT RIGHT" maxim. Every OBPI in this decomposition is expected to Close The Loop: read the surface before changing it, write a failing test before writing implementation, run the observed-output check, and emit `tdd_red_observed` / `tdd_green_observed` events as the *result* of the discipline, not as a post-hoc claim. The anti-pattern canon in AGENTS.md is the authoring frame for every OBPI here — particularly test-dump theater, which this ADR exists to detect and prevent.

## Intent

GHI-160 surfaced systemic rot across gzkit's governance graph during the ADR-0.25.0 closeout session on 2026-04-15. Two failure families coexist. First: 29 of 55 ADRs had zero code-REQs in the coverage graph because the REQ-X.Y.Z-NN-MM identifier convention postdated much of the codebase and older OBPIs were never retroactively converted. Phases 1-4 of the remedy audited, backfilled REQ IDs across 260 briefs, and decorated orphan tests. Second: the TDD Red-Green-Refactor discipline that Gate 2 names has no canonical emission channel — ARB receipts are QA-step outcomes where exit_status=0 means 'success', which actively conflates with TDD RED where exit_status!=0 is the correct outcome. Agents either fabricate RED in commit prose, skip RED entirely (test-dump theater), or do the work honestly but leave no verifiable trace. The operator's explicit guidance: 'ARB may not be the best place to report RED. This would be an independent set of TDD emissions or just emissions out to the main ledger.' This ADR closes both failure families: it authors the canonical TDD emission surface as first-class ledger events + CLI commands with verification semantics (not trust-based emission), and retroactively houses Phases 1-7 of the GHI-160 remedy program under a proper ADR so the work has governance anchor rather than being grandfathered audit-artifact exceptions in perpetuity. ADR-0.25.0 closeout is explicitly paused until this ADR's OBPIs complete.

## Decision

Author a new CLI surface `gz tdd` with verified emission semantics, back it with two new typed ledger events, and integrate it with the attestation-enrichment receipt-ID requirement and the Phase 6 validate checks.

**CLI surface:**
- `gz tdd red <test-target> --req REQ-X.Y.Z-NN-MM` — runs the test target via subprocess, verifies exit code is non-zero, parses the runner output to classify failure kind (assertion | missing_attribute | missing_module | name_error | collection_error), rejects collection-errors as 'test infrastructure broken, not RED', emits `tdd_red_observed` event on success, returns the failing output.
- `gz tdd green <test-target> --req REQ-X.Y.Z-NN-MM [--red-ref <event-id>]` — runs the test target, verifies exit code is zero, emits `tdd_green_observed` event with optional link to the prior RED event, returns test count and timestamps.
- `gz tdd chain <req-id>` — reports the RED→GREEN history for a REQ, showing the full cycle trace.
- Exit codes follow the 4-code map: 0 = emission recorded, 1 = verification failed (wrong exit code or unclassifiable), 2 = subprocess/IO error, 3 = REQ not found in coverage graph.

**Ledger event types:**
- `tdd_red_observed`: schema fields include req_id, test_target, stdout_digest, exit_code, failure_kind, agent, timestamp.
- `tdd_green_observed`: schema fields include req_id, test_target, red_event_ref (optional), exit_code, test_count, agent, timestamp.
- Both events validate against `data/schemas/tdd_event.schema.json` (new).

**Verification (the core value):**
The emission channel is trust-based ONLY to the degree that the agent can be trusted to invoke the correct command at the correct moment. Everything else is machine-verified: RED must actually fail, GREEN must actually pass, failure kind is classified from the real runner output, not from a prose claim. This closes the loophole where agents write tests after implementation and claim RED happened.

**Integration:**
- Update `.gzkit/rules/attestation-enrichment.md` to accept `tdd_red_observed` and `tdd_green_observed` event IDs as valid citations for Gate 2 TDD claims, alongside existing ARB receipt IDs.
- Update `.gzkit/rules/tests.md` Red-Green-Refactor section to cite the `gz tdd` commands as the canonical way to produce verifiable evidence.
- Update `docs/user/commands/tdd.md` (new manpage) and runbook.
- Phase 6's `gz validate --commit-trailers` and `gz validate --requirements` checks fold into the decomposition evidence for this ADR.

**Retroactive housing:**
Phases 1-7 of GHI-160 (audit, --include-doc flag, REQ backfill across 260 briefs, orphan @covers, gz validate --requirements, gz validate --commit-trailers, TASK backfill for GHI-153/155/156 fixes) are documented in this ADR's Evidence section and linked from artifacts/audits/ghi-160-phase-7-task-backfill.md. The Phase 7 audit's grandfather list becomes the ADR's formal scope statement rather than an indefinite exception.

**Checklist decomposition (5 OBPIs — see Checklist section below):**
OBPI-01: typed ledger events + schema. OBPI-02: `gz tdd` CLI verified emission. OBPI-03: attestation-enrichment + rules integration. OBPI-04: runbook + manpage + docs. OBPI-05: retroactive governance housing for GHI-160 Phases 1-7 (audit artifact linkage, closeout evidence, ledger proof).

**Forcing-function stress tests applied during design:**
- Pre-mortem: 'It is 18 months from now, this failed spectacularly. Why?' — Answer: because `gz tdd red` verification was too lenient and agents discovered ways to fake RED by, e.g., raising an assertion inside the code under test rather than in the test itself. Mitigation: failure_kind must come from the TEST file's stack frame, not the code-under-test frame. This is a tight corner in the verifier but non-negotiable.
- Reversibility: two-way door. Ledger events are append-only but adding new event types is additive; the CLI is a new surface that can be deprecated without affecting existing surfaces.
- Smallest version: if we had half the time, we would cut `gz tdd chain` and ship only `red` + `green`. Chain is a convenience reporter, not the core decision.
- 2am operator question: 'The ceremony is blocked because a REQ has no RED event. Where do I look?' — Answer: `gz tdd chain <req-id>` shows the gap. If the chain is empty and the REQ has test coverage (`gz covers --req`), the agent skipped emission — fix by running the tests under `gz tdd green` retroactively (which will emit GREEN without requiring a prior RED for already-covered REQs, but will flag the missing-RED condition in the attestation-enrichment rule).

## Comparator Uplift (2026-05-07)

Superpowers' TDD discipline and Specmatic's executable-contract posture both
belong here. TDD emissions should bind not only red/green proof, but the spec,
contract surface, or workflow stage they protect, so graph rot is visible before
review or attestation tries to rely on stale proof.

## Consequences

### Positive

1. TDD RED/GREEN becomes a first-class, machine-verifiable event class — the Red-Green-Refactor discipline that Gate 2 names now has a canonical emission channel with real verification, not trust.
2. 'Test-dump theater' becomes detectable — `gz tdd` cannot be fooled by writing tests after implementation because the RED event requires a genuinely failing run at a specific moment, signed into the append-only ledger.
3. Attestation enrichment gains a second receipt class (alongside ARB) — agents citing 'Gate 2 tests pass' can cite the specific TDD event IDs, and reviewers can verify the RED→GREEN sequence by timestamp.
4. GHI-160 Phases 1-7 gain proper governance housing — no more perpetual grandfather exceptions in audit artifacts.
5. Phase 6 `gz validate` checks (--requirements, --commit-trailers) now trace to a governing ADR's OBPIs rather than orphan Phase commits.
6. The CLI surface is portable — any GovZero-compliant repo that adopts gzkit gains TDD emission for free.
7. The ADR-0.25.0 closeout (which the operator explicitly paused) has a clear resume condition: this ADR's OBPIs complete and the governance graph is verifiable end-to-end.

### Negative

1. New CLI surface: `gz tdd` is a new top-level verb. Heavy-lane ADR. This expands the CLI doctrine and requires manpage, help text, and runbook integration.
2. New ledger event types: schema additions are backward-compatible but require migration for existing ledger consumers. The validation + replay tooling must be updated to recognize the new types.
3. Verification semantics are opinionated: the RED classifier may reject edge cases (e.g., a test that fails because of a legitimate flaky assertion rather than missing behavior) and force agent rework. This is intentional — a false-negative here is better than a false-positive that accepts fake RED — but it increases the friction of RED emission.
4. Agent workflow change: the TDD cycle now includes two explicit CLI invocations per REQ. This is the entire point (verifiable emission) but it adds a new step that must be captured in every skill that mentions TDD.
5. Retroactive housing is not free: linking Phases 1-7 of the GHI-160 program to OBPI-05 requires walking the commit history and updating audit artifacts. The Phase 7 audit becomes the primary evidence artifact for OBPI-05.
6. Schema drift risk: the new event types live in data/schemas/tdd_event.schema.json. Any future change to the schema requires a migration and a deprecation path.
7. The RED verification is an AST/runner-output-parsing task — classification bugs (e.g., mis-parsing pytest output because we only support unittest today) will surface as false 'RED is invalid' errors. Must be actively maintained.

## Decomposition Scorecard

<!-- Deterministic OBPI sizing: score each dimension 0/1/2. -->
<!-- Cutoffs are notional defaults and should be calibrated over time from project evidence. -->

- Data/State: 2
- Logic/Engine: 2
- Interface: 2
- Observability: 1
- Lineage: 2
- Dimension Total: 9
- Baseline Range: 5+
- Baseline Selected: 5
- Split Single-Narrative: 0
- Split Surface Boundary: 0
- Split State Anchor: 0
- Split Testability Ceiling: 0
- Split Total: 0
- Final Target OBPI Count: 5

## Checklist

<!-- Each item becomes an OBPI (One Brief Per Item). Sequential numbering, no gaps. -->

- [ ] Typed ledger events tdd_red_observed and tdd_green_observed with JSON schema
- [ ] gz tdd red/green/chain CLI commands with verified emission semantics
- [ ] Attestation-enrichment rule integration accepting TDD event citations
- [ ] Runbook, manpage, and docs for gz tdd + tests.md rule update
- [ ] Retroactive governance housing for GHI-160 Phases 1-7 + Phase 6 validate-check evidence linkage

## Q&A Transcript

<!-- Interview transcript preserved for context -->

*Interview conducted: 2026-04-15T13:08:39.312471*

### Q: What is the ADR identifier? (e.g., ADR-0.1.0)

**A:** ADR-0.41.0

### Q: What is the title of this ADR?

**A:** TDD Emission and Governance Graph Rot Remediation

### Q: What is the semantic version?

**A:** 0.41.0

### Q: Which lane? (lite = internal changes, heavy = external contracts)

**A:** heavy

### Q: What is the parent brief ID?

**A:** GHI-160

### Q: What problem are we solving? What is the specific goal of this ADR?

**A:** GHI-160 surfaced systemic rot across gzkit's governance graph during the ADR-0.25.0 closeout session on 2026-04-15. Two failure families coexist. First: 29 of 55 ADRs had zero code-REQs in the coverage graph because the REQ-X.Y.Z-NN-MM identifier convention postdated much of the codebase and older OBPIs were never retroactively converted. Phases 1-4 of the remedy audited, backfilled REQ IDs across 260 briefs, and decorated orphan tests. Second: the TDD Red-Green-Refactor discipline that Gate 2 names has no canonical emission channel — ARB receipts are QA-step outcomes where exit_status=0 means 'success', which actively conflates with TDD RED where exit_status!=0 is the correct outcome. Agents either fabricate RED in commit prose, skip RED entirely (test-dump theater), or do the work honestly but leave no verifiable trace. The operator's explicit guidance: 'ARB may not be the best place to report RED. This would be an independent set of TDD emissions or just emissions out to the main ledger.' This ADR closes both failure families: it authors the canonical TDD emission surface as first-class ledger events + CLI commands with verification semantics (not trust-based emission), and retroactively houses Phases 1-7 of the GHI-160 remedy program under a proper ADR so the work has governance anchor rather than being grandfathered audit-artifact exceptions in perpetuity. ADR-0.25.0 closeout is explicitly paused until this ADR's OBPIs complete.

### Q: What did we decide? Be specific about the approach, libraries, patterns.

**A:** Author a new CLI surface `gz tdd` with verified emission semantics, back it with two new typed ledger events, and integrate it with the attestation-enrichment receipt-ID requirement and the Phase 6 validate checks.

**CLI surface:**
- `gz tdd red <test-target> --req REQ-X.Y.Z-NN-MM` — runs the test target via subprocess, verifies exit code is non-zero, parses the runner output to classify failure kind (assertion | missing_attribute | missing_module | name_error | collection_error), rejects collection-errors as 'test infrastructure broken, not RED', emits `tdd_red_observed` event on success, returns the failing output.
- `gz tdd green <test-target> --req REQ-X.Y.Z-NN-MM [--red-ref <event-id>]` — runs the test target, verifies exit code is zero, emits `tdd_green_observed` event with optional link to the prior RED event, returns test count and timestamps.
- `gz tdd chain <req-id>` — reports the RED→GREEN history for a REQ, showing the full cycle trace.
- Exit codes follow the 4-code map: 0 = emission recorded, 1 = verification failed (wrong exit code or unclassifiable), 2 = subprocess/IO error, 3 = REQ not found in coverage graph.

**Ledger event types:**
- `tdd_red_observed`: schema fields include req_id, test_target, stdout_digest, exit_code, failure_kind, agent, timestamp.
- `tdd_green_observed`: schema fields include req_id, test_target, red_event_ref (optional), exit_code, test_count, agent, timestamp.
- Both events validate against `data/schemas/tdd_event.schema.json` (new).

**Verification (the core value):**
The emission channel is trust-based ONLY to the degree that the agent can be trusted to invoke the correct command at the correct moment. Everything else is machine-verified: RED must actually fail, GREEN must actually pass, failure kind is classified from the real runner output, not from a prose claim. This closes the loophole where agents write tests after implementation and claim RED happened.

**Integration:**
- Update `.gzkit/rules/attestation-enrichment.md` to accept `tdd_red_observed` and `tdd_green_observed` event IDs as valid citations for Gate 2 TDD claims, alongside existing ARB receipt IDs.
- Update `.gzkit/rules/tests.md` Red-Green-Refactor section to cite the `gz tdd` commands as the canonical way to produce verifiable evidence.
- Update `docs/user/commands/tdd.md` (new manpage) and runbook.
- Phase 6's `gz validate --commit-trailers` and `gz validate --requirements` checks fold into the decomposition evidence for this ADR.

**Retroactive housing:**
Phases 1-7 of GHI-160 (audit, --include-doc flag, REQ backfill across 260 briefs, orphan @covers, gz validate --requirements, gz validate --commit-trailers, TASK backfill for GHI-153/155/156 fixes) are documented in this ADR's Evidence section and linked from artifacts/audits/ghi-160-phase-7-task-backfill.md. The Phase 7 audit's grandfather list becomes the ADR's formal scope statement rather than an indefinite exception.

**Checklist decomposition (5 OBPIs — see Checklist section below):**
OBPI-01: typed ledger events + schema. OBPI-02: `gz tdd` CLI verified emission. OBPI-03: attestation-enrichment + rules integration. OBPI-04: runbook + manpage + docs. OBPI-05: retroactive governance housing for GHI-160 Phases 1-7 (audit artifact linkage, closeout evidence, ledger proof).

**Forcing-function stress tests applied during design:**
- Pre-mortem: 'It is 18 months from now, this failed spectacularly. Why?' — Answer: because `gz tdd red` verification was too lenient and agents discovered ways to fake RED by, e.g., raising an assertion inside the code under test rather than in the test itself. Mitigation: failure_kind must come from the TEST file's stack frame, not the code-under-test frame. This is a tight corner in the verifier but non-negotiable.
- Reversibility: two-way door. Ledger events are append-only but adding new event types is additive; the CLI is a new surface that can be deprecated without affecting existing surfaces.
- Smallest version: if we had half the time, we would cut `gz tdd chain` and ship only `red` + `green`. Chain is a convenience reporter, not the core decision.
- 2am operator question: 'The ceremony is blocked because a REQ has no RED event. Where do I look?' — Answer: `gz tdd chain <req-id>` shows the gap. If the chain is empty and the REQ has test coverage (`gz covers --req`), the agent skipped emission — fix by running the tests under `gz tdd green` retroactively (which will emit GREEN without requiring a prior RED for already-covered REQs, but will flag the missing-RED condition in the attestation-enrichment rule).

### Q: What good things result from this decision? List benefits.

**A:** 1. TDD RED/GREEN becomes a first-class, machine-verifiable event class — the Red-Green-Refactor discipline that Gate 2 names now has a canonical emission channel with real verification, not trust.
2. 'Test-dump theater' becomes detectable — `gz tdd` cannot be fooled by writing tests after implementation because the RED event requires a genuinely failing run at a specific moment, signed into the append-only ledger.
3. Attestation enrichment gains a second receipt class (alongside ARB) — agents citing 'Gate 2 tests pass' can cite the specific TDD event IDs, and reviewers can verify the RED→GREEN sequence by timestamp.
4. GHI-160 Phases 1-7 gain proper governance housing — no more perpetual grandfather exceptions in audit artifacts.
5. Phase 6 `gz validate` checks (--requirements, --commit-trailers) now trace to a governing ADR's OBPIs rather than orphan Phase commits.
6. The CLI surface is portable — any GovZero-compliant repo that adopts gzkit gains TDD emission for free.
7. The ADR-0.25.0 closeout (which the operator explicitly paused) has a clear resume condition: this ADR's OBPIs complete and the governance graph is verifiable end-to-end.

### Q: What tradeoffs or downsides come with this decision?

**A:** 1. New CLI surface: `gz tdd` is a new top-level verb. Heavy-lane ADR. This expands the CLI doctrine and requires manpage, help text, and runbook integration.
2. New ledger event types: schema additions are backward-compatible but require migration for existing ledger consumers. The validation + replay tooling must be updated to recognize the new types.
3. Verification semantics are opinionated: the RED classifier may reject edge cases (e.g., a test that fails because of a legitimate flaky assertion rather than missing behavior) and force agent rework. This is intentional — a false-negative here is better than a false-positive that accepts fake RED — but it increases the friction of RED emission.
4. Agent workflow change: the TDD cycle now includes two explicit CLI invocations per REQ. This is the entire point (verifiable emission) but it adds a new step that must be captured in every skill that mentions TDD.
5. Retroactive housing is not free: linking Phases 1-7 of the GHI-160 program to OBPI-05 requires walking the commit history and updating audit artifacts. The Phase 7 audit becomes the primary evidence artifact for OBPI-05.
6. Schema drift risk: the new event types live in data/schemas/tdd_event.schema.json. Any future change to the schema requires a migration and a deprecation path.
7. The RED verification is an AST/runner-output-parsing task — classification bugs (e.g., mis-parsing pytest output because we only support unittest today) will surface as false 'RED is invalid' errors. Must be actively maintained.

### Q: What are the implementation checklist items? Each becomes an OBPI.

**A:** 1. Typed ledger events tdd_red_observed and tdd_green_observed with JSON schema
2. gz tdd red/green/chain CLI commands with verified emission semantics
3. Attestation-enrichment rule integration accepting TDD event citations
4. Runbook, manpage, and docs for gz tdd + tests.md rule update
5. Retroactive governance housing for GHI-160 Phases 1-7 + Phase 6 validate-check evidence linkage

### Q: What alternatives were considered and why were they rejected?

**A:** 1. Option B — Extend ARB with --expect-red / --expect-green flags. Rejected because ARB's own documentation explicitly disavows TDD semantics ('exit_status=0 means success'), and mixing QA receipts with TDD receipts conflates two concerns. The operator's direction was explicit: 'ARB may not be the best place to report RED.'

2. Option C — Lightweight ledger emission helper (gzkit.events.emit_tdd_red) with no CLI wrapper and no verification. Rejected because it's trust-based, which is exactly what GHI-157 flagged as broken. The operator explicitly critiqued 'test-dump theater' as a behavior bug; an emission channel without verification would not change the behavior, only the documentation format.

3. Fold Phase 5 TDD emission into ADR-0.27.0 (arb-receipt-system-absorption) as a new OBPI rather than author a new ADR. Rejected because ADR-0.27.0 is already Pending/Heavy with 13 OBPIs targeting the absorption of airlineops ARB; adding TDD emission would conflate absorption scope with new-design scope. Further, Phase 5 is architecturally its own concern — ARB is about QA receipt wrapping, TDD emission is about verifiable discipline evidence. Separate ADRs preserve scope clarity.

4. Two separate ADRs — one for TDD emission, one for governance-rot remediation housing. Rejected because the GHI-160 Phase 1-7 work is the causal origin of needing TDD emission. Without the rot remediation, we wouldn't have surfaced the need for verified TDD evidence. Splitting them would produce two ADRs whose lineage has to be reconstructed externally. One umbrella ADR with five OBPIs keeps the lineage intact.

5. Defer Phase 5 until after ADR-0.25.0 closeout resumes. Rejected because the operator explicitly paused ADR-0.25.0 until the governance foundation is sound — 'I care more about fixing this than getting through the current ceremony.' Deferring Phase 5 would mean ADR-0.25.0 either closes on partial remediation (contradicting the pause) or waits indefinitely for unscheduled Phase 5 work (contradicting the DO IT RIGHT maxim).


## Evidence

<!-- Links to tests, documentation, and other artifacts that prove completion -->

- [ ] Tests: `tests/`
- [ ] Docs: `docs/`

## Alternatives Considered

1. Option B — Extend ARB with --expect-red / --expect-green flags. Rejected because ARB's own documentation explicitly disavows TDD semantics ('exit_status=0 means success'), and mixing QA receipts with TDD receipts conflates two concerns. The operator's direction was explicit: 'ARB may not be the best place to report RED.'

2. Option C — Lightweight ledger emission helper (gzkit.events.emit_tdd_red) with no CLI wrapper and no verification. Rejected because it's trust-based, which is exactly what GHI-157 flagged as broken. The operator explicitly critiqued 'test-dump theater' as a behavior bug; an emission channel without verification would not change the behavior, only the documentation format.

3. Fold Phase 5 TDD emission into ADR-0.27.0 (arb-receipt-system-absorption) as a new OBPI rather than author a new ADR. Rejected because ADR-0.27.0 is already Pending/Heavy with 13 OBPIs targeting the absorption of airlineops ARB; adding TDD emission would conflate absorption scope with new-design scope. Further, Phase 5 is architecturally its own concern — ARB is about QA receipt wrapping, TDD emission is about verifiable discipline evidence. Separate ADRs preserve scope clarity.

4. Two separate ADRs — one for TDD emission, one for governance-rot remediation housing. Rejected because the GHI-160 Phase 1-7 work is the causal origin of needing TDD emission. Without the rot remediation, we wouldn't have surfaced the need for verified TDD evidence. Splitting them would produce two ADRs whose lineage has to be reconstructed externally. One umbrella ADR with five OBPIs keeps the lineage intact.

5. Defer Phase 5 until after ADR-0.25.0 closeout resumes. Rejected because the operator explicitly paused ADR-0.25.0 until the governance foundation is sound — 'I care more about fixing this than getting through the current ceremony.' Deferring Phase 5 would mean ADR-0.25.0 either closes on partial remediation (contradicting the pause) or waits indefinitely for unscheduled Phase 5 work (contradicting the DO IT RIGHT maxim).

## Attestation Block

| Term | Status | Attested By | Date | Reason |
|------|--------|-------------|------|--------|
| 0.41.0 | Pending | | | |
