@nurix/etna 0.20.36 → 0.20.38

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (212) hide show
  1. package/data/catalog/rules/frontend.md +5 -5
  2. package/data/catalog/rules/pnpm.md +2 -2
  3. package/data/catalog/skills/nustack/SKILL.md +2 -2
  4. package/data/catalog/skills/nustack/references/cli-design.md +35 -35
  5. package/data/catalog/skills/nustack/references/monorepo-master-list.md +6 -6
  6. package/data/catalog/skills/nustack/references/monorepo-setup.md +13 -13
  7. package/data/catalog/skills/nustack/references/publishing.md +40 -39
  8. package/data/harness-index.json +1 -1
  9. package/data/harnesses/code/harness.json +2 -2
  10. package/data/harnesses/code/hooks/approved-packages.md +1 -2
  11. package/data/harnesses/code/rules/frontend.md +5 -5
  12. package/data/harnesses/code/rules/pnpm.md +2 -2
  13. package/data/harnesses/code/skills/boundary/SKILL.md +33 -22
  14. package/data/harnesses/code/skills/boundary/references/index.md +2 -4
  15. package/data/harnesses/code/skills/boundary/references/mechanisms.md +3 -10
  16. package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
  17. package/data/harnesses/code/skills/boundary/references/packs/frontend.md +17 -17
  18. package/data/harnesses/code/skills/boundary/references/packs/generic-tail.md +1 -1
  19. package/data/harnesses/code/skills/brainstorm/README.md +11 -13
  20. package/data/harnesses/code/skills/brainstorm/SKILL.md +150 -132
  21. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +48 -51
  22. package/data/harnesses/code/skills/brainstorm/references/harvest.md +51 -56
  23. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +48 -42
  24. package/data/harnesses/code/skills/design/SKILL.md +31 -35
  25. package/data/harnesses/code/skills/design/components/charts.md +121 -43
  26. package/data/harnesses/code/skills/design/components/collections.md +209 -41
  27. package/data/harnesses/code/skills/design/components/feedback.md +86 -25
  28. package/data/harnesses/code/skills/design/components/hooks.md +198 -12
  29. package/data/harnesses/code/skills/design/components/index.md +93 -71
  30. package/data/harnesses/code/skills/design/components/inputs.md +249 -157
  31. package/data/harnesses/code/skills/design/components/layout.md +98 -38
  32. package/data/harnesses/code/skills/design/components/media.md +46 -25
  33. package/data/harnesses/code/skills/design/components/motion.md +56 -46
  34. package/data/harnesses/code/skills/design/components/navigation.md +54 -15
  35. package/data/harnesses/code/skills/design/components/overlays.md +51 -41
  36. package/data/harnesses/code/skills/design/components/setup.md +84 -5
  37. package/data/harnesses/code/skills/design/components/typography.md +72 -22
  38. package/data/harnesses/code/skills/design/components/utils.md +47 -13
  39. package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
  40. package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
  41. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
  42. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
  43. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
  44. package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
  45. package/data/harnesses/code/skills/design/data/iconography.md +2 -2
  46. package/data/harnesses/code/skills/design/references/compose.md +14 -16
  47. package/data/harnesses/code/skills/design/references/emission.md +6 -6
  48. package/data/harnesses/code/skills/design/references/foundations.md +5 -5
  49. package/data/harnesses/code/skills/design/references/intake.md +6 -6
  50. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  51. package/data/harnesses/code/skills/design/references/ship-gate.md +5 -5
  52. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +4 -4
  53. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +1 -1
  54. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +1 -1
  55. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +1 -1
  56. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +1 -1
  57. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +2 -2
  58. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +1 -1
  59. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +1 -1
  60. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +1 -1
  61. package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
  62. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
  63. package/data/harnesses/code/skills/documentation/SKILL.md +5 -5
  64. package/data/harnesses/code/skills/documentation/references/examples.md +22 -22
  65. package/data/harnesses/code/skills/documentation/references/frontmatter.md +3 -3
  66. package/data/harnesses/code/skills/documentation/references/instruction-style.md +3 -3
  67. package/data/harnesses/code/skills/documentation/references/source-comments.md +3 -3
  68. package/data/harnesses/code/skills/documentation/references/style-guide.md +5 -5
  69. package/data/harnesses/code/skills/documentation/references/untemplated.md +8 -8
  70. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +3 -2
  71. package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -1
  72. package/data/harnesses/code/skills/documentation/templates/acceptance-criteria.md +1 -1
  73. package/data/harnesses/code/skills/documentation/templates/api-reference.md +1 -1
  74. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +3 -7
  75. package/data/harnesses/code/skills/documentation/templates/behavioral-checklist.md +1 -1
  76. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +1 -1
  77. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +1 -1
  78. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +3 -3
  79. package/data/harnesses/code/skills/documentation/templates/doctrine.md +1 -1
  80. package/data/harnesses/code/skills/documentation/templates/domain-model.md +1 -1
  81. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +1 -1
  82. package/data/harnesses/code/skills/documentation/templates/feature.md +3 -3
  83. package/data/harnesses/code/skills/documentation/templates/handover.md +2 -2
  84. package/data/harnesses/code/skills/documentation/templates/implementation-map.md +1 -1
  85. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +1 -1
  86. package/data/harnesses/code/skills/documentation/templates/non-goals.md +1 -1
  87. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +2 -2
  88. package/data/harnesses/code/skills/documentation/templates/package.md +1 -1
  89. package/data/harnesses/code/skills/documentation/templates/protected-files.md +1 -1
  90. package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
  91. package/data/harnesses/code/skills/documentation/templates/security-overview.md +1 -1
  92. package/data/harnesses/code/skills/documentation/templates/system-overview.md +1 -1
  93. package/data/harnesses/code/skills/documentation/templates/system.md +1 -1
  94. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +1 -1
  95. package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +3 -5
  96. package/data/harnesses/code/skills/issue-bridge/SKILL.md +51 -16
  97. package/data/harnesses/code/skills/issue-bridge/references/trackers/github.md +5 -5
  98. package/data/harnesses/code/skills/issue-bridge/references/trackers/jira.md +11 -8
  99. package/data/harnesses/code/skills/issue-bridge/references/trackers/linear.md +16 -11
  100. package/data/harnesses/code/skills/nustack-graph/SKILL.md +38 -29
  101. package/data/harnesses/code/skills/polygraph/references/dispatch.md +31 -18
  102. package/data/harnesses/code/skills/polygraph/references/rows.md +11 -6
  103. package/data/harnesses/code/skills/schema-design/SKILL.md +39 -41
  104. package/data/harnesses/code/skills/test/SKILL.md +38 -42
  105. package/data/harnesses/code/skills/testing/SKILL.md +83 -73
  106. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +156 -193
  107. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +15 -15
  108. package/data/harnesses/delivery/harness.json +2 -2
  109. package/data/harnesses/delivery/skills/brainstorm/README.md +11 -13
  110. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +150 -132
  111. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +48 -51
  112. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +51 -56
  113. package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +48 -42
  114. package/data/harnesses/delivery/skills/cost-report/SKILL.md +10 -10
  115. package/data/harnesses/delivery/skills/documentation/SKILL.md +5 -5
  116. package/data/harnesses/delivery/skills/documentation/references/examples.md +22 -22
  117. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +3 -3
  118. package/data/harnesses/delivery/skills/documentation/references/instruction-style.md +3 -3
  119. package/data/harnesses/delivery/skills/documentation/references/source-comments.md +3 -3
  120. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +5 -5
  121. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +8 -8
  122. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +3 -2
  123. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -1
  124. package/data/harnesses/delivery/skills/documentation/templates/acceptance-criteria.md +1 -1
  125. package/data/harnesses/delivery/skills/documentation/templates/api-reference.md +1 -1
  126. package/data/harnesses/delivery/skills/documentation/templates/architecture-decision.md +3 -7
  127. package/data/harnesses/delivery/skills/documentation/templates/behavioral-checklist.md +1 -1
  128. package/data/harnesses/delivery/skills/documentation/templates/changelog-entry.md +1 -1
  129. package/data/harnesses/delivery/skills/documentation/templates/changelog-index.md +1 -1
  130. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +3 -3
  131. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +1 -1
  132. package/data/harnesses/delivery/skills/documentation/templates/domain-model.md +1 -1
  133. package/data/harnesses/delivery/skills/documentation/templates/environment-registry.md +1 -1
  134. package/data/harnesses/delivery/skills/documentation/templates/feature.md +3 -3
  135. package/data/harnesses/delivery/skills/documentation/templates/handover.md +2 -2
  136. package/data/harnesses/delivery/skills/documentation/templates/implementation-map.md +1 -1
  137. package/data/harnesses/delivery/skills/documentation/templates/migration-runbook.md +1 -1
  138. package/data/harnesses/delivery/skills/documentation/templates/non-goals.md +1 -1
  139. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +2 -2
  140. package/data/harnesses/delivery/skills/documentation/templates/package.md +1 -1
  141. package/data/harnesses/delivery/skills/documentation/templates/protected-files.md +1 -1
  142. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
  143. package/data/harnesses/delivery/skills/documentation/templates/security-overview.md +1 -1
  144. package/data/harnesses/delivery/skills/documentation/templates/system-overview.md +1 -1
  145. package/data/harnesses/delivery/skills/documentation/templates/system.md +1 -1
  146. package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +1 -1
  147. package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +3 -5
  148. package/data/harnesses/delivery/skills/escalate/SKILL.md +11 -11
  149. package/data/harnesses/delivery/skills/prompt-eval/SKILL.md +8 -8
  150. package/data/harnesses/delivery/skills/prompt-library/SKILL.md +30 -9
  151. package/data/harnesses/delivery/skills/route/SKILL.md +8 -8
  152. package/data/harnesses/etna/harness.json +2 -2
  153. package/data/harnesses/etna/skills/boundary/SKILL.md +33 -22
  154. package/data/harnesses/etna/skills/boundary/references/index.md +2 -4
  155. package/data/harnesses/etna/skills/boundary/references/mechanisms.md +3 -10
  156. package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
  157. package/data/harnesses/etna/skills/boundary/references/packs/frontend.md +17 -17
  158. package/data/harnesses/etna/skills/boundary/references/packs/generic-tail.md +1 -1
  159. package/data/harnesses/etna/skills/brainstorm/README.md +11 -13
  160. package/data/harnesses/etna/skills/brainstorm/SKILL.md +150 -132
  161. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +48 -51
  162. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +51 -56
  163. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +48 -42
  164. package/data/harnesses/etna/skills/documentation/SKILL.md +5 -5
  165. package/data/harnesses/etna/skills/documentation/references/examples.md +22 -22
  166. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +3 -3
  167. package/data/harnesses/etna/skills/documentation/references/instruction-style.md +3 -3
  168. package/data/harnesses/etna/skills/documentation/references/source-comments.md +3 -3
  169. package/data/harnesses/etna/skills/documentation/references/style-guide.md +5 -5
  170. package/data/harnesses/etna/skills/documentation/references/untemplated.md +8 -8
  171. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +3 -2
  172. package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -1
  173. package/data/harnesses/etna/skills/documentation/templates/acceptance-criteria.md +1 -1
  174. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +1 -1
  175. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +3 -7
  176. package/data/harnesses/etna/skills/documentation/templates/behavioral-checklist.md +1 -1
  177. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +1 -1
  178. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +1 -1
  179. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +3 -3
  180. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +1 -1
  181. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +1 -1
  182. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +1 -1
  183. package/data/harnesses/etna/skills/documentation/templates/feature.md +3 -3
  184. package/data/harnesses/etna/skills/documentation/templates/handover.md +2 -2
  185. package/data/harnesses/etna/skills/documentation/templates/implementation-map.md +1 -1
  186. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +1 -1
  187. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +1 -1
  188. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +2 -2
  189. package/data/harnesses/etna/skills/documentation/templates/package.md +1 -1
  190. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +1 -1
  191. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
  192. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +1 -1
  193. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +1 -1
  194. package/data/harnesses/etna/skills/documentation/templates/system.md +1 -1
  195. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +1 -1
  196. package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +3 -5
  197. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +156 -193
  198. package/data/harnesses/etna/skills/workflow-mapper/references/patterns.md +15 -15
  199. package/data/harnesses/hr/harness.json +2 -2
  200. package/data/harnesses/hr/skills/evaluator/SKILL.md +71 -73
  201. package/data/harnesses/hr/skills/evaluator/criteria/code-quality.md +28 -47
  202. package/data/harnesses/hr/skills/evaluator/criteria/deployment-readiness.md +33 -43
  203. package/data/harnesses/hr/skills/evaluator/criteria/maintainability.md +34 -46
  204. package/data/harnesses/hr/skills/evaluator/criteria/mechanical-ambition.md +13 -13
  205. package/data/harnesses/hr/skills/evaluator/criteria/problem-substantiveness.md +7 -7
  206. package/data/harnesses/hr/skills/evaluator/criteria/testing.md +36 -41
  207. package/data/harnesses/hr/skills/evaluator/criteria/ux-mechanics.md +25 -11
  208. package/data/harnesses/hr/skills/evaluator/criteria/value-articulation.md +7 -7
  209. package/data/harnesses/hr/skills/evaluator/preflight.md +27 -46
  210. package/data/harnesses/hr/skills/interview-eval/SKILL.md +37 -42
  211. package/data/harnesses/hr/skills/interview-eval/rubric.md +21 -23
  212. package/package.json +2 -2
@@ -5,7 +5,7 @@ description: "The test-lifecycle skill — three modes. Plan-gate mode: after `b
5
5
 
6
6
  # Testing — Ledger, Layers, Gate
7
7
 
8
- One skill owns the test lifecycle's three procedural moments; the standing constraints (regimes, deferral, gate preconditions) are `.claude/rules/testing.md` and are never restated here. Pick the mode from the moment:
8
+ One skill owns the three procedural moments of the test lifecycle. The standing constraints — the regimes, deferral, the gate's preconditions — are `.claude/rules/testing.md` and are never restated here. Pick the mode from the moment:
9
9
 
10
10
  | Moment | Mode |
11
11
  | --- | --- |
@@ -17,32 +17,38 @@ One skill owns the test lifecycle's three procedural moments; the standing const
17
17
 
18
18
  ## Plan-gate mode — the Test Obligations ledger
19
19
 
20
- You derive the tests an implementation plan owes and pin them into the plan as an explicit, reviewable manifest — in the same pass that writes the plan, after `boundary`'s amendments are folded, ordered second; a plan shown to the user already carries this ledger. You never write a test file; you write the **ledger gate mode discharges**, so the gate proves a checklist instead of a vibe.
20
+ You derive the tests an implementation plan owes and write them into the plan as a reviewable manifest — in the same pass that writes the plan, ordered second after `boundary`'s amendments are folded. A plan shown to the user already carries this ledger. **You never write a test file**: tests written before the code exists couple to an implementation that has not settled, and tests written inside the build loop tax every iteration. You write the ledger gate mode discharges, so the gate proves a checklist rather than an impression.
21
21
 
22
- **The litmus is "which promise, at which altitude, proven by what?"** A plan promises behavior; each promise earns exactly one test at the cheapest layer that can actually prove it. Spend your reading deciding the *layer* and the *oracle*, not on prose. Writing tests *before* the code exists fabricates implementation coupling or leaves the suite red for the plan's duration; writing them *during* the build loop taxes every iteration — so the plan gate emits obligations, the loop stays free of test files, and gate mode discharges the manifest in one pass.
22
+ **The litmus is "which promise, at which altitude, proven by what?"** Each promise earns exactly one test at the cheapest layer that can prove it. Spend the reading on the *layer* and the *oracle*, not on prose.
23
23
 
24
24
  ### Contract sources
25
25
 
26
- - **The plan's Proposed Changes** — each file/entity/API change is a behavior that may owe a test.
27
- - **The owning LLD** (`docs/features/{feature}.md`, via the ownership index) — every obligation names the LLD promise it proves; the LLD is referenced, never restated. This one-directional chain (LLD → manifest → tests + Completion checklist) is what stops the artifacts drifting.
28
- - **`.claude/rules/testing.md`** — frameworks and canonical placement per stack; target paths come from there, never invented. The repo's existing runner always wins.
29
- - **`boundary`'s output** — a HIGH/CRITICAL finding is itself a behavior owed a regression test. Fold boundary's amendments first, then read the amended plan.
26
+ - **The plan's Proposed Changes** — each file, entity, or API change is a behavior that may owe a test.
27
+ - **The owning LLD** (`docs/features/{feature}.md`, via the ownership index) — every obligation names the LLD promise it proves. The LLD is referenced, never restated; the chain runs one way (LLD → ledger → tests and checklist), which is what keeps the artifacts from drifting.
28
+ - **`.claude/rules/testing.md`** — frameworks and canonical placement per stack. Target paths come from there, never invented; the repo's existing runner always wins.
29
+ - **`boundary`'s output** — a HIGH or CRITICAL finding is itself a behavior owed a regression test. Read the plan after boundary's amendments are folded.
30
30
 
31
31
  ### Layer assignment
32
32
 
33
- Assign each behavior the **cheapest layer that can prove it**, then name the oracle. The ledger altitudes are `unit` / `component` / `integration` / `e2e` (strata mapping: § Bridge below). **Integration is the default for server behavior** — a route/handler against a real in-memory datastore via the app instance; server-side error paths, races, and idempotency belong there with injected faults (network mock, fake timers, forced constraint). **A journey is the default for a rendered surface** — any promise a user could observe in a real browser (what a screen shows over real rows, what a click changes, where navigation lands and what the URL carries, what a refused or failed request shows) is owed at layer 8 as `extend journey <surface>`, never as a component test; the surface's own fault paths (a 500 on load, a 400 on submit) stay in the journey too, injected at the app's own endpoint from the browser. What a rendered surface still owes below the browser is enumerated in § Placement discipline: a pure derivation with real branches (layer 6), a regression pin for a state the journey world cannot reach (layer 7), the wire's error taxonomy (layer 5), and geometry that shipped wrong (7b).
33
+ Assign each behavior the **cheapest layer that can prove it**, then name the oracle. The ledger altitudes are `unit` / `component` / `integration` / `e2e`; § Bridge maps them to strata.
34
34
 
35
- **The journey world is a precondition, not an excuse.** A rendered surface owes its journeys whether or not the repo's e2e config boots today. If it does not — no config, a world pointed at a deleted package, a job parked in CI — the plan's **first** obligation row is wiring it (`e2e · <config> · the world builds, seeds, boots and one journey passes from a cold shell`), and every journey row names it as a dependency. Emitting `blocked` rows in place of journeys and routing the promises down to component tests is the failure this rule exists to stop: a broken world that nothing obliges anyone to fix stays broken, and every UI promise for months lands in a simulated DOM. Density is one spec file per surface and one `test()` per user journey, carrying as many assertions as the journey has observable steps — prefer **"extend journey `<surface>`"** over a new file.
35
+ - **Integration is the default for server behavior** — a route or handler against a real in-memory datastore via the app instance. Server-side error paths, races, and idempotency belong there, with injected faults (network mock, fake timers, a forced constraint).
36
+ - **A journey is the default for a rendered surface.** Any promise a user could observe in a real browser — what a screen shows over real rows, what a click changes, where navigation lands and what the URL carries, what a refused or failed request shows — is owed at layer 8 as `extend journey <surface>`, **never** as a component test. The surface's own fault paths (a 500 on load, a 400 on submit) stay in the journey, injected at the app's own endpoint from the browser.
37
+ - **Below the browser, a rendered surface owes only** a pure derivation with real branches (layer 6), a regression pin for a state the journey world cannot reach (layer 7), the wire's error taxonomy (layer 5), and geometry that shipped wrong (7b) — § Placement discipline.
38
+
39
+ **The journey world is a precondition, not an excuse.** A rendered surface owes its journeys whether or not the repo's e2e config boots today. When it does not — no config, a world pointed at a deleted package, a job parked in CI — the plan's **first** row wires it (`e2e · <config> · the world builds, seeds, boots and one journey passes from a cold shell`), and every journey row names that row as a dependency. **Never emit `blocked` rows in place of journeys and route the promises down to component tests**: a broken world nothing obliges anyone to fix stays broken, and every UI promise lands in a simulated DOM for as long as it does.
40
+
41
+ Density is one spec file per surface and one `test()` per user journey, carrying as many assertions as the journey has observable steps — prefer **"extend journey `<surface>`"** over a new file.
36
42
 
37
43
  ### Run (plan-gate)
38
44
 
39
- **Input:** a plan path (given, or the newest in `docs/history/plans/`), boundary-checked with amendments folded; skipped on a boundary BLOCK. For a non-plan diff, the hunks stand in for Proposed Changes but the obligations are paid **immediately** — only a plan has a ledger to defer into.
45
+ **Input:** a plan path (given, or the newest in `docs/history/plans/`), boundary-checked with amendments folded. **Skip on a boundary BLOCK.** For a non-plan diff the hunks stand in for Proposed Changes, but the obligations are paid **immediately** — only a plan has a ledger to defer into.
40
46
 
41
- 1. **Build the behavior list** from Proposed Changes + the LLD's promises + HIGH/CRITICAL boundary findings. Note compiler-guarded behaviors — they owe **no** test.
42
- 2. **Assign layer + oracle** per behavior; cheapest proving layer wins.
43
- 3. **Map to a target file** per `testing.md`; name fixtures/factories and fault injection; use the repo-standard fake-data source.
47
+ 1. **Build the behavior list** from Proposed Changes, the LLD's promises, and HIGH/CRITICAL boundary findings. Mark compiler-guarded behaviors — they owe **no** test.
48
+ 2. **Assign layer and oracle** per behavior; the cheapest proving layer wins.
49
+ 3. **Map each to a target file** per `testing.md`; name fixtures, factories, and fault injection; use the repo-standard fake-data source.
44
50
  4. **Route by surface**: a user-observable promise on a rendered surface → `e2e` (its surface's journey, with the world-wiring row first if the world does not boot); server behavior → `integration`; only what § Placement discipline keeps below the browser → `component` / `unit`.
45
- 5. **Emit the Test Obligations section into the plan** (an executor dispatched with only the plan sees nothing else), plus a one-line chat summary:
51
+ 5. **Emit the Test Obligations section into the plan** — an executor dispatched with only the plan sees nothing else — plus a one-line chat summary:
46
52
 
47
53
  ```
48
54
  ## Test Obligations
@@ -54,19 +60,17 @@ Assign each behavior the **cheapest layer that can prove it**, then name the ora
54
60
  Completion checklist: docs/tests/{feature}.md (derived at the gate, not now)
55
61
  ```
56
62
 
57
- A behavior with no obligation is stated too, with the reason — "none — compiler-guarded" reads as *checked*; an empty cell reads as *not analyzed*. A short manifest is valid — do not pad. **`Outcome` is written empty here — it is gate mode's cell**, and the completion walls read it: a plan cannot reach `Status: Complete` while any row's Outcome is empty.
63
+ State a behavior with no obligation too, with its reason — "none — compiler-guarded" reads as *checked*, an empty cell as *not analyzed*. A short manifest is valid; never pad it. **Leave `Outcome` empty — it is gate mode's cell**, and a plan cannot reach `Status: Complete` while any row's Outcome is empty.
58
64
 
59
65
  ---
60
66
 
61
67
  ## Placement mode — layered test strategy
62
68
 
63
- You decide **where a test lives and what it may assert**. **The litmus is "where can this defect originate?"** A test lives with the only layer that can produce the defect it catches. "The 409 response carries the current body" can only break in a route handler — service-contract layer. "The buffer the user typed survives the 409" can only break in component state — component layer. Same feature, two owners, two tests, zero overlap. Placement is decided by this question alone — testing a feature wherever you first *see* it is what makes suites flat, duplicative, and multiplicative in cost.
69
+ You decide **where a test lives and what it may assert**. **The litmus is "where can this defect originate?"** A test lives with the only layer that can produce the defect it catches. "The 409 response carries the current body" can only break in a route handler — service-contract layer. "The buffer the user typed survives the 409" can only break in component state — component layer. Same feature, two owners, two tests, zero overlap. **Placement is decided by this question alone** — testing a feature wherever you first *see* it is what makes suites flat, duplicative, and multiplicative in cost.
64
70
 
65
71
  ### The stack
66
72
 
67
- The maximum form, for a full-stack application. Each layer names what only it can break, the oracle that proves it, and the technology **class** — the concrete framework comes from `testing.md`'s stack table, never from here.
68
-
69
- **7b is lettered, not numbered, because it is layer 7's other half rather than a rung above it** — same subject, same tests-shaped artifacts, a different oracle. It exists because a simulated DOM computes no layout: `getBoundingClientRect()` returns zeros, so an assertion about what a person can actually see has nowhere legal to live and comes out as a class-name proxy (`classList.contains("w-24")`) that fails on a benign restyle and passes on `w-[10000px]`. A stack without a rendered surface has no 7b.
73
+ The maximum form, for a full-stack application. Each layer names what only it can break, the oracle that proves it, and the technology **class** — the concrete framework comes from `testing.md`'s stack table, never from here. 7b is lettered because it is layer 7's other half, not a rung above it: same subject, a real-engine oracle. A stack without a rendered surface has no 7b.
70
74
 
71
75
  | # | Layer | Owns (defects only it can originate) | Oracle | Technology class |
72
76
  | --- | --- | --- | --- | --- |
@@ -80,11 +84,11 @@ The maximum form, for a full-stack application. Each layer names what only it ca
80
84
  | 7b | **Rendered composition** | Defects only a real rendering engine produces: geometry (overlap, clipping, a container that grows when a panel opens), the theme cascade where your tokens meet a component library's, focus order and accessible names through a third-party primitive | Measurement in a real browser engine — `getBoundingClientRect`, computed style, the accessibility tree | Real-renderer component runner (the unit runner's browser mode), **never** a simulated DOM |
81
85
  | 8 | **Journeys** | Everything a user can observe on a rendered surface: what a screen shows over real rows, what an action changes, where navigation lands and what the URL carries, what a refused or failed request shows, a create-then-delete round trip — and composition: the build serves, auth flows end to end | A real browser (or the real binary/wire, for a stack that renders nothing) against the really-running app over a seeded world; faults injected at the app's own endpoints | Browser/process driver class; **one spec file per surface**, one test per user journey, variants wherever a user can see them |
82
86
 
83
- Layer 4 is the hinge. Every layer ≥5 runs on the assumption that layers 1–3 are green — and the artifact makes that assumption *enforceable*: when the provider's response type changes, the fixture stops compiling, and every consumer test fails at typecheck before it runs. A consumer-side test that hand-writes a wire response has smuggled unverified layer-3 knowledge upward; route it through the artifact.
87
+ **Layer 4 is the hinge.** Every layer ≥5 assumes layers 1–3 are green, and the artifact makes that assumption enforceable: when the provider's response type changes, the fixture stops compiling and every consumer test fails at typecheck. **A consumer-side test never hand-writes a wire response** — that smuggles unverified layer-3 knowledge upward; route it through the artifact.
84
88
 
85
89
  ### How many layers — derived, never chosen
86
90
 
87
- **A layer exists iff the application has the boundary that can originate that layer's defects; an absent boundary makes the layer vanish** — it never merges into a neighbor. Merging is the failure mode: "simplifying" layers 3 and 7 together reinvents the flat feature test, where every UI assertion silently re-verifies the API beneath it and cost goes multiplicative again.
91
+ **A layer exists iff the application has the boundary that can originate that layer's defects; an absent boundary makes the layer vanish — it never merges into a neighbor.** Merging layers 3 and 7 to "simplify" reinvents the flat feature test: every UI assertion silently re-verifies the API beneath it, and cost goes multiplicative.
88
92
 
89
93
  | Application shape | Strata present |
90
94
  | --- | --- |
@@ -94,45 +98,42 @@ Layer 4 is the hinge. Every layer ≥5 runs on the assumption that layers 1–3
94
98
  | Frontend on a third-party API | 4 (derived from the API's published spec), 5, 6, 7, 8 |
95
99
  | Library | 2 only — its exported API is the contract, its tests are its consumers |
96
100
 
97
- Derive the stack first, then place tests: a placement argument that starts "this feels like an integration test" has skipped the derivation.
101
+ Derive the stack before placing a test: a placement argument that starts "this feels like an integration test" has skipped the derivation.
98
102
 
99
103
  ### Placement discipline
100
104
 
101
- - **Three conditions put a UI test below a real browser; all must hold.** *(a)* Its assertion names a **product promise**, not a construction detail — litmus: would it survive a total visual redesign that changes no behavior? `not.toHaveProperty("taskMode")` survives; `classList.contains("w-24")` does not. *(b)* The defect it catches can **originate below the layout engine** — a wrong wire path, a dropped field, a state-machine bug, a wrong string. *(c)* **The surface's journey cannot reach it** — the state needs a fixture the seeded world lacks, an external system, or an orchestration detail no user step exposes. Fail (a) or (b) and the honest home is 7b; fail (c) and the home is the journey, as one more assertion.
102
- - **Geometry may never be asserted in a runner without a layout engine.** There is no valid proxy: a class token is not a width, and a test that pretends otherwise is simultaneously brittle and blind. When the only available runner simulates the DOM, the behavior is driven and pinned at 7b — never approximated.
105
+ - **A UI test sits below a real browser only when all three conditions hold.** *(a)* Its assertion names a **product promise**, not a construction detail — would it survive a total visual redesign that changes no behavior? `not.toHaveProperty("taskMode")` survives; `classList.contains("w-24")` does not. *(b)* The defect it catches can **originate below the layout engine** — a wrong wire path, a dropped field, a state-machine bug, a wrong string. *(c)* **The surface's journey cannot reach it** — the state needs a fixture the seeded world lacks, an external system, or an orchestration detail no user step exposes. Fail (a) or (b) and the home is 7b; fail (c) and the home is the journey, as one more assertion.
106
+ - **Never assert geometry in a runner without a layout engine.** A simulated DOM computes no layout — `getBoundingClientRect()` returns zeros — so the assertion comes out as a class-name proxy that fails on a benign restyle and passes on `w-[10000px]`. There is no valid proxy: when the only available runner simulates the DOM, drive and pin the behavior at 7b, never approximate it.
103
107
  - **An assertion provable at two layers is misplaced — it belongs at the lower one.** The duplication check is mechanical, not judgment.
104
- - **Behavior variants sink to the cheapest layer that owns them** — a derivation's variants to 6, a rule's to 2. A variant a user can *see* (a second sort order, a filtered roster, a refused form) belongs in the journey that shows it, as one more assertion, not as a component case. A variant at layer 3 pays wire tax on a domain test.
105
- - **One representative path upward for the server; the whole surface for the browser.** Layer 3 keeps one happy path per route plus exhaustive coverage of *contract edges only*. Layer 8 keeps one spec per surface covering everything a user can reach in the seeded world — the count is set by the surface, never by a cap. A cap on journeys is what pushes UI promises into a simulated DOM, and a simulated DOM talks to a hand-written fake of the wire, so a route rename or an envelope change passes it green.
106
- - **7b stays small by construction.** It holds geometry regressions that actually shipped and the handful of composition assertions a component library's contract cannot make alone (the theme cascade, the accessible name through its primitive). It is not a second component suite — a behavior that a simulated DOM can prove has no business paying a browser's price.
107
- - **External systems enter as modeled fakes, not spies.** A fake implements the port's semantics so tests assert resulting state; a spy only proves methods were called, which passes just as happily with the bytes swapped.
108
- - **Failure localization is the payoff to protect.** One defect turns exactly one layer red, at its owner. When a single change reddens several layers, at most one of those tests was correctly placed — treat the rest as findings.
109
-
110
- Layering makes cost **additive** — a new API behavior costs one layer-2 test and maybe a layer-3 edge, zero frontend tests; a new UI state costs one more assertion in its surface's journey, zero backend tests. A flat suite pays N×M, because every top-layer path implicitly re-verifies every behavior beneath it.
108
+ - **Behavior variants sink to the cheapest layer that owns them** — a derivation's variants to 6, a rule's to 2. A variant a user can *see* (a second sort order, a filtered roster, a refused form) is one more assertion in the journey that shows it, not a component case. A variant at layer 3 pays wire tax on a domain test.
109
+ - **One representative path upward for the server; the whole surface for the browser.** Layer 3 keeps one happy path per route plus exhaustive coverage of *contract edges only*. Layer 8 keeps one spec per surface covering everything a user can reach in the seeded world — the surface sets the count, **never** a cap. A cap on journeys pushes UI promises into a simulated DOM, which talks to a hand-written fake of the wire, so a route rename or an envelope change passes it green.
110
+ - **7b stays small by construction.** It holds geometry regressions that actually shipped and the few composition assertions a component library's contract cannot make alone (the theme cascade, the accessible name through its primitive). A behavior a simulated DOM can prove does not pay a browser's price.
111
+ - **External systems enter as modeled fakes, not spies.** A fake implements the port's semantics so tests assert resulting state; a spy proves only that methods were called, and passes just as happily with the bytes swapped.
112
+ - **Protect failure localization.** One defect turns exactly one layer red, at its owner. When a single change reddens several layers, at most one of those tests was correctly placed — treat the rest as findings.
111
113
 
112
114
  ### The tree
113
115
 
114
- ```
115
- tests/
116
- schema/ L1 — infrastructure-bound runner (real engine)
117
- domain/ L2 — infrastructure-bound runner (real storage, modeled ports)
118
- routes/ L3 — infrastructure-bound runner (in-process app)
119
- contract/ L4 — no runner; typed fixtures + interception handlers
120
- client/ L5 — plain unit runner
121
- view/ L6 — plain unit runner
122
- component/ L7 — unit runner + DOM environment (per-file opt-in); residual where e2e/ exists
123
- rendered/ L7b — the same runner in browser mode; a real engine, kept small
124
- helpers/ shared seeds, fakes, and builders — owned by no stratum
125
- e2e/ L8 — one spec per surface over a seeded world; its own config, never mixed into the unit runner's glob
126
- ```
127
-
128
- - **A stratum the app lacks gets no directory** — an empty `component/` in a backend service is a lie about the app's shape.
129
- - **One shared glob list, imported by both runner configs** — two hand-maintained lists drift; one imported constant cannot.
130
- - **Concrete runner, framework, and DOM environment come from `testing.md`'s per-stack table** — this skill names the slot, never the brand.
131
- - **Contract modules the provider binds** (the layer-4 source types) live in the app's shared source zone — importable by both sides; `tests/contract/` holds only the compiled fixtures and fakes.
116
+ | Path | Stratum | Runner |
117
+ | --- | --- | --- |
118
+ | `tests/schema/` | L1 | infrastructure-bound runner (real engine) |
119
+ | `tests/domain/` | L2 | infrastructure-bound runner (real storage, modeled ports) |
120
+ | `tests/routes/` | L3 | infrastructure-bound runner (in-process app) |
121
+ | `tests/contract/` | L4 | no runner; typed fixtures + interception handlers |
122
+ | `tests/client/` | L5 | plain unit runner |
123
+ | `tests/view/` | L6 | plain unit runner |
124
+ | `tests/component/` | L7 | unit runner + DOM environment (per-file opt-in); residual where `e2e/` exists |
125
+ | `tests/rendered/` | L7b | the same runner in browser mode; a real engine, kept small |
126
+ | `tests/helpers/` | none | shared seeds, fakes, and builders |
127
+ | `e2e/` | L8 | one spec per surface over a seeded world; its own config, never mixed into the unit runner's glob |
128
+
129
+ - **A stratum the app lacks gets no directory** — an empty `component/` in a backend service misstates the app's shape.
130
+ - **One shared glob list, imported by both runner configs** — two hand-maintained lists drift.
131
+ - **The concrete runner, framework, and DOM environment come from `testing.md`'s per-stack table** — this skill names the slot, never the brand.
132
+ - **Contract modules the provider binds** (the layer-4 source types) live in the app's shared source zone, importable by both sides; `tests/contract/` holds only the compiled fixtures and fakes.
132
133
 
133
134
  ### Bridge to the obligation ledger
134
135
 
135
- The ledger's altitudes are coarse names for where a test *runs*; the strata say what it may *assert*:
136
+ The ledger's altitudes name where a test *runs*; the strata say what it may *assert*:
136
137
 
137
138
  | Ledger altitude | Strata it covers |
138
139
  | --- | --- |
@@ -141,48 +142,57 @@ The ledger's altitudes are coarse names for where a test *runs*; the strata say
141
142
  | component | 7, 7b |
142
143
  | e2e | 8 |
143
144
 
144
- When writing or discharging a ledger row, name the stratum, not just the altitude — "integration" alone leaves open whether the row asserts a schema invariant, a business rule, or an envelope: three owners, three oracles.
145
+ **When writing or discharging a ledger row, name the stratum, not just the altitude** — "integration" alone leaves open whether the row asserts a schema invariant, a business rule, or an envelope: three owners, three oracles.
145
146
 
146
147
  ### Run (placement)
147
148
 
148
- 1. **Derive the stack** from the application's real boundaries (storage? published wire? separate client? DOM?).
149
- 2. **Place each behavior** by the litmus; name stratum, oracle, technology class; take the concrete framework and file placement from `testing.md`.
149
+ 1. **Derive the stack** from the application's real boundaries — storage, a published wire, a separate client, a DOM.
150
+ 2. **Place each behavior** by the litmus; name its stratum, oracle, and technology class; take the concrete framework and file placement from `testing.md`.
150
151
  3. **Flag violations, don't just place** — assertions provable lower, derivation variants above 6, hand-written wire fixtures above layer 4, spies where fakes should model state, and UI promises pinned at 7 that the surface's journey can reach.
151
- 4. **Report as a stratum map** — one line per stratum: exists/absent (why), what lives there, what is misplaced and where it moves. For a plan, feed the strata into the ledger's rows.
152
+ 4. **Report a stratum map** — one line per stratum: present or absent (and why), what lives there, what is misplaced and where it moves. For a plan, feed the strata into the ledger's rows.
152
153
 
153
154
  ---
154
155
 
155
156
  ## Gate mode — discharge the ledger
156
157
 
157
- Runs as the tail of every build pass — the session opens it the moment the unit's code is written, without asking (constraints — preconditions, verdict-inline, tier, honesty — are `.claude/rules/testing.md` § The gate). **Drive the real thing first, then pin what must not regress**: driving finds the defects that matter to a user, and shows which behaviors are worth the permanent cost of a test.
158
+ The tail of every build pass: the session opens it the moment the unit's code is written, without asking. Its constraints — preconditions, the inline verdict, tier, honest reporting — are `.claude/rules/testing.md` § The gate. **Drive the real thing first, then pin what must not regress** — driving finds the defects that matter to a user and shows which behaviors are worth a test's permanent cost.
158
159
 
159
- 1. **Write the checklist** — derive or update `docs/tests/{feature}.md` from the ledger and the LLD's promises (the `documentation` skill's `templates/behavioral-checklist.md`; one `**Assert**` per observable). Derived before the driving it is the script; derived after, it is merely a report with nothing to trace tests back to. `docs/tests/{feature}.md` pairs with `docs/features/{feature}.md` — writing a checklist whose feature doc does not exist is the tell that one is owed; check here, when the checklist is named.
160
+ 1. **Write the checklist** — derive or update `docs/tests/{feature}.md` from the ledger and the LLD's promises (the `documentation` skill's `templates/behavioral-checklist.md`; one `**Assert**` per observable). **Derive it before driving** — before, it is the script; after, it is a report with nothing to trace tests back to. `docs/tests/{feature}.md` pairs with `docs/features/{feature}.md`; a checklist whose feature doc does not exist means one is owed — check here, when the checklist is named.
160
161
 
161
- **The gate owns these files, not just their first draft.** Whoever drives a checklist maintains it in the same pass — nothing else in the repo is watching, because a checklist owns no code and no `owns:` glob implicates it, so a surface can be rewritten under a checklist and every hook stays silent. Before driving, reconcile the file against the surface you are about to drive: **retire** sections whose behavior no longer exists (delete them — a checklist is a truth document, and the history lives in git), **add** sections for behavior shipped since the last run, and **repair every `Pinned:` trace**, because a trace naming a test that no longer exists is worse than no trace — it reports coverage that cannot fail. A section you cannot pin says `none yet` and names the test it owes. **Never soften an assertion to make the run green**: the checklist states what the feature promises, the run records what happened, and the backlog carries the difference.
162
- 2. **Drive the real surface, and on a rendered surface drive it visually FIRST.** The old order ran every cheap oracle before earning the right to look at the product; it inverted here because the defects that reach users on a rendered surface are the ones no simulated DOM can see. A slider thumb sitting on its own labels, a settings panel that grows the box someone types into: a suite of two hundred component tests is blind to both by construction, and the only oracle that caught them was judgement applied to real pixels.
162
+ **You maintain the checklist, not just its first draft.** Nothing else watches it: it owns no code and no `owns:` glob implicates it, so a surface can be rewritten under it and every hook stays silent. Before driving, reconcile the file against the surface you are about to drive:
163
+ - **Retire** sections whose behavior no longer exists — delete them; a checklist is a truth document and its history lives in git.
164
+ - **Add** sections for behavior shipped since the last run.
165
+ - **Repair every `Pinned:` trace** — a trace naming a test that no longer exists reports coverage that cannot fail, which is worse than no trace. A section you cannot pin says `none yet` and names the test it owes.
163
166
 
164
- **The browser is reached Chrome-CDP-first, Playwright second.** CDP drives the user's own browser interactively — it is the cheapest way to *look*, it needs no script written in advance, and looking is what discovery requires. Playwright is the fallback where CDP is unavailable (headless, CI, a runtime without it) and the tool of record for anything that must run unattended afterwards. Where the runtime offers neither, emit the browser-verification checklist for the user to run; their report is the rung's verdict and `Status: Complete` waits for it.
167
+ **Never soften an assertion to make the run green.** The checklist states what the feature promises, the run records what happened, and the backlog carries the difference — record the defect and send it to the backlog.
168
+ 2. **Drive the real surface — on a rendered surface, visually and FIRST.** The defects that reach users through an interface — a slider thumb sitting on its own labels, a settings panel that grows the box someone types into — are invisible to a simulated DOM by construction; only judgement applied to real pixels catches them.
169
+ - **Reach the browser Chrome-CDP-first, Playwright second.** CDP drives the user's own browser interactively and needs no script written in advance, which is what looking requires. Playwright is the fallback where CDP is unavailable (headless, CI, a runtime without it) and the tool of record for anything that must run unattended afterwards. Where the runtime offers neither, emit the browser-verification checklist for the user to run; their report is this step's verdict, and `Status: Complete` waits for it.
170
+ - **Judgement leads, scripts follow — never the reverse.** A *judged* drive — an agent or a person reading the actual rendering against the design's intent — **finds** geometry and taste defects; a *scripted* assertion only **guards** a contract someone already discovered. A generated script asserting "the slider sets the value" passes over a thumb covering its labels.
171
+ - **Run the cheap oracles in the same pass** — suites, the CLI binary, HTTP against the running app. They are what the drive's findings get pinned into (step 3), not a gate to pass before looking.
172
+ - On a surface with no rendering — a CLI, a service, a library — drive its own real binary or real wire; the visual clause does not apply.
173
+ 3. **Pin the durable behaviors — once, against the driven code** — as suite tests per `testing.md`, naming each test's stratum (§ Bridge).
174
+ - **On a rendered surface the pin is the surface's journey first**: the drive just performed *is* the journey, so write it down as the test against the seeded world. Reach for a component test only where § Placement discipline's condition (c) holds.
175
+ - **Write pins after the drive and the fixes, never beside the first attempt** — an earlier pin is rewritten on every iteration and proves only that its author and the code agree.
176
+ - **Write the pins inline, as the agent that drove** — only it knows what the drive found and what each pin must therefore assert; a sub-agent briefed from the ledger row reproduces the row, not the finding.
177
+ - **A pinned test must pass from a cold shell** — the canonical test command with no dev server hand-started and no seeded state beyond what the suite builds for itself; a server app is exercised in-process per `testing.md`'s stack table, **never** over a port. A test whose oracle is "fetch the server I happen to have running" is a driven check wearing a test's name, and goes red the moment the session ends.
178
+ - **A suite whose subject is no longer reachable from the product's entry points is deleted with the code path**, never repointed to keep it green.
179
+ - **A case that asserts nothing beyond "it did not throw" is not a pin** — give it an assertion on resulting state or delete it.
165
180
 
166
- **Judged and scripted are two different rungs and the difference is the point.** A *judged* drive — an agent or a person reading the actual rendering against the design's intent — is what **finds** geometry and taste defects; a *scripted* assertion only **guards** a contract someone already discovered. A generated script asserting "the slider sets the value" passes happily over a thumb covering its labels. So judgement leads and scripts follow it, never the reverse.
167
-
168
- Cheap oracles have not stopped mattering — they stopped being a gate you pass before looking. Suites, the CLI binary, and HTTP against the running worker run in the same pass and are what the drive's findings get **pinned into** (rung 3). On a surface with no rendering — a CLI, a service, a library — this rung is its own real binary or real wire, and the visual clause simply does not apply.
169
-
170
- **A failing checklist assertion is never softened to make a run green** — record the defect, send it to the backlog.
171
- 3. **Pin the durable behaviors — once, against the driven code** — as suite tests per `testing.md`, naming each test's stratum (§ Bridge). **On a rendered surface the pin is the surface's journey first**: the drive just performed *is* the journey, so write it down as the test against the seeded world, and reach for a component test only where § Placement discipline's third condition holds. Pins are written after the drive and the fixes, never beside the first attempt: a pin written earlier is rewritten on every iteration and proves only that its author and the code agree. **Pinning is written inline, by the agent that drove** — it alone knows what the drive found and what each pin must therefore assert; a sub-agent briefed from the ledger row reproduces the row, not the finding. **A pinned test must pass from a cold shell** — `pnpm test` with no dev server hand-started, no seeded state assumed beyond what the suite builds for itself. A test whose oracle is "fetch the server I happen to have running" is a driven check wearing a test's name: it goes red the moment the session ends (on Workers, `@cloudflare/vitest-pool-workers` is the self-contained harness; an Express app is driven via `supertest`, never a port). Before discharging, run the suite once from a clean shell — a suite that needs the session's environment discharges nothing. A test is a permanent maintenance cost, bought deliberately:
181
+ A test is a permanent maintenance cost, bought deliberately; a driven check is evidence that proves the change works today and leaves nothing behind:
172
182
 
173
183
  | Earns a suite test | Verified by driving alone |
174
184
  | --- | --- |
175
185
  | A promise an LLD makes about the feature's contract | Copy and spacing that no defect has ever turned on — restated by a test, not protected by one |
176
186
  | A bug that occurred once — its regression test | A one-off migration or backfill's output |
177
- | **A layout defect that shipped** — its geometry pin, at 7b, measured in a real engine | Layout a judged drive has looked at and found correct — looking is the proof, and a pin buys nothing until something breaks |
187
+ | **A layout defect that shipped** — its geometry pin, at 7b, measured in a real engine | Layout a judged drive has looked at and found correct — looking is the proof, and a pin buys nothing until something breaks |
178
188
  | An error path, race, or idempotency guarantee | Behavior a type or the compiler already makes unshippable |
179
189
  | A user-observable step of a surface — as an assertion in its journey | A same-branch table row: an `it.each` earns one row per branch or boundary, never one per literal |
190
+ 4. **Run the affected suite and the affected surface's journeys from a cold shell** before discharging — a suite that needs the session's environment discharges nothing. The e2e config builds, seeds and boots its own world, so "needs the world running" is never a reason a journey did not run.
191
+ 5. **Discharge every ledger row into exactly one outcome**: **satisfied** (test green, or driven check passed), **owes nothing** (with the reason — compiler-guarded, covered elsewhere), or **blocked** (missing infrastructure named, row converted to a backlog item).
192
+ - **Re-read the ledger from the plan file on disk, never from conversation memory** — a context-held copy is how rows get missed.
193
+ - **Write each row's outcome into its `Outcome` cell in the plan file** — exactly `satisfied`, `owes nothing — {reason}`, or `blocked → backlog`. The Stop wall and CI read that cell, and a row left unexamined blocks completion.
194
+ 6. **Report results honestly, including failures.** Record which test now guards each checklist section (`Pinned:` traces) and each section's `AC:` line where the repo carries a keyed acceptance-criteria source, closing with the coverage count — `AC coverage: {n}/{m}; uncovered: {keys} → backlog`.
180
195
 
181
- A driven check is evidence, not an artifact — it proves the change works today and leaves nothing behind; that is why this rung exists. Two hygiene rules hold at every pin: **a suite whose subject is no longer reachable from the product's entry points is deleted with the code path**, never repointed to keep it green; and **a case that asserts nothing beyond "it did not throw" is not a pin** — give it an assertion on resulting state or delete it.
182
- 4. **Run the affected suite and the affected surface's journeys from a cold shell** — the e2e config builds, seeds and boots its own world, so "needs the world running" is never a reason a journey did not run.
183
- 5. **Discharge every ledger row into exactly one outcome**: **satisfied** (test green, or driven check passed), **owes nothing** (with the reason — compiler-guarded, covered elsewhere), or **blocked** (missing infrastructure named, row converted to a backlog item). **Open by re-reading the ledger from the plan file on disk, never from conversation memory** — a context-held copy is how rows get missed. **Write each row's outcome into its `Outcome` cell in the plan file** — exactly `satisfied`, `owes nothing — {reason}`, or `blocked → backlog` — because the Stop wall and CI read that cell, and a row left unexamined blocks completion.
184
- 6. **Report results honestly, including failures**; record which test now guards each checklist section (`Pinned:` traces) and each section's `AC:` line where the repo carries a keyed acceptance-criteria source, closing with the coverage count — `AC coverage: {n}/{m}; uncovered: {keys} → backlog`.
185
-
186
- **Record every section you drove — in the changelog entry, not in the checklist.** One line per section: what was driven, PASS or FAIL, the environment, and the evidence the assertion turned on (the literal observed, the row version, the request body). It goes in the entry because it is a dated event, and the checklist is a truth document that carries no dates (the `documentation` skill § The three natures). **A `FAIL` is recorded as a `FAIL` and stays** — with the backlog item it raised — because a corpus of driven records that has never recorded a failure is either describing a flawless product or being written by someone who already knew the answer, and a reader cannot tell which. In the checklist itself, the section's `Pinned:` trace is what distinguishes a verified promise from a typed one; a section the drive could not reach says `not reachable — {what blocks it}` there, so an unexamined section and a guarded one never look alike.
196
+ **Record every section you drove in the changelog entry, not in the checklist** — one line per section: what was driven, PASS or FAIL, the environment, and the evidence the assertion turned on (the literal observed, the row version, the request body). A drive is a dated event and the checklist is a truth document that carries no dates (the `documentation` skill § The three natures). **A `FAIL` is recorded as a `FAIL` and stays**, with the backlog item it raised — a record of drives that never shows a failure cannot be told apart from one written by someone who already knew the answer. In the checklist itself, the `Pinned:` trace distinguishes a verified promise from a typed one; a section the drive could not reach says `not reachable — {what blocks it}` there, so an unexamined section and a guarded one never look alike.
187
197
 
188
- Completion steps — freezing the plan, the changelog entry — are the root policy file's, not yours.
198
+ Freezing the plan and finishing the changelog entry are the root policy file's Completion steps, not this skill's.