tdd · diff

git:20261016.95e8e18 to git:20261016.a9f63fc

91 added, 209 removed. Audit A to A.

---
name: tdd
- description: The test-first gate. Routed to by an authorized /feature, /fix, and /refactor before any implementation code is written. Six gated phases — obligation scan, red, green, obligation verify, coverage, lint. No feature code exists before Phase 1 clears; nothing reaches commit-gate until all six are green.
+ description: Verify authorized feature, fix, and refactor work with scoped obligations, regression-first fixes, behavioral checks, characterization baselines, coverage, and lint.
disable-model-invocation: true
---
# tdd
- ## Authoritative format boundary
-
- For an HTML spec/plan pair, load `{{PLUGIN_ROOT}}/includes/artifacts.md` and use
- the installed structured-artifact engine for artifact I/O. Check the plan's
- exact binding to its selected spec, use typed `index`, `outline`, and symbol-scoped `read`,
- and follow contextual pages for the selected task. The workflow must not parse rendered HTML
- for criteria, status, evidence, or authority. Missing or
- invalid HTML capability is a STOP, not a fallback to Markdown. Existing
- authoritative Markdown pairs continue through the legacy path. HTML `--farm`
- dispatch remains blocked.
-
-
- Test-first, or it does not ship. Routed to by an authorized `/feature`, `/fix`, and `/refactor`.
-
- For a feature author, including a confirmed small-lane feature, the owning
- coordinator selects task paths and obtains the current bounded map, provenance,
- scoped command records and collector observations, applicable constraint
- references, and host-effective instructions in native precedence order. Before
- the author mutates or executes a discovered command, compose the fresh child
- input with `_artifactpromptlib.compose_feature_actor_input` and send its
- returned `input` to that child. Bind the selected spec and plan IDs
- for full-lane work. For a confirmed small-lane feature, pass its mini-spec
- text as `confirmed_mini_spec` and leave both artifact IDs absent; do not invent
- a plan or additional approval record. The packet
- is an orientation aid with `requires_actor_check`, not admission. Recheck
- worktree/source identity and resolve applicable critical constraints before a
- material action. Missing optional map detail permits bounded read-only source
- inspection, with full schema or document body read only when needed.
- Apply `_contextselectlib.prepare_actor_delivery` to that selected packet for
- the actual child, task, worktree and current source/host epochs when that
- helper is useful. Deliver the relevant bounded input; a missing receipt does
- not independently deny execution. Re-select context after a material source
- or worktree change, and do not claim a child saw input not actually delivered.
-
- For a fix or targeted test-only change, use the caller that already owns the
- task. Before the author mutates or executes a discovered command, call
- `_contextselectlib.compose_fix_or_test_actor_input` with the current scoped
- sources, exact command cwd and collector evidence, then send its returned
- `input` to that actor. Use `route='fix'`, `caller='fix'`, and the confirmed
- bug-origin evidence and named regression for a fix. Use `route='test_change'`
- with the existing `fix`, `feature`, or `refactor` caller for a test-only change;
- do not create a feature spec pair merely to deliver context. the selected
- caller retains its real host permissions and applicable TDD checks. Reuse an actual bug-origin RED
- when it already proves the named regression; for a targeted test change,
- validate the test against the real defect or an honest fault fixture. Never
- change production behavior merely to manufacture a failing test. If this
- conflicts with a required TDD gate, surface the conflict to that gate's owner;
- context delivery does not waive it. The packet remains reported evidence, not
- task admission.
+ Select the verification approach before changing code. Keep the intended behavior,
+ observed results, and pending checks explicit throughout implementation.
## Pre-flight
- Read these, or STOP and surface the gap — never guess a command or a threshold:
-
- - `{{PROJECT_DIR}}/.codearbiter/CONTEXT.md` — the `stage:` frontmatter (the maturity value) and project context.
- - `{{PROJECT_DIR}}/.codearbiter/tech-stack.md` — test, coverage, and lint invocations; file layout; mock patterns.
- - `{{PLUGIN_ROOT}}/includes/verification-boundary.md` — the required split between focused local proof and exhaustive exact-head hosted CI.
- - `{{PROJECT_DIR}}/.codearbiter/coding-standards.md` — style, structure, naming. Required for Phase 3.
- - For `/feature`, the authoritative selected spec. For HTML, read its typed
- criterion records through the installed engine and confirm the paired plan's
- exact binding; for legacy Markdown, read
- `{{PROJECT_DIR}}/.codearbiter/specs/<slug>.md`. It is the feature obligation
- source.
- - For `/fix`, the bug-origin evidence: observed and expected behavior, the
- current expectation and its citations, supported cause, and the regression
- oracle with its cited evidence. If a validated debug handoff supplies these,
- recheck its source binding and freshness in the actual worktree and the
- original caller authority through the fix owner. A packet or its intent field
- does not authorize repair. Do not create a feature artifact to enter TDD.
- - For `/refactor` backfill, the user-approved surface table and pre-existing
- parity evidence owned by `/refactor`. It does not require a feature spec.
- - `{{PROJECT_DIR}}/.codearbiter/security-controls.md` — only when the change touches a security boundary (auth, crypto, secrets, a trust boundary). Optional; absent on most changes.
- - `{{PROJECT_DIR}}/.codearbiter/code-map.md` — if present, a coarse concern→path→role map to orient before writing tests and code. Absent is fine — it is read-on-demand, populated by context-creation or commit-gate heal.
-
- ## Phase 1 — Obligation scan · gate: BLOCK
-
- An **obligation** is one verifiable claim about the change: (a) a unique ID, (b) a source citation,
- (c) a status. Status moves `OPEN → MAPPED → COVERED`; an obligation Phase 4 cannot tie to a passing
- test is `MISSING`. "We should test X" is not an obligation.
-
- Derive every obligation before any code is written, and record each as `ID · source · OPEN`:
-
- - **Spec (`/feature`)** — one obligation per acceptance criterion in the selected spec. For
- HTML, cite the exact artifact ID and criterion ID returned by the engine;
- caller-supplied labels cannot manufacture obligations or widen the selected
- criterion set.
- - **Bug-origin regression (`/fix`)** — one obligation for each scoped wrong
- behavior to repair. Cite the current expectation, observed defect and supported
- cause, regression oracle and evidence, and relevant source binding. A validated
- debug handoff supplies cited facts, not authority; derive these rows in the
- existing ledger. Do not invent a feature artifact such as a spec, plan, or
- mini-spec. The target regression must go red for the right reason before the
- minimum implementation. If the expectation is unresolved or the proposed
- behavior is new, stop and use the feature or decision owner.
- - **Refactor parity (`/refactor` backfill)** — cite the approved surface table
- and the uncovered symbol or seam with its pre-existing behavior and parity
- evidence. Do not turn a refactor into a feature or a bug fix.
- - **Contract** — API and input-validation invariants, error responses, boundary conditions.
- - **Security** — only when `security-controls.md` applies: the assertion that the security-relevant boundary holds.
-
- Gate: the obligation list is complete. For `/feature`, continue when each obligation
- maps to the selected full-lane spec's criterion records or the confirmed small-lane mini-spec.
- An exact source/plan binding protects the agreed outcome; it is **not another artifact approval**.
- Do not re-ask the user for a code or independent authorization merely to test or implement the
- existing criteria. Escalate only a material change to the agreed outcome or a real host/security
- decision to its actual owner; ordinary Contract and Security regression checks may proceed under
- existing permissions without a new artifact-level human checkpoint.
- For `/fix`, the scoped bug-origin regression follows the original caller's repair authority and
- current evidence; the absence of a feature spec is not a block or permission to expand scope.
- Review any proposed obligation beyond that supported correction under its actual owner. An ADR
- remains a user-attributed decision through `/adr`; neither a handoff nor this ledger creates one.
- For `/refactor`, retain its user-approved surface table and parity gates; backfill only the named
- uncovered behavior or seam. The TDD checklist does not amend that table.
- Under `/sprint`, derive spec obligations and necessary Contract and Security checks within the
- already-authorized outcome. If an addition materially changes that outcome or needs new authority,
- ask the actual owner; a score or ledger entry does not grant scope. SMARTS is optional for a
- difficult in-scope method choice, and material decisions retain their reasons in the sprint log.
- A partial obligation list never passes.
-
- ## Phase 2 — Red · gate: BLOCK
+ Use the selected specification or inline criteria for a feature, the observed defect
+ and expected behavior for a fix, and the agreed surface plus existing behavior for a
+ refactor. Read applicable project instructions and the test, coverage, and lint
+ commands in `{{PROJECT_DIR}}/.codearbiter/tech-stack.md`. Follow
+ `{{PLUGIN_ROOT}}/includes/verification-boundary.md` for local versus hosted checks.
+ Read security controls when the affected behavior crosses a security boundary.
+ Use `.codearbiter/code-map.md` on demand for source orientation when present.
- Bind a failing test ID to each obligation and move that obligation `OPEN → MAPPED`.
- Run the test command from `tech-stack.md`. For `/fix`, first assess an existing failing
- test against target red: compare its assertion and regression oracle with the current
- target failure and evidence. Name the existing test ID in the obligation ledger and
- reuse that named existing target-red test when its oracle is adequate and it fails for
- the target reason. Do not duplicate a test solely because of its age or because it
- predates repair. Add tests only for uncovered obligations. Do not make a named target
- failure green before observing and recording its red result.
+ For artifact I/O, load `{{PLUGIN_ROOT}}/includes/artifacts.md`. Use the selected
+ spec/plan identities and typed criterion records for HTML. Direct implementation
+ reads the same relevant inputs; it does not require a child or delivery receipt.
- - Every newly written test MUST fail, and fail **for the right reason** — the assertion, not an import error or a typo. A new test that passes with no implementation is wrong; fix it before continuing.
- - Record unrelated existing failures in the baseline and report them; an unrelated failure is not target red. An import or setup error is not target red. Preserve each failure's identity and output. A newly broken pre-existing test is a conflict — stop and surface it.
- - Required commit gates remain blocked while required checks fail. Do not skip tests, suppress failures, or waive gates to proceed.
+ For actual delegation, send bounded context to the named actor. Feature actors use
+ `_artifactpromptlib.compose_feature_actor_input`; fix and test-only actors use
+ `_contextselectlib.compose_fix_or_test_actor_input`. Bind the actual task paths,
+ commands and cwd, applicable constraints, and effective instructions. A small-lane
+ feature supplies `confirmed_mini_spec` with absent spec/plan IDs. A fix supplies
+ `route='fix'`, `caller='fix'`, bug-origin evidence and the named regression. Test-only
+ work uses `route='test_change'` under its existing feature, fix, or refactor caller.
+ Use `required_refs` for particular task-critical inputs. Missing optional map or
+ provenance information permits focused source inspection.
- Observe the target regression red on the broken source before repair or implementation. If a material fixture or setup change occurs after that observation, the earlier red no longer qualifies: repeat target red on the broken implementation with the changed fixture or setup before the minimum repair. For an intermittent or timing defect, prefer a faithful deterministic seam. If only repeated trials can exercise the mechanism, predeclare a finite trial bound and failure oracle; record the stochastic sample limit. Do not claim deterministic proof from a passing sample or retry until green. A failing trial must match the target mechanism, not merely fail intermittently.
+ `_contextselectlib.prepare_actor_delivery` can prepare the actor's bounded input.
+ Send the returned delivery text when requested and retain observed delivery facts.
+ An advisory delivery result needs no further retry. Re-select after a material
+ source, scope or worktree change. Resolve actual critical missing or conflicting
+ inputs before the affected action, and preserve host permissions.
- Reject the standard traps: asserting on a mock instead of behavior; a test that can never fail; a
- snapshot so broad it asserts nothing; coupling to an implementation detail instead of observable
- behavior; asserting on the framework's behavior rather than your own.
+ ## Phase 1 — Obligations and verification approach
- The reasons to skip red are known. Hearing one is the tell that this gate is about to be waived —
- never the license to waive it:
+ Record each required claim with an ID, its source, and its proving check. Include
+ applicable contract and security boundaries. Retain the existing feature criteria,
+ fix expectation, or refactor surface; ask only about a consequential missing choice.
- | excuse | reality |
+ | Work | Evidence required |
|---|---|
- | "Too simple to fail first." | Simple changes have the cheapest red tests — and "too simple to test" and "too simple to break" have never been the same claim. |
- | "I'll write the test right after." | A test written after green has never been seen red: it is authored against the implementation it was meant to constrain, and its power to catch the bug is never demonstrated. |
- | "The test would just restate the implementation." | Then it is aimed at the wrong seam — assert the observable behavior, not the wiring. A change with no observable behavior to assert is a design finding, not an exemption. |
- | "The existing suite already covers this." | Then the failing test is impossible to write — try it. If it genuinely cannot go red, the obligation is already COVERED and Phase 4 records exactly that; if it goes red, the claim was wrong and you are holding the proof. |
-
- Gate: the runner confirms each newly written test red for the right reason, or an
- adequate named existing target-red test red for that reason, with every obligation
- `MAPPED` to a failing test. Record unrelated existing failures separately; they
- cannot count as target red or clear later required checks. No implementation code
- is written until this gate clears.
-
- ## Phase 3 — Green · gate: BLOCK
-
- Write the **minimum** implementation that satisfies the Phase 2 tests — no speculative logic, no
- gold-plating — to the conventions in `coding-standards.md`. Run the impact-bounded local tests from
- `verification-boundary.md`: the new regression plus affected pre-existing contracts. A broken
- pre-existing test is a regression: fix it. Exhaustive and cross-platform suites run on exact-head
- hosted CI before merge.
+ | Confirmed fix | Observe a named regression failing for the defect before repair, then passing after repair. Reuse an adequate current bug-origin RED. |
+ | Feature | Prefer test-first behavior checks. Existing implementation can be verified through current criterion-focused tests and meaningful negative controls where needed; report the observed sequence accurately. |
+ | Refactor or coverage backfill | Run characterization tests against existing behavior before restructuring. An initially passing test is a valid baseline. Preserve that baseline and its assertions through the refactor. |
+ | Documentation or non-executable change | Use the relevant reference, generation, schema, or rendering validation. Mark test and coverage phases inapplicable with the concrete reason. |
- Gate: rerun the same named target test for fresh green on the repaired source, then rerun fresh affected-contract tests on that source. Record these results with the applicable coverage, lint, and type-check results; an old-head green is not repair proof. The applicable local suite is green, reached by satisfying the Phase 2 tests — not by weakening them. A test's
- assertions MUST be unchanged between red and green; only fixtures and setup may move, and a material change to either requires renewed target red on the broken implementation before this green. A relaxed
- assertion is a gate violation.
+ Each obligation moves `OPEN → MAPPED → COVERED`; a claim without adequate evidence
+ remains `MISSING`. Declare the approach and needed checks up front. Record only
+ observed results, including failures, skips, and unavailable checks.
- ## Phase 4 — Obligation verify · gate: BLOCK
+ ## Phase 2 — Establish the baseline
- Walk the Phase 1 list item by item. Each `MAPPED` obligation moves to `COVERED` (a real passing test
- that exercises the claim) or `MISSING` (no test truly covers it). For security-relevant or
- contract-critical logic, dispatch the `coverage-auditor` agent
- (`{{PLUGIN_ROOT}}/agents/coverage-auditor.md`) to confirm the tests exercise the claim.
+ Run the selected checks and read their output. For a confirmed fix, verify that the
+ named regression fails for the target assertion, not an import, setup, or unrelated
+ error. Reuse a suitable existing test rather than duplicating it. Add tests for
+ uncovered behavior. Keep unrelated baseline failures separately identified.
- A `MISSING` obligation returns the workflow to Phase 2 — author a correct failing test, then re-run
- Phase 3 — and loops until it is `COVERED`.
+ For test-first feature work, observe the intended missing behavior before adding
+ it. For characterization, observe the existing behavior passing. A negative control
+ or isolated fault fixture can establish that a test detects a relevant deviation;
+ do not alter correct production behavior merely to obtain a failure.
- **Stakes:** when you block on a `MISSING` obligation, state what the untested seam leaves exposed, not
- just that it is `MISSING` — one line naming the consequence: "this error path is untested; a 500 here
- would reach users silently." The block is the rule; the stakes are why it is worth the friction.
+ For timing defects, prefer a deterministic seam. When repeated trials are necessary,
+ state a finite trial bound and failure oracle before running them. Report sample
+ limits; a passing sample is not deterministic proof.
- Gate: every obligation `COVERED`, each backed by a passing test. Any `MISSING` blocks Phase 5.
+ Proceed when the selected baseline supports the intended change. A confirmed fix
+ requires its genuine target RED. Missing characterization coverage requires useful
+ baseline tests before restructuring. Never weaken assertions or suppress failures.
- ## Phase 5 — Coverage · gate: BLOCK
+ ## Phase 3 — Implement and check
- Coverage scales with the maturity value (`stage:` in `CONTEXT.md`) — a rigor knob, not a promotion
- gate. The threshold table is the shared `{{PLUGIN_ROOT}}/includes/maturity-coverage.md` (the
- single source of truth, also used by `refactor` Phase 2).
+ Implement the scoped change using project conventions. Run the proving checks on
+ the resulting source, followed by affected pre-existing contracts. Repair regressions
+ and retain failed results until superseded by an actual rerun.
- Resolve the surface's **declared coverage profile** from `tech-stack.md` against
- `{{PLUGIN_ROOT}}/includes/maturity-coverage.md`, then run its coverage command.
- Every required metric must clear the maturity threshold. Apply the shared
- profile-selection, report-validity and critical-path evidence requirements;
- do not substitute metrics or treat an unmeasured metric as passed. Below the
- floor on any required metric → add meaningful tests until it is met.
+ For a regression-first fix, run the same named test for fresh GREEN. Keep its
+ assertions unchanged between RED and GREEN. A material fixture or setup change
+ requires renewed target RED against the broken source before claiming that sequence.
+ For refactors, preserve the behavior and baseline test assertions.
- **Name the host you measured on**, and for a tree `tech-stack.md` marks as platform-forked, the
- figure is the UNION across its supported hosts — a single-host report scores the other platform's
- arm as permanently uncovered (issue #521, conditions in `{{PLUGIN_ROOT}}/includes/maturity-coverage.md`).
- Where only one host is available, say so and name what is missing rather than quoting it as the
- whole.
+ ## Phase 4 — Verify obligations
- Where the surface has no coverage tooling at all, take the no-tooling exemption in
- `{{PLUGIN_ROOT}}/includes/maturity-coverage.md` — which requires QUOTING the `tech-stack.md`
- Coverage section that omits a command for this surface — and pass the phase on the Phase 4
- obligation verify alone. Without that citation the phase STOPs: "I could not find the command" and
- "this surface has none" look identical from here and demand opposite responses. Do NOT invent a
- command, and do NOT silently skip the phase as though it had been run — a gate that cannot execute
- still reads as satisfied, which is worse than an absent one.
+ Match each obligation to evidence that exercises its claim. Mark it `COVERED` only
+ when the applicable check passed. An unexplained failure or untested requirement
+ remains `MISSING`; repair the affected work and rerun its checks. Reuse current
+ results when the relevant source and inputs are unchanged.
- **Stakes:** when coverage blocks below threshold, name the class of code left dark — the paths a later
- regression could rot unnoticed — not just "below threshold." The number is the rule; the untested paths
- are why it matters.
+ Review the combined change at the scope its risks warrant. Use `coverage-auditor`
+ (`{{PLUGIN_ROOT}}/agents/coverage-auditor.md`) for an independently required review of security or contract-critical behavior.
+ State exactly what the evidence proves and what remains unknown.
- Gate: threshold met on every required metric in the declared coverage profile
- for the current maturity value, with the shared critical-path evidence, or the no-tooling
- exemption taken WITH its citation and Phase 4 proof. A test added only to move the percentage fails this gate in
- spirit — it converts an honest red into a green that asserts nothing.
+ ## Phase 5 — Coverage
- ## Phase 6 — Lint · gate: BLOCK
+ Apply `{{PLUGIN_ROOT}}/includes/maturity-coverage.md` using the project's declared
+ coverage profile and maturity stage. Run the owning coverage command for the affected
+ surface; every required metric must meet its threshold and critical-path evidence
+ requirements. Keep production scope, exclusions, and metrics unchanged unless the
+ user has authorized a policy change.
- Run lint, and the type-check if the project is statically typed, from `tech-stack.md`. Resolve every
- error.
+ Name the measurement host and retain the supported host union for platform-forked
+ trees. An unavailable host remains unmeasured. When the surface has no coverage
+ tooling, cite its `tech-stack.md` Coverage declaration and use the shared no-tooling
+ rule with the Phase 4 evidence. Never invent a command or treat unmeasured coverage
+ as passing.
- Gate: clean lint and type-check, zero errors — this is what clears the path to `commit-gate`.
- "Mostly passes" is not passing.
+ ## Phase 6 — Lint and handoff
- ## Hard rules
+ Run applicable lint and type checks from the project command guide. Resolve errors.
+ Return the scoped obligations, selected verification approach, actual command/cwd
+ and outcomes, and any pending checks to the caller. The commit owner evaluates this
+ evidence for the selected staged changes; it does not require a different historical
+ test sequence from the one appropriate to the work.
- - MUST NOT skip, suppress, or comment out a test to clear any gate.
- - MUST NOT mark an obligation `COVERED` without a passing test that exercises the claim.
- - MUST NOT lower a coverage threshold without a decision recorded in `CONTEXT.md`.
- - MUST NOT inline-suppress a lint rule without a written reason, and never to bypass a security-relevant rule.
- - MUST NOT guess the test, coverage, or lint command — read `tech-stack.md` or STOP.
- - MUST, at exit, run the follow-up harvest (`{{PLUGIN_ROOT}}/includes/harvest.md`) over any `[NEEDS-TRIAGE]` raised this run — batch-confirm promoting work to `open-tasks.md` and decisions to `open-questions.md` so nothing languishes; nothing auto-promotes interactively.
+ Preserve failures and actual user stops. Do not skip tests, lower coverage thresholds,
+ or suppress security checks to obtain a pass. Use `{{PLUGIN_ROOT}}/includes/harvest.md`
+ for genuine out-of-scope findings. Completion reports must distinguish implementation,
+ verification, review, and release.