Imported from joeloverbeck/continuity-loom (
reports/skill-evidence/tdd/reviews/rev_c08a5b3e-c82c-42b6-8958-8c636dba5e3c/pre-land-backup/SKILL.md). Install upstream withnpx skills add joeloverbeck/continuity-loom --skill pre-land-backup. Copyright stays with the author.
Test-Driven Development
TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping: what a good test is, where tests go, the anti-patterns, and the rules of the loop. Every section applies on every cycle — consult them before and during the loop, not after.
Orientation. For a single feature or bug fix, the operative guidance is What a good test is, Seams, Anti-patterns, and Rules of the loop below. The preflight, acceptance-manifest, shared-boundary-table, atom/sequence-map, and closeout hard-stops between here and those sections apply when the work is a PRD or multi-issue family — typically when this skill runs under the implement skill; that closeout contract lives in closeout-evidence.md.
When exploring the codebase, read CONTEXT.md (if it exists) so test names and interface vocabulary match the project's domain language, and respect ADRs in the area you're touching.
Before the first red test, record whether CONTEXT.md exists and was read, identify every applicable ADR or principle document, and give each one an explicit authority disposition: aligned with a concrete basis, covered by an approved amendment or exception with a durable reference, or reasoned N/A.
Use this preflight before writing the first red test:
TDD preflight:
- CONTEXT.md status: <read / absent / N/A>
- ADRs/principles/docs status: <aligned because authorities and concrete basis / approved amendment or exception with durable authority reference / conflict - blocked because ... / N/A because ...>
- Pre-red evidence reference: <file-backed or tracker-backed ledger plus heading or row anchor by default; exact conversation block plus anchor only while it remains inspectable; chronology proof that this preflight and table precede the first red command>
- Agreed seams: <issue/PRD-stated seams restated / user-confirmed seams / confirmation needed>
- Authoritative acceptance manifest: <path generated from saved exact issue JSON / N/A because one non-PRD issue has no shared or parent boundary>
- Row plan: <red-first seams>; <no-runnable criteria>; <evidence-only browser/manual/external seams>
- Acceptance atom map: <each exact criterion mapped to authoritative atoms and required proof surfaces, with every named value in a quantified range listed unless the source permits sampling / all criteria atomic, with proof surfaces named / blocked because ...>
- Acceptance sequence map: <each order/transition/timeline-sensitive criterion mapped to the ordered events and proof that observes their order; stateful re-entry and terminal paths mapped on one active instance; overlapping async invocation either prevented or mapped through attempt A remains pending -> attempt B settles -> attempt A settles / all rows use sequence N/A because their criteria are not sequence-sensitive / blocked because ...>
- Proof server plan: <configured API/UI ports plus owner-check command; unrelated pre-existing owners and isolated proof-owned ports/proxy plan / configured ports verified free / N/A because no browser/manual proof server applies>
- Shared-boundary table stub: <created before first red test / N/A>; <every in-scope issue has a row or exceptions named>
- Existing expectation rewrite checkpoint: <none yet / row will be added immediately if an existing test, fixture, snapshot, route/schema expectation, or artifact assertion is edited after a failing command>
- User confirmation needed: <yes/no, and why>
Authority-conformance pre-red hard stop: reading an authority is not a conformance result. For every applicable authority, record aligned with the exact basis or record an approved amendment or approved exception with a durable authority reference. If the requested behavior conflicts with an authority, stop and obtain the exact amendment, exception, or scope correction; do not run the first red command while any authority conflict is unresolved. N/A requires a reason. Carry the same disposition into every affected compact row and the closeout gate.
Acceptance-source inventory hard stop: for a parent PRD, child issue family, or named multi-issue set, save the exact issue JSON and generate the authoritative acceptance manifest with .claude/skills/implement/scripts/build-acceptance-manifest.mjs before the first red command. The preflight and compact-table row plan must account for every generated parent section check, individual USN, AC check, and Principles check. A broad range such as US1-US36 does not replace the individual story-to-seam map; use exact keyed rows or an adjacent keyed map for every story. Reuse the same manifest for TDD closeout, review, and implementation closeout rather than rebuilding scope from prose.
Shared-boundary pre-red hard stop: when the work covers multiple issues, one PRD with child issues, or one implementation boundary shared by several acceptance rows, paste the compact evidence table immediately below the preflight before any red command. A prose row plan is not enough. Mark each row as red-first, existing contract-change expectation, static contract check + browser evidence, coverage-only existing behavior, no-runnable, or evidence-only; if the table is genuinely N/A, name the exception in the Shared-boundary table stub field before proceeding.
Acceptance-atom and sequence pre-red hard stop: before the first red command, resolve every composite term in the issue or PRD through its authoritative parent/child definition, implementation decision, glossary, or named contract. In Acceptance atom map, list every required atom and map each atom to every promised proof surface. In Acceptance sequence map, identify every order-, transition-, or timeline-sensitive criterion and list the ordered events plus the proof surface that observes their order. For example, if provenance means actor + timestamp + flow step across API + report + browser, the map and eventual evidence must name all six obligations rather than only provenance; if acceptance requires Proposal → staging → Pressure, it must preserve that order rather than proving the three states independently. A quantified range such as “two through five” requires proof at every named value unless the source explicitly permits boundary or representative sampling. A lifecycle or renderer term such as “controlled rerender,” “resume,” or “transition” requires one active instance plus the triggering action and observer that prove continuity; two independent snapshots or server renders are not equivalent. For an ephemeral draft, provenance report, modal workflow, or other stateful interaction, map re-entry while state is active and every applicable terminal path: success, failure, cancel, discard, persistence, baseline restoration, and the action that retains, clears, or re-enables the session. For a user-triggered async action that can be invoked before its earlier promise settles, either prove the action prevents overlap or map attempt A remains pending -> attempt B settles -> attempt A settles, including mixed success/failure orderings and the observer that proves newest-attempt ownership. A row may group atoms, surfaces, or ordered events only when its assertion or evidence directly proves every grouped obligation; otherwise split the row. Carry the exact criterion plus atoms:, proof surfaces:, and sequence: into each row's Acceptance covered cell, using atoms: atomic only when the authoritative criterion truly has one indivisible obligation and sequence: N/A because the criterion is not sequence-sensitive only when order cannot affect acceptance.
Coverage-only admissibility hard stop: before classifying a row as coverage-only existing behavior, map the exact acceptance criteria to materially distinct public seams. A route, action, refresh, request, API, or rendered-state behavior needs its own row unless one assertion directly observes every grouped condition. Run the criterion-specific public assertion or probe before any production change and record its concrete green command/evidence plus the exact acceptance reference. If the assertion fails, classify the seam as red-first; if it has not run yet, leave the row TBD rather than claiming coverage-only behavior.
Existing expectation rewrite checkpoint: if an existing test, fixture, snapshot, route/schema expectation, or artifact assertion fails after an intended contract change and you edit that existing expected value, update the compact evidence table immediately before continuing. Use an existing contract-change expectation row, start Red command/failure with existing contract-change expectation in <test file> because ... plus the failing command/assertion, cite the authorizing spec/issue/worked example in Acceptance covered, and keep the full existing-test closeout rule under Rules of the loop from becoming a last-minute validator repair.
For shared-boundary issue families, paste this compact evidence table stub before the first red test; do not substitute a prose-only row plan. The red and green cells can be TBD while work is still in progress, but every in-scope issue and agreed seam must already have a row with a red-first, existing contract-change expectation, static contract check + browser evidence, coverage-only existing behavior, no-runnable, or evidence-only classification.
| Issue | CONTEXT.md status | ADRs/principles/docs status | Seam | Red command/failure | Green command or evidence | Acceptance covered | Review fix / red-first skip reason |
|---|---|---|---|---|---|---|---|
| #N | <read / absent / N/A> | <aligned because authorities and basis / approved amendment or exception with durable reference / N/A because ...> | <red-first / existing contract-change expectation / static contract check + browser evidence / coverage-only existing behavior / no-runnable / evidence-only seam> | <command plus expected failure / partial red - wrong reason / coverage-only existing behavior; red-first N/A because behavior already existed and no production code changed / N/A / explicit skip reason / TBD> | <passing command / browser route-action-result / external/cold proof artifact or audit-row citation / artifact path / N/A / TBD> | <exact criterion or checkbox; atoms: authoritative atoms or atomic, including every named range value; proof surfaces: surface for each atom; sequence: ordered events plus same-instance action and observer, including applicable stateful re-entry/terminal paths and async settlement order / N/A because criterion is not sequence-sensitive> | <N/A / review-fix evidence / partial-red follow-up / red-first skip reason> |
When the repo implement skill owns the surrounding workflow, keep this table or equivalent fields in the implementation ledger before review and carry them into the final closeout sink before tracker mutation. Do not wait until closeout pressure to reconstruct TDD evidence from prose-only command notes.
For parent/child issue families, named multi-issue sets, and other long or compaction-prone runs, create a file-backed or tracker-backed ledger before the first red command and append the exact preflight, compact table, and command chronology there. Conversation-only evidence is durable only while the exact preflight block, compact rows, and chronology remain inspectable verbatim; a context-compaction summary or reconstructed recollection does not qualify.
Implement-owned pre-red hard stop: when this skill is invoked under the repo implement skill, do not run the first red command until either the TDD preflight: block and compact table stub above are pasted, or the visible implementation ledger explicitly states that it contains each required TDD preflight field and compact-table row. The preflight must fill Pre-red evidence reference: with the durable sink and exact heading or row anchor; keep the first red command in that same sink after the anchor, or record another inspectable chronology proof. For parent PRDs, child families, and named issue sets, that visible state must include the authoritative acceptance-manifest path and a row or keyed-map destination for every generated check. If this gate was missed, stop before more implementation or review and paste the literal TDD recovery addendum: block from closeout-evidence.md. Its four required fields inventory the missed pre-red gates, recovered authoritative-manifest coverage, reconstructed red/green evidence by issue/seam, and final preservation sink; an anchored reference without that block is not recovery evidence.
Before handing work to review, drafting a pre-close audit, or mutating the tracker, read closeout-evidence.md. It owns the validator command, interim/final durable-sink gates, parent-rollup template, and tracker-mutation stop; do not reconstruct those contracts from memory.
What a good test is
Tests verify behavior through public interfaces, not implementation details. Code can change entirely; tests shouldn't. A good test reads like a specification — "user can checkout with valid cart" tells you exactly what capability exists — and survives refactors because it doesn't care about internal structure.
See tests.md for examples and mocking.md for mocking guidelines.
Seams — where tests go
A seam is the public boundary you test at: the interface where you observe behavior without reaching inside. Tests live at seams, never against internals.
Test only at pre-agreed seams. Before writing any test, write down the seams under test and confirm them with the user. No test is written at an unconfirmed seam. You can't test everything — agreeing the seams up front is how testing effort lands on the critical paths and complex logic instead of every edge case.
If a PRD or issue explicitly names proof seams, those count as pre-agreed after you restate them in the implementation ledger. Ask the user only when the seam is absent, ambiguous, or conflicts with the codebase's actual public interfaces.
When seam confirmation is needed, ask: "What's the public interface, and which seams should we test?"
Static/source-level contract checks are exceptional. Use them only when an explicit acceptance criterion names a forbidden or required source contract, such as a route string, import, schema key, or generated artifact path. Label the evidence as a static contract check, keep the expected value tied to the spec, and pair it with a public behavior test or browser smoke when the feature is user-visible.
Do not use source-file string checks merely to automate browser-visible UI acceptance. For visible UI behavior, use a public UI/rendered DOM test or evidence-only browser smoke unless the acceptance criterion names a source-level contract.
When writing a static contract check, target the smallest source construct that proves the contract. Avoid whole-file regex spans that can cross unrelated regions or match incidental text. After the red run, confirm the failure names the intended forbidden or required contract rather than a broader accidental match.
When a static contract check is paired with browser proof, label the compact-table Seam cell as static contract check + browser evidence. Put the failing source-level contract command in Red command/failure, and put both the passing focused command and the browser route/action/artifact in Green command or evidence.
Anti-patterns
- Implementation-coupled — mocks internal collaborators, tests private methods, or verifies through a side channel (querying the database instead of using the interface). The tell: the test breaks when you refactor but behavior hasn't changed.
- Tautological — the assertion recomputes the expected value the way the code does (
expect(add(a, b)).toBe(a + b), a snapshot derived by hand the same way, a constant asserted equal to itself), so it passes by construction and can never disagree with the code. Expected values must come from an independent source of truth — a known-good literal, a worked example, the spec. - Horizontal slicing — writing all tests first, then all implementation. Bulk tests verify imagined behavior: you test the shape of things rather than user-facing behavior, the tests go insensitive to real changes, and you commit to test structure before understanding the implementation. Work in vertical slices instead — one test → one implementation → repeat, each test a tracer bullet that responds to what the last cycle taught you.
Shared-boundary red-command hard stop: for shared-boundary issue families, do not run the first broad or shared-boundary red command until the compact evidence table stub is visible in the conversation, implementation ledger, or durable scratchpad. The stub must have one row per in-scope issue and agreed seam, or an explicit exception/clarification for each missing seam. A prose-only row plan is not enough.
Rules of the loop
-
Red before green. Write the failing test first, then only enough code to pass it. Don't anticipate future tests or add speculative features.
-
Stateful interaction adversaries belong in the tracer. When behavior owns an ephemeral draft, provenance report, modal, retry state, or other session-like state, exercise re-entry while state is active and every applicable terminal path before declaring green. Prove the original baseline and ownership survive rejected/repeated entry, and prove exactly which success, failure, cancel, discard, or persistence outcome retains, clears, restores, or re-enables the state.
-
Async completion order is user-visible behavior. When the same user action can overlap an earlier in-flight call, either disable or guard re-invocation and test that public behavior, or control the boundary promises so attempt A remains pending, attempt B settles, then attempt A settles. Assert the final public state for both older-success/newer-failure and older-failure/newer-success orderings; call counts or internal tokens are not the oracle.
-
Bootstrap red is not behavior red. A focused command that fails only because the intended test file does not exist (for example,
no test files found) can seed the loop only asbootstrap red. Before implementing behavior, follow it with the smallest failing assertion for the agreed seam, or record an explicit red-first skip reason if a true assertion red is impossible. Do not report a missing-test-file failure as proof that the behavior contract went red. -
Review findings restart the loop. If review reveals missing behavior after the implementation is already green, add or adjust the smallest assertion first and run it red before fixing. If the code was already fixed to protect the tree or unblock verification, record that red-first was skipped and why. A review-fix evidence row that says only
fixed and coveredis not enough; it must include the red command/failure or an explicitred-first skipped because ...reason. -
Standards-only review fixes do not need fake behavior reds. If review finds a Standards-only, ADR-only, or conformance-only problem and the fix does not change acceptance behavior, record
red-first skipped because Standards-only/conformance-only fix did not change behavior, rerun the affected focused and root gates, and refresh browser/manual evidence only when the touched files affect a covered route, action, browser-consumed API shape, fixture, or data setup. -
Schema-heavy fixture setup is a precondition, not the behavior red. When a tracer uses persisted records, temporary databases, serialized DTOs, or another setup surface with runtime-required fields, construct it through the public typed builder or parser and run the smallest setup-only probe when practical before the intended behavior red. A setup/schema failure does not count as the behavior red: record
partial red - wrong reason: fixture/setup failed because ..., repair only the fixture precondition, then rerun until the assertion fails for the intended acceptance behavior. -
Dependency state is a precondition, not a behavior red. When a package manifest or lockfile changes, run the dependency install or synchronization command required by the root guidance before treating a focused or canonical command as red/green evidence. Classify missing-module, missing-binary, or workspace-link failures observed before synchronization as setup-only, repair the install, and rerun the original command.
-
Cross-workspace build freshness is a precondition, not a behavior red. Before interpreting a focused consumer test across a workspace boundary, establish whether the consumer resolves the upstream workspace's current source or built output. When it resolves built output, refresh the affected upstream workspace build before the baseline or red run and again after changing public exports, DTOs, or other consumed build artifacts. Record a stale-build failure as
partial red - wrong reason: stale upstream workspace build because ..., refresh that build, and rerun the exact focused command before recording red or green behavior evidence. -
Robustness harnesses are assurance after behavior green. When acceptance requires mutation, scoped coverage, property, metamorphic, or golden assurance, use
docs/ACTIVE-DOCS.mdto select and read the active development-assurance authority; in this repo that authority isdocs/specs/robustness-testing.md. Do not count runner, plugin-discovery, sandbox, symlink-traversal, or other harness setup failures as behavior red. Record the original command and failure, verify installed runner and plugin versions against the manifest and lockfile, preserve the exact changed-source, product, test, and mutation scopes, and justify exclusions only for proven non-product or non-test infrastructure. After behavior green, run the closest equivalent assurance command and the repository's canonical result gate; report the assurance step blocked when equivalence cannot be demonstrated. -
Copied stateful fixtures require consistent snapshots. Create a copied database, world file, or other stateful fixture with an application-consistent snapshot mechanism, then probe the expected identity and state before using it for a red, green, or evidence-only row. For Worldloom SQLite files that may have live WAL state, use SQLite
.backupor an explicit checkpoint-aware copy rather than rawcp; classify a failed, empty, or stale copy as superseded evidence. -
Authority-sensitive fixture identity stays explicit. When an acceptance criterion, user instruction, or repository policy forbids publishing a machine-local fixture path, keep the path private and record
fixture paths withheld because <authority and reason>; logical fixture <stable ID>; content SHA-256 <64 hexadecimal characters>; provenance <generated, derived, or copied-source statement>in the shared current-evidence inventory. Do not disguise a withheld path asnoneornone published because; the logical identity, content hash, and provenance preserve reproducibility without disclosing the path. -
Wrong-reason red is only partial red. If a red command for a review fix fails because of a missing file, a generic invariant, an unrelated assertion, or any reason that does not prove the intended behavior is wrong, record
partial red - wrong reason: <reason>, then add or adjust the smallest assertion that fails for the intended behavior before patching. If no intended-behavior red is possible, record an explicitred-first skipped because ...reason. -
Unexpected green can be wrong-surface coverage. If a new or adjusted assertion passes before the intended behavior fix, pause before counting it as proof. Verify the assertion observes the intended public route, panel, action, or source construct, not a legacy surface, nearby component, broad HTML/source span, or incidental text. If the assertion was too broad, tighten it and run again until it fails for the intended missing behavior; record coverage-only proof only after confirming the behavior already truly exists.
-
Coverage-only review fixes are different from behavior fixes. If review reveals missing proof or coverage, but the behavior already exists, add the smallest assertion and run it. If it passes without a code change, record
coverage-only review fix; red-first N/A because behavior already existed and no code changed. If it fails, treat the finding as missing behavior and restart the red → green loop. -
Coverage-only existing behavior rows are initial-implementation proof rows, not review fixes. If an issue requires proof for behavior that already exists and the new assertion passes before any production change, record
coverage-only existing behavior; red-first N/A because behavior already existed and no production code changed, cite the public seam and acceptance criterion, and verify the assertion observes the intended route, action, API, or source construct. If the assertion fails, treat it as missing behavior and restart the red → green loop. Do not use this phrase for review findings; usecoverage-only review fixthere. -
Review-fix evidence and freshness. When review creates or changes a TDD row, use the canonical keyed review-fix map and freshness rules in closeout-evidence.md. Give every finding one unique
RF-Nrow, repeat that ID in the exact compact TDD row it updates, and keep each finding's red, green, durability, freshness, backend-currentness, and identity evidence together. A transient browser/manual red must includeRegression durability:; do not leave review-fix proof as prose-only notes or bundle several findings into one unkeyed entry. -
Record the loop. For each slice, append lightweight evidence of the red command and expected failure, then the green command, to the durable sink named by
Pre-red evidence reference:so line order or another recorded anchor preserves chronology. If red-first is skipped, say why. For focused commands, check the output confirms the intended file, seam, or assertion actually ran; if a package script does not forward file arguments cleanly, invoke the underlying runner directly. -
Existing-test failures after intended contract changes are regression evidence. If an existing test fails after an intended behavior, schema, route, or artifact contract changes, record the failing command before editing the test. Update the expectation only when the spec, issue, or worked example authorizes the new behavior; otherwise fix the implementation. Rerun the focused command and any broader gate that exposed the failure. In the compact evidence table, put the failing existing-test command in
Red command/failurefor the affected seam, or use a dedicatedexisting contract-change expectationrow when the failure spans several acceptance rows. ReserveReview fix / red-first skip reasonfor review findings, coverage-only review fixes, and explicit red-first skips. Closeout stop: if any existing test expectation was edited after a failing command, add anexisting contract-change expectationrow before the TDD closeout preflight; if none were edited, recordExisting-test contract-change rows: none. -
Existing-test contract-change row means expectation rewrite. Do not use
existing-test contract-change rowsmerely because new assertions were added to an existing test file. It applies only when an existing expectation, snapshot, fixture assertion, route/schema expectation, or equivalent contract assertion was changed after a failing command and the issue/spec authorizes the new expected behavior. In that case, the compact table must include a row whoseSeamcell is exactlyexisting contract-change expectation; otherwise recordExisting-test contract-change rows: none. -
Docs-only and no-runnable criteria stay explicit. If an acceptance criterion is a document deliverable, review/conformance claim, or otherwise has no runnable public seam, do not invent a test seam. Record red and green as
N/A, cite the review/conformance evidence, and carry the no-runnable reason in the compact evidence table. -
Browser/manual evidence can be evidence-only. If acceptance requires browser-visible, manual, screenshot, walkthrough, or other evidence that is not itself a red-first automated seam, record it as an evidence-only row instead of forcing a fake failing test. Set red to
N/Aor an explicit red-first skip reason, and record the browser route, action path, observed outcome, artifact path, or walkthrough result in the green/evidence field. Record console error/warning state next to the evidence or in the closeout preflight. Before starting or attaching to any proof server, inspect the configured API/UI ports and their owning processes; record unrelated pre-existing owners without stopping or reusing them, then either prove the configured ports free or choose isolated proof-owned ports and align the UI proxy/API base. Record the proof-owned session name, URL, command, or PID before relying on it; during cleanup, stop only proof-owned processes and state whether each was stopped, intentionally left running, or unrelated and pre-existing. When browser proof consumes a backend, reachability alone is not proof that the process serves the current code: record the server command and watch/reload mode, confirm process and port ownership from the browser proof's execution context, restart or reload after relevant server/API changes unless current-code reload is demonstrated, and run the smallest expected-shape API field or behavior probe before the final UI assertion. If currentness is uncertain or a stale process caused an error, restart the proof-owned backend and use a clean browser session. When browser proof uses a copied stateful fixture, record its snapshot method and source plus the expected-state probe that proved the copy current before the final UI assertion. If the proof spans hot reload/HMR, reused browser sessions, agent-induced setup/request errors, or unexplained console errors or warnings, treat it as preliminary and rerun a clean browser session on the final tree, or explicitly classify the console output as unrelated with evidence. For dense app screens or long single-page snapshots, keep evidence bounded: prefer targeted DOM/text assertions, concise excerpts, and screenshots over full-page snapshot dumps. If later edits touch a route, UI action, browser-consumed API shape, fixture, or data setup covered by an evidence-only row, rerun the evidence on the final tree or record an explicit stale/blocked reason before closeout. If a later behavior-changing UI edit is outside the evidence-only route/action path,not affectedis acceptable only when the closeout names the changed path, explains why the evidence route/action path and browser-consumed API/fixtures were untouched, and reruns targeted proof for the changed path. -
Published current evidence survives cleanup truthfully. Before deleting proof-owned fixtures, scripts, packets, or artifacts, compare them with the published
Current evidence identities:inventory and closeout references. A published current artifact is not safe to remove until closeout is complete and its retained-or-removed disposition is recorded. If it is removed after publication, update the durable evidence so it does not imply that the local artifact remains inspectable; retain the command/result or tracker-hosted evidence needed to support the claim. -
Issue-level browser/manual N/A stays explicit. If exact issue or PRD acceptance says browser/manual proof is N/A because the browser contract, routes, rendered behavior, validation response, fixtures, and action path are unchanged, do not create a fake evidence-only row. Record the exact issue/PRD rationale in the row plan or compact table context, and carry it into closeout as
Evidence-only rows freshness: none - browser/manual N/A because ...or an adjacent explicit N/A note. Browser/manual proof is still required for any changed browser-consumed surface or UI/browser-visible criterion that is not covered by the explicit N/A. -
External/cold proof can be evidence-only. If acceptance requires a cold external LLM, fresh subagent, packet-read, credentialed service, nonlocal probe, or other proof outside repo-local tests, record it as an evidence-only row or cite a per-criterion audit row in the same durable sink. Set red to
N/Aor an explicit red-first skip reason, and record the exact packet/artifact/report path, subagent/probe result, blocker, or same-sink audit-row citation inGreen command or evidence. Do not let a focused test command stand in for external proof it did not exercise. -
One slice at a time. One seam, one test, one minimal implementation per cycle. When a vertical slice legitimately spans several public seams, write the smallest tracer-bullet test at each seam, keep the issue/audit mapping explicit, and avoid bulk tests that are not tied to an acceptance criterion.
-
Shared-boundary issue families still need tracer bullets. When PRD child issues share one implementation boundary and separate red-green cycles would be artificial, write the smallest red tracer at each agreed seam, record the red failures by seam and issue, then implement the shared boundary while keeping the acceptance mapping explicit.
-
Inventory shared-boundary seams before broad red tests. Before writing the first broad tracer for a shared-boundary issue family, list every agreed seam and mark each one as
red-first,existing contract-change expectation,static contract check + browser evidence,coverage-only existing behavior,no-runnable, orevidence-only. Instantiate the compact evidence table stub before the first red test: one row per in-scope issue and agreed seam, withTBDallowed only in command/evidence cells that cannot exist yet. Use that inventory as the row plan for the compact evidence table; if a seam cannot be classified, stop and clarify the seam before writing tests. -
Shared-boundary closeout hard stop. Do not enter closeout for a shared-boundary issue family until the canonical compact evidence table in closeout-evidence.md has one row per agreed seam, or an explicit red-first skip reason for each seam that could not reasonably go red first.
-
Implementation closeout consumes TDD evidence. Before review, pre-close audit, issue closure, or parent PRD closeout, follow closeout-evidence.md and preserve the interim/final durable-sink fields there; do not rely on prose-only red/green notes surviving compaction.
-
Refactoring is not part of the loop. Incidental cleanup belongs to the review stage (see the
code-reviewskill), not the red → green implementation cycle. When the requested work is itself a behavior-preserving refactor with observable or static acceptance criteria, the loop can use a red tracer for the required contract plus behavior-preservation tests at the agreed seams.