@nurix/etna 0.20.3 → 0.20.5

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.
@@ -9,10 +9,10 @@
9
9
  | Regime | During the work | Proven |
10
10
  | --- | --- | --- |
11
11
  | **Plan-driven build** | No new test files. Code only — the loop stays fast | At the verification gate, before `Status: Complete` |
12
- | **Bug fix** — a defect in shipped behavior | The regression test ships with the fix | Immediately — it fails before the change, passes after |
13
- | **Ad-hoc / non-plan change** | The test ships with the change **when it alters promised behavior** — layout, copy, and config tweaks owe none | Immediately, same discipline as a bug fix |
12
+ | **Bug fix** — a defect in shipped behavior | Fix it, drive it, then write its regression test — in the same unit of work | Before the unit ends — the pin is written once, against the fixed code |
13
+ | **Ad-hoc / non-plan change** | Make the change, drive it, then write its test **when it alters promised behavior** — layout, copy, and config tweaks owe none | Before the unit ends, same discipline as a bug fix |
14
14
 
15
- - **A bug fix cannot defer** — "fails before, passes after" is provable afterward only by reverting to the pre-fix ref, a cost nobody pays; capture the property at fix time or lose it.
15
+ - **A bug fix cannot defer past its own unit of work — but its pin comes after the fix is driven, never beside the first attempt.** A test written while the fix is still moving is rewritten on every iteration, and written by the fix's author beside the fix it proves only that the two agree. Write it once, against the fixed code; where the defect was subtle, run it once against the pre-fix code (stash the fix) so the pin is shown to bite — that is one command, not an iteration.
16
16
  - **Ad-hoc work cannot defer — there is no ledger to defer into.** A non-plan change that alters no promised behavior — a pure refactor, a rename — owes no test.
17
17
 
18
18
  ## During the loop
@@ -21,16 +21,18 @@ Rules for the plan regime between the plan gate and the verification gate:
21
21
 
22
22
  - **No new test files** — obligations wait in the plan's ledger (written at the plan gate by the `testing` skill).
23
23
  - **Existing tests broken by the plan's intended behavior change are updated to the new contract before any mid-plan commit** — the shared branch never carries a red suite, and an update is never a weakening (§ Discipline).
24
- - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it with its regression test now — deferring it to the gate loses "fails before" — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
24
+ - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it now and pin it at the build pass's pin step, with the unit's other pins — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
25
25
  - **The ledger is amendable while the plan is open** — the gate discharges whatever it holds at gate time.
26
26
  - **A mid-plan commit is a checkpoint, not a verification claim.**
27
27
 
28
28
  ## The gate
29
29
 
30
- **A discrete, user-triggered step.** When implementation is complete, report it and offer the gate — never run it unbidden, and never flip `Status: Complete` without it. An explicit user acceptance of finished plan work — "ship it", "commit", "looks good" — counts as the trigger; open the gate without asking again. A plan with outstanding obligations stays open, whatever the code does. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
30
+ **The tail of every build pass, never a separate ask.** When the unit's code is written the gate runs — drive the real surface, fix what driving finds, pin, discharge — and the session does not stop to ask whether it should. What the user decides is the freeze and the commit: "ship it", "commit", "looks good" close a plan whose gate has already run; they never open one. Never flip `Status: Complete` without the gate. A plan with outstanding obligations stays open, whatever the code does.
31
+
32
+ - **Inside the build pass the order is fixed — code → drive → fix → pin.** Tests written while the code is still moving are rewritten on every iteration, and written by the code's author beside the code they pass by construction; a judged drive is what finds the defects (below). Pinning is the last step and happens once, against code the drive has already shown to be right. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
31
33
 
32
34
  - **Precondition: the ledger exists.** A plan with no Test Obligations section is blocked at the gate — run the `testing` skill (plan-gate mode) on it first; an empty ledger passes vacuously and the gap surfaces only after the file is frozen.
33
- - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **Authoring test files is dispatched fan-out by default** — at any nesting level, sub-agents on the cheapest capable tier write the pins from the checklist and ledger rows while the gating agent keeps the checklist, the driving, the cold-shell suite run, and every discharge: a sub-agent's green claim is a report, and the verdict is the re-run. Only a lone regression test riding a bug fix stays inline — briefing a sub-agent costs more than the test.
35
+ - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **The pins are written inline, by the agent that drove the surface** — the drive is what tells it which behaviors earned a test and what each one must assert, and a sub-agent briefed from the ledger alone holds neither. Nothing in the gate is dispatched: the checklist, the driving, the pinning, the cold-shell suite run and every discharge stay with one agent, so the state of the gate is never somewhere nobody is looking.
34
36
  - **The gate needs no stronger tier than the session default** — a standard-tier session suffices whatever tier built the plan; the plan and its ledger carry all the state the gate needs, so gating in a fresh session loses nothing.
35
37
  - **On a rendered surface, browser driving LEADS the gate — it is not its final rung.** The order inverted deliberately: the defects that reach users through an interface are geometric and compositional, and a simulated DOM computes no layout, so a suite that is entirely green says nothing about whether anything is where it should be. **Reach the browser Chrome-CDP-first and Playwright second** — CDP drives a real browser interactively and needs no script written in advance, which is what discovery requires; Playwright is the fallback where CDP is unavailable and the tool of record for whatever must run unattended afterwards. Cheap oracles run in the same pass and are what the drive's findings get pinned into; they are no longer a gate to pass before looking. A surface with nothing rendered — a CLI, a service, a library — drives its own real binary or wire instead, and this clause does not apply.
36
38
  - **A judged drive discovers; a scripted assertion guards.** Only the first finds a defect nobody has seen — a script asserting a control's value passes over a control drawn on top of its own label. Scripts are written after a judged drive names the class of defect, never generated ahead of one, and **a red script is never regenerated** — regeneration re-derives the assertion from the surface as it currently is, which turns a defect into the asserted truth with everything green.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "d54acc9dc88e",
2
+ "fingerprint": "e8ec199f3a00",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -29,15 +29,17 @@ Three peer modes, then a verification gate and a Completion step — enter where
29
29
  | --- | --- | --- | --- |
30
30
  | **Brainstorming** | explicit ask (`/brainstorm start`); or offer a session — never auto-enter — when the user brings a large piece of work (name what makes it big) or an utterance contradicts a recorded pillar (name the principle) | `brainstorm` agent + skill | LLD, Plan, or close + harvest |
31
31
  | **LLD** (low-level design) | new feature work | `lld-mode` agent + `documentation` skill | Plan |
32
- | **Plan** | an LLD is approved | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md` | Verification gate → Completion |
32
+ | **Plan** | the user asks for the plan — the design is settled (an LLD, or a discussion that reached one) | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md`, **gated in the same pass** (§ Boundaries, § Test obligations) | Build pass → Completion |
33
33
 
34
34
  > Brainstorm entry needs a **basis** — a reference document or a one-shot brain dump; drip-sized asks (a bug fix, one button) are too small and get redirected. A **pillar** is a recorded strategic principle from a past brainstorm: in-progress sessions live under `docs/research/`, harvested ones under `docs/history/brainstorms/`, harvested doctrine under `docs/architecture/`. The LLD is the feature doc itself — `docs/features/{feature}.md`, design intent first, extended in place at Completion.
35
35
 
36
- > **The lightweight lane:** a change touching one module, **at most ~10 files, none on a contract-heavy surface** (db schema, wire envelopes, auth, events, env/config — the `boundary` skill's list), and under about **three days'** work skips the modes above entirely — the ad-hoc regime of `.claude/rules/testing.md` applies: make the change, pay its test immediately if it alters promised behavior, cover it with a changelog row. The predicate is mechanical; when in doubt, the `boundary` diff scan is the tiebreak, not self-assessment.
36
+ > **Two stops, and only two.** The work between them runs without asking. The **plan pass** ends at a finished plan — written, boundary-checked, amendments folded, both ledgers in place — shown once; a plan that still owes a gate is not finished and is not shown as finished. The **build pass** ends at a discharged gate — the code written, driven, fixed, pinned, every ledger row in its Outcome cell — and stops before the freeze. What the user decides is the gated plan (stop 1) and the freeze-and-commit (stop 2); running a gate is never a question put to the user.
37
+
38
+ > **The lightweight lane:** a change touching one module, **at most ~10 files, none on a contract-heavy surface** (db schema, wire envelopes, auth, events, env/config — the `boundary` skill's list), and under about **three days'** work skips the modes above entirely — the ad-hoc regime of `.claude/rules/testing.md` applies: make the change, drive it, then pin it in the same unit of work if it alters promised behavior, cover it with a changelog row. The predicate is mechanical; when in doubt, the `boundary` diff scan is the tiebreak, not self-assessment.
37
39
 
38
40
  **On Plan Completion:**
39
41
 
40
- 1. **The verification gate passes first** **[override]** — user-triggered: when implementation completes, report it and offer the gate; never run it unbidden. This deliberately inverts the runtime's finish-the-task default: completion is the user's call. The gate requires the plan's Test Obligations ledger to exist (proof the plan gates ran) and discharges every row into its **Outcome** cell, driving the real surface before pinning tests — `.claude/rules/testing.md`. A plan with outstanding obligations stays open, whatever the code does.
42
+ 1. **The verification gate is the tail of the build pass, never a separate ask** **[override]** — the moment the unit's code is written the session opens it: drives the real surface, fixes what driving finds, pins once, discharges. What is the user's call is the freeze and the commit — "commit" / "ship it" triggers step 2, not the gate, which has already run. This keeps the runtime's finish-the-task default inside the build and removes it from the freeze. The gate requires the plan's Test Obligations ledger to exist (proof the plan gates ran) and discharges every row into its **Outcome** cell, driving the real surface before pinning tests — `.claude/rules/testing.md`. A plan with outstanding obligations stays open, whatever the code does.
41
43
  2. **Discharge, then freeze — in one edit.** Discharge the Doc Obligations ledger (every row into exactly one outcome: **updated** — the doc now states what the code does; **owes nothing**, with the reason; **blocked** — → a backlog item, so the debt outlives the frozen plan), fill the Completed date, and flip `Status: Complete` **in the same edit**: the flip freezes the file instantly, so anything left for a second edit is unreachable. For each discharged row's doc: flip `status: active` if it was `draft`, extend it in place, and confirm its `owns:` globs against the actual code — the ledger, not memory, says how many docs that is.
42
44
  3. Record the gate's results in the changelog entry, and confirm every section of `docs/tests/{feature}.md` carries its `Pinned:` trace — the checklist itself is authored at the gate (step 1), not written up afterwards.
43
45
 
@@ -64,15 +66,15 @@ The `lld-mode` agent checks for ownership conflicts during LLD research — feat
64
66
 
65
67
  Boundaries are **diagnosed, not documented** — the `boundary` skill derives them fresh from source on every run (the definition and mechanism catalog live in the skill), so nothing is persisted that could go stale.
66
68
 
67
- **Invoke the `boundary` skill after a plan is approved and before its first implementation step.** It parses the plan's Proposed Changes, reads the touched source, traces the consumers on the other side, and reports severity-ranked violations with suggested amendments and a pass/block verdict — in chat, read-only except its one write: its own segment of the plan's **`Gates:`** line. That line is machine-read — the compliance hook blocks implementation edits inside the plan's scope while it reads `Boundary: pending` — so this gate is enforced, not ceremony. Fold the amendments into the plan before coding. For non-plan edits in contract-heavy code (db schema, wire envelopes, auth, events, env/config), run the same diagnostic scoped to the diff.
69
+ **Invoke the `boundary` skill while the plan is being written — a plan is not finished until it carries the verdict.** It parses the plan's Proposed Changes, reads the touched source, traces the consumers on the other side, and reports severity-ranked violations with suggested amendments and a pass/block verdict — in chat, read-only except its one write: its own segment of the plan's **`Gates:`** line. That line is machine-read — the compliance hook blocks implementation edits inside the plan's scope while it reads `Boundary: pending` — so this gate is enforced, not ceremony. The session folds the amendments into the plan in the same pass, then writes the segment to `passed`; the plan the user reads already carries it. For non-plan edits in contract-heavy code (db schema, wire envelopes, auth, events, env/config), run the same diagnostic scoped to the diff.
68
70
 
69
71
  ### Test obligations — specify before implementing
70
72
 
71
- **After `boundary` passes and its amendments are folded, invoke the `testing` skill (plan-gate mode)** — same plan gate, ordered second. It derives the tests the plan owes from its Proposed Changes and the owning LLD, and writes the **Test Obligations** ledger into the plan (one row per promised behavior: layer · target file · oracle · fixtures · an empty **Outcome** cell the verification gate fills). It writes no test files — the ledger is what the verification gate discharges, and because it lives in the plan file it survives dispatch to an executor that sees only the plan. On a boundary **BLOCK** it does not run — re-plan first. Layer rules and the e2e altitude gate live in the skill. **The Doc Obligations table is the author's, filled at the same gate** — a lookup against the ownership index, not a skill run; the hook blocks implementation edits while either section is missing.
73
+ **Then, still in the plan pass, invoke the `testing` skill (plan-gate mode)** — after `boundary`'s amendments are folded, ordered second. It derives the tests the plan owes from its Proposed Changes and the owning LLD, and writes the **Test Obligations** ledger into the plan (one row per promised behavior: layer · target file · oracle · fixtures · an empty **Outcome** cell the verification gate fills). It writes no test files — the ledger is what the verification gate discharges, and because it lives in the plan file it survives dispatch to an executor that sees only the plan. On a boundary **BLOCK** it does not run — re-plan first. Layer rules and the e2e altitude gate live in the skill. **The Doc Obligations table is the author's, filled in the same pass** — a lookup against the ownership index, not a skill run; the hook blocks implementation edits while either section is missing.
72
74
 
73
75
  ### Verification — prove before completing
74
76
 
75
- **Deferring tests is what keeps the build loop fast, and the ledger is what makes deferring safe.** Obligations accumulate in the plan and are discharged in one pass at the **verification gate** — mandatory before `Status: Complete`. The gate and the regimes are `.claude/rules/testing.md`; the procedure (checklist → drive → pin → discharge) is the `testing` skill (gate mode). The gate's verdict is never delegated (§ Delegation), and browser work is main-session-only where Runtime Notes say so.
77
+ **Deferring tests is what keeps the build loop fast, and the ledger is what makes deferring safe.** Obligations accumulate in the plan and are discharged in one pass at the **verification gate** — the tail of every build pass, mandatory before `Status: Complete`. Inside the build pass the order is fixed: **code → drive → fix → pin** — the pins are written once, against code a drive has already shown to be right. The gate and the regimes are `.claude/rules/testing.md`; the procedure (checklist → drive → pin → discharge) is the `testing` skill (gate mode). The gate's verdict is never delegated (§ Delegation), and browser work is main-session-only where Runtime Notes say so.
76
78
 
77
79
  ### Documentation — close the loop
78
80
 
@@ -124,7 +126,8 @@ The single policy for sub-agent dispatch — when to fan out, at what tier, and
124
126
  **[override]** — this section replaces any runtime default that withholds dispatch until it is asked for. A runtime instruction of the shape "do not use sub-agents unless the user requested it" is exactly the default meant here, and it loses: delegating the work named below is the STANDING instruction, and the user re-requesting it each time is not a precondition. THE MARKER IS WHAT MAKES THAT TRUE — without it this section is merely a project preference meeting a runtime rule, and the runtime rule wins silently. Observed: a session that read its own source files inline, then authored its test bodies inline, while both this section and `.claude/rules/testing.md` said to dispatch — nothing in the repo claimed precedence, so nothing was violated.
125
127
 
126
128
  - **Delegate to keep bulk out of the main context.** Wide file reads, sweeps, broad research, audits, fixture prep — work whose raw tool output the main session doesn't need — defaults to a sub-agent: output a sub-agent reads dies with it, while output read inline is re-read and re-billed on every later turn. The hand-off is self-contained (the sub-agent sees none of the conversation), so it must still cost less than the work; run independent delegations in parallel.
127
- - **The policy binds every agent, not only the main session.** A sub-agent doing build work inherits these defaults with the dispatch capability to honor them (Runtime Notes): it dispatches its own sub-agents for work this policy routes off-thread — the bookkeeping drain, gate-mode test authoring — instead of absorbing it into its own loop. What never delegates (a gate verdict, browser driving) never delegates at any level.
129
+ - **The policy binds every agent, not only the main session.** A sub-agent doing build work inherits these defaults with the dispatch capability to honor them (Runtime Notes): it dispatches its own sub-agents for work this policy routes off-thread — the bookkeeping drain, a wide read — instead of absorbing it into its own loop. What never delegates (a gate verdict, browser driving, the pins the drive earned) never delegates at any level.
130
+ - **A dispatch is scoped to minutes and read before anything else starts.** One file, one sweep — never a build. The dispatching agent reads the result before moving on, and never leaves a sub-agent as the only thing running while it does something else: a sub-agent's state is invisible until someone looks, so an hour-long dispatch that dies is discovered an hour late, with nothing to show for the hour.
128
131
  - **Small or judgment work stays inline.** A task finishable in a handful of tool calls is faster done than briefed. **Never delegate judgment by reflex** — a second opinion is for a high-stakes call or an explicit request.
129
132
  - **A delegated result is a report, not verifiable ground truth** — verify load-bearing results directly.
130
133
  - **Tiers**: mechanical fan-out → the cheapest capable tier; judgment-heavy delegation → the session's standard tier; the strongest tier **only** on explicit user request. The session itself defaults to the standard tier, entering the strongest only by explicit user switch. Model names live in Runtime Notes.
@@ -136,7 +139,7 @@ The single policy for sub-agent dispatch — when to fan out, at what tier, and
136
139
 
137
140
  Defaults — ❌ prohibitions hold unless the user explicitly asks otherwise; ✅ and ⚠️ items are standing policy:
138
141
 
139
- - ✅ **Verification** — batched at the gate, never continuous; the regimes and the gate are `.claude/rules/testing.md`, the procedure the `testing` skill (gate mode).
142
+ - ✅ **Verification** — batched at the gate, never continuous, and the gate is the build's last step, never a separate ask; the regimes and the gate are `.claude/rules/testing.md`, the procedure the `testing` skill (gate mode).
140
143
  - ❌ **Dependencies** – Never upgrade pinned packages without asking; security patches and test-tooling installs at `latest` (`testing.md`) are exempt.
141
144
  - ❌ **Compatibility** – Never maintain backward compatibility unless specified.
142
145
  - ❌ **Branches & Worktrees [override]** – Never self-create git branches or worktrees; commit straight to the checked-out branch. This replaces any built-in "branch first on the default branch" default. Exception: when the user asks for a pull request, create the branch the PR requires before committing its changes.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.13.1",
4
+ "version": "3.14.1",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -25,5 +25,5 @@
25
25
  }
26
26
  ],
27
27
  "docsRoot": "docs",
28
- "digest": "af8ccf4c5383"
28
+ "digest": "b3304fa7a078"
29
29
  }
@@ -465,7 +465,7 @@ function stopGate(projectDir, payload) {
465
465
  (counts.expiredWaived > 0
466
466
  ? "An expired waiver is a deferral that ran out — re-judge whether its reason still holds rather than re-waiving by default. "
467
467
  : "") +
468
- "If implementation of the open plan is complete, also report it and offer the verification gate — never run it unbidden.",
468
+ "If the open plan's code is written, its gate is the build's tail — drive, fix, pin, discharge before stopping; the freeze and the commit are the user's.",
469
469
  };
470
470
  }
471
471
 
@@ -9,10 +9,10 @@
9
9
  | Regime | During the work | Proven |
10
10
  | --- | --- | --- |
11
11
  | **Plan-driven build** | No new test files. Code only — the loop stays fast | At the verification gate, before `Status: Complete` |
12
- | **Bug fix** — a defect in shipped behavior | The regression test ships with the fix | Immediately — it fails before the change, passes after |
13
- | **Ad-hoc / non-plan change** | The test ships with the change **when it alters promised behavior** — layout, copy, and config tweaks owe none | Immediately, same discipline as a bug fix |
12
+ | **Bug fix** — a defect in shipped behavior | Fix it, drive it, then write its regression test — in the same unit of work | Before the unit ends — the pin is written once, against the fixed code |
13
+ | **Ad-hoc / non-plan change** | Make the change, drive it, then write its test **when it alters promised behavior** — layout, copy, and config tweaks owe none | Before the unit ends, same discipline as a bug fix |
14
14
 
15
- - **A bug fix cannot defer** — "fails before, passes after" is provable afterward only by reverting to the pre-fix ref, a cost nobody pays; capture the property at fix time or lose it.
15
+ - **A bug fix cannot defer past its own unit of work — but its pin comes after the fix is driven, never beside the first attempt.** A test written while the fix is still moving is rewritten on every iteration, and written by the fix's author beside the fix it proves only that the two agree. Write it once, against the fixed code; where the defect was subtle, run it once against the pre-fix code (stash the fix) so the pin is shown to bite — that is one command, not an iteration.
16
16
  - **Ad-hoc work cannot defer — there is no ledger to defer into.** A non-plan change that alters no promised behavior — a pure refactor, a rename — owes no test.
17
17
 
18
18
  ## During the loop
@@ -21,16 +21,18 @@ Rules for the plan regime between the plan gate and the verification gate:
21
21
 
22
22
  - **No new test files** — obligations wait in the plan's ledger (written at the plan gate by the `testing` skill).
23
23
  - **Existing tests broken by the plan's intended behavior change are updated to the new contract before any mid-plan commit** — the shared branch never carries a red suite, and an update is never a weakening (§ Discipline).
24
- - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it with its regression test now — deferring it to the gate loses "fails before" — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
24
+ - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it now and pin it at the build pass's pin step, with the unit's other pins — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
25
25
  - **The ledger is amendable while the plan is open** — the gate discharges whatever it holds at gate time.
26
26
  - **A mid-plan commit is a checkpoint, not a verification claim.**
27
27
 
28
28
  ## The gate
29
29
 
30
- **A discrete, user-triggered step.** When implementation is complete, report it and offer the gate — never run it unbidden, and never flip `Status: Complete` without it. An explicit user acceptance of finished plan work — "ship it", "commit", "looks good" — counts as the trigger; open the gate without asking again. A plan with outstanding obligations stays open, whatever the code does. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
30
+ **The tail of every build pass, never a separate ask.** When the unit's code is written the gate runs — drive the real surface, fix what driving finds, pin, discharge — and the session does not stop to ask whether it should. What the user decides is the freeze and the commit: "ship it", "commit", "looks good" close a plan whose gate has already run; they never open one. Never flip `Status: Complete` without the gate. A plan with outstanding obligations stays open, whatever the code does.
31
+
32
+ - **Inside the build pass the order is fixed — code → drive → fix → pin.** Tests written while the code is still moving are rewritten on every iteration, and written by the code's author beside the code they pass by construction; a judged drive is what finds the defects (below). Pinning is the last step and happens once, against code the drive has already shown to be right. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
31
33
 
32
34
  - **Precondition: the ledger exists.** A plan with no Test Obligations section is blocked at the gate — run the `testing` skill (plan-gate mode) on it first; an empty ledger passes vacuously and the gap surfaces only after the file is frozen.
33
- - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **Authoring test files is dispatched fan-out by default** — at any nesting level, sub-agents on the cheapest capable tier write the pins from the checklist and ledger rows while the gating agent keeps the checklist, the driving, the cold-shell suite run, and every discharge: a sub-agent's green claim is a report, and the verdict is the re-run. Only a lone regression test riding a bug fix stays inline — briefing a sub-agent costs more than the test.
35
+ - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **The pins are written inline, by the agent that drove the surface** — the drive is what tells it which behaviors earned a test and what each one must assert, and a sub-agent briefed from the ledger alone holds neither. Nothing in the gate is dispatched: the checklist, the driving, the pinning, the cold-shell suite run and every discharge stay with one agent, so the state of the gate is never somewhere nobody is looking.
34
36
  - **The gate needs no stronger tier than the session default** — a standard-tier session suffices whatever tier built the plan; the plan and its ledger carry all the state the gate needs, so gating in a fresh session loses nothing.
35
37
  - **On a rendered surface, browser driving LEADS the gate — it is not its final rung.** The order inverted deliberately: the defects that reach users through an interface are geometric and compositional, and a simulated DOM computes no layout, so a suite that is entirely green says nothing about whether anything is where it should be. **Reach the browser Chrome-CDP-first and Playwright second** — CDP drives a real browser interactively and needs no script written in advance, which is what discovery requires; Playwright is the fallback where CDP is unavailable and the tool of record for whatever must run unattended afterwards. Cheap oracles run in the same pass and are what the drive's findings get pinned into; they are no longer a gate to pass before looking. A surface with nothing rendered — a CLI, a service, a library — drives its own real binary or wire instead, and this clause does not apply.
36
38
  - **A judged drive discovers; a scripted assertion guards.** Only the first finds a defect nobody has seen — a script asserting a control's value passes over a control drawn on top of its own label. Scripts are written after a judged drive names the class of defect, never generated ahead of one, and **a red script is never regenerated** — regeneration re-derives the assertion from the surface as it currently is, which turns a defect into the asserted truth with everything green.
@@ -63,13 +63,13 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
63
63
 
64
64
  **The doc cross-check is free and you are the only one who can make it.** You already hold the touch list; resolving those paths against the ownership index and comparing the result to the plan's **Doc Obligations** rows costs one lookup. The plan's author wrote that ledger, so it is the one gate artifact nobody independently checked — a `None` that contradicts your touch list is the failure this section exists to catch. Report the gap; never edit the ledger yourself.
65
65
 
66
- **BLOCK** = any CRITICAL. HIGH findings yield **PASS WITH AMENDMENTS** — fold the amendments into the plan before coding. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the entry's safe-change sequence.
66
+ **BLOCK** = any CRITICAL. HIGH findings yield **PASS WITH AMENDMENTS** — the invoking session folds the amendments into the plan in the same pass, before the plan is shown as finished. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the entry's safe-change sequence.
67
67
 
68
68
  6. **Record the verdict in the plan's `Gates:` line.** Rewrite only your own segment, to exactly `Boundary: passed YYYY-MM-DD` (PASS, or PASS WITH AMENDMENTS once the amendments are folded) or `Boundary: blocked YYYY-MM-DD` (BLOCK). The compliance hook greps exactly this segment — implementation edits inside the plan's scope stay blocked while it reads `Boundary: pending` (the other gates are enforced by section presence, not segment text). A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
69
69
 
70
70
  ## Rules
71
71
 
72
- - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the user folds your amendments into the plan. The single write you own is the plan's `Gates:` line (step 6), your segment only.
72
+ - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the invoking session folds your amendments into the plan in the same pass, then writes the segment to `passed`; a plan is not finished until it does. The single write you own is the plan's `Gates:` line (step 6), your segment only.
73
73
  - **Verify in source.** Never flag from plan text alone — read both sides of every finding and cite them: code as `file:line`, doctrine as the doc path.
74
74
  - **No other side, no violation.** An intersection with no traced consumer and no doctrine behind it isn't a violation — it's a **new edge**: report it in its own section with the hardening its mechanism prescribes (version the cache key now, make the enum append-only now), so the fragile edge is born safe.
75
75
  - **A clean report is valid.** Zero violations means say so — the coverage table is the evidence it was checked, not skipped. Don't pad findings.
@@ -1,6 +1,6 @@
1
1
  # Plan (docs/history/plans/YYYY-MM-DD-feature-name.md)
2
2
 
3
- Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; after approval the plan gates (`boundary`, then `testing` plan-gate mode) run against the still-`Draft` file, the status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
3
+ Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; the plan gates (`boundary`, then `testing` plan-gate mode) run in the same pass that writes the plan, against the still-`Draft` file — a plan is not finished, and is not shown as finished, until its `Gates:` line carries every verdict, so what the user approves is the gated plan. The status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
4
4
 
5
5
  The `boundary` skill parses the **Proposed Changes** sections to check boundary impact before execution, and the `testing` skill (plan-gate mode) writes a **Test Obligations** section into the plan at the same gate. Keep that structure stable — section headings and bullet shape are load-bearing for the parsers, and the Test Obligations table is the ledger the verification gate discharges before the plan may reach `Status: Complete`.
6
6
 
@@ -9,15 +9,15 @@ One skill owns the test lifecycle's three procedural moments; the standing const
9
9
 
10
10
  | Moment | Mode |
11
11
  | --- | --- |
12
- | Plan gate, after `boundary` passes | **Plan-gate** — derive what the plan owes |
12
+ | The plan pass, after `boundary`'s amendments are folded | **Plan-gate** — derive what the plan owes |
13
13
  | A strategy / placement / altitude question, or laying out a suite | **Placement** — derive the strata, place the tests |
14
- | The user triggers the verification gate | **Gate** — drive, pin, discharge |
14
+ | The build pass reaches its tail — the unit's code is written | **Gate** — drive, fix, pin, discharge |
15
15
 
16
16
  ---
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 — at the same gate `boundary` runs, ordered second. 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 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.
21
21
 
22
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.
23
23
 
@@ -154,7 +154,7 @@ When writing or discharging a ledger row, name the stratum, not just the altitud
154
154
 
155
155
  ## Gate mode — discharge the ledger
156
156
 
157
- Runs only when the user triggers the verification gate (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.
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
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.
160
160
 
@@ -168,7 +168,7 @@ Runs only when the user triggers the verification gate (constraints — precondi
168
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
169
 
170
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** as suite tests per `testing.md`, naming each test's stratum (§ Bridge). **Pinning is dispatched, not written in your own loop** — batch the rows (per stratum or per target file) to sub-agents on the cheapest capable tier, each briefed with the ledger row, the checklist section, the target file, and the stratum; run the returned tests yourself — the cold-shell run below is the verdict, never the sub-agent's report. No dispatch mechanism ⇒ write them inline. **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:
171
+ 3. **Pin the durable behaviors — once, against the driven code** — as suite tests per `testing.md`, naming each test's stratum (§ Bridge). 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:
172
172
 
173
173
  | Earns a suite test | Verified by driving alone |
174
174
  | --- | --- |
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "delivery",
3
3
  "name": "delivery",
4
- "version": "0.2.22",
4
+ "version": "0.2.23",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -10,5 +10,5 @@
10
10
  "seeds": [],
11
11
  "tools": [],
12
12
  "docsRoot": "docs",
13
- "digest": "784354742e46"
13
+ "digest": "530448328369"
14
14
  }
@@ -1,6 +1,6 @@
1
1
  # Plan (docs/history/plans/YYYY-MM-DD-feature-name.md)
2
2
 
3
- Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; after approval the plan gates (`boundary`, then `testing` plan-gate mode) run against the still-`Draft` file, the status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
3
+ Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; the plan gates (`boundary`, then `testing` plan-gate mode) run in the same pass that writes the plan, against the still-`Draft` file — a plan is not finished, and is not shown as finished, until its `Gates:` line carries every verdict, so what the user approves is the gated plan. The status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
4
4
 
5
5
  The `boundary` skill parses the **Proposed Changes** sections to check boundary impact before execution, and the `testing` skill (plan-gate mode) writes a **Test Obligations** section into the plan at the same gate. Keep that structure stable — section headings and bullet shape are load-bearing for the parsers, and the Test Obligations table is the ledger the verification gate discharges before the plan may reach `Status: Complete`.
6
6
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "discover",
3
3
  "name": "discover",
4
- "version": "0.1.16",
4
+ "version": "0.1.17",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -10,5 +10,5 @@
10
10
  "seeds": [],
11
11
  "tools": [],
12
12
  "docsRoot": "docs",
13
- "digest": "0bf7a6a6f479"
13
+ "digest": "15abe8b51cd9"
14
14
  }
@@ -292,6 +292,50 @@ the elements needing redaction change as you navigate.
292
292
  > redaction was real; the *frame* was never examined. **Never write a zero-PII assertion you did not verify
293
293
  > by looking at the image** — and prefer "redacted: <what>" over a blanket claim.)
294
294
 
295
+ ### 5.6 Reconstructing an ALGORITHM — differential testing, in separated layers
296
+
297
+ §5.4 says what a *catalog* capture must dump. This is the extra bar for the harder case: a dimension
298
+ that reconstructs **behaviour** — a scoring formula, a ranking function, a pricing calculation, a
299
+ matcher, a state machine. A word list can be checked by reading it. An algorithm cannot: it is only
300
+ `complete` once it has been **run against the live product on inputs chosen to break it**.
301
+
302
+ **The rule.** A reconstructed algorithm is `partial` until:
303
+
304
+ 1. It is **executable** and committed to the corpus, not merely described in prose.
305
+ 2. It has been **differentially tested against the live product** on a real corpus plus deliberately
306
+ adversarial inputs — not only on the examples it was derived from.
307
+ 3. The test **separates the estimator from the feature extraction**, and the per-layer pass rates are
308
+ recorded separately. One aggregate number is not enough.
309
+ 4. The inputs and the product's own observed outputs are frozen in `raw/` (or beside the
310
+ implementation) as **re-runnable fixtures**, so a later run can repeat the comparison.
311
+
312
+ **Why the layer split is the load-bearing part.** Almost every reconstruction has two independent
313
+ places to be wrong — the *computation* and the *inputs fed to it*. Tested together they are
314
+ indistinguishable, and the aggregate score points at whichever one you already suspect:
315
+
316
+ - **Layer A — the estimator.** Feed the algorithm **the product's own reported feature values** and
317
+ check it reproduces the product's own output. This tests the mathematics alone.
318
+ - **Layer B — the feature extraction.** Compare **your** computed features against the product's
319
+ reported features. This tests tokenisation / parsing / counting alone.
320
+ - **Layer C — end-to-end.** Both together. C failing while A passes localises the fault to B in one
321
+ step, with no re-derivation of a formula that was already right.
322
+
323
+ **A residual that survives a correct layer B is a finding about the TARGET, not an error in the
324
+ reconstruction** — and it is often the most valuable thing the dimension produces. Chase it; do not
325
+ tune it away. And when the target's behaviour is a defect, **do not silently replicate it** to make
326
+ the numbers match: implement the correct behaviour by default and put bug-parity behind an explicit,
327
+ documented flag. A reconstruction that quietly reproduces a bug teaches the next reader the bug.
328
+
329
+ > (Origin: hemingway — the run shipped a "validated" reference implementation of the app's readability
330
+ > scorer whose **formula was exactly right** and whose **tokenizer agreed with the target on only 41 of
331
+ > 62 real inputs**. A single end-to-end comparison read as *"the model is wrong"* and would have sent
332
+ > the run back to re-derive a correct formula. Splitting the test localised it immediately: layer A was
333
+ > **62/62** from the first run, and `Δletters = 0` in 20 of the 21 layer-B divergences pinned the fault
334
+ > to word/sentence segmentation, which was then reverse-engineered to **61/62**. The one residual that
335
+ > survived a correct tokenizer was **a defect in the product** — a literal `...` silently deletes the
336
+ > preceding text from every statistic — which no static lane could have found and which only appeared
337
+ > because adversarial inputs were included.)
338
+
295
339
  ---
296
340
 
297
341
  ## 6. The shared-surface seam rule (bundle ↔ session ↔ wire-capture)
@@ -509,6 +553,11 @@ Downloading a public binary (CRX/`.asar`/`.ipa`/`.apk`) and reading its manifest
509
553
 
510
554
  A capture is complete when: `_summary.md` exists with full provenance frontmatter + honest `status`; **every Finding is backed by a `raw/` artifact — an inline value is NOT sufficient (§5.3)**; the dimension's **§5.4 dump manifest is satisfied verbatim**; `raw/` artifacts carry `_meta` (with `verbatim:` and, if bounded, `sampling:`); redaction pass run; `gaps` recorded (never fabricated).
511
555
 
556
+ > **Algorithm reconstructions have an extra bar (§5.6):** if the dimension reconstructed *behaviour*
557
+ > rather than a catalog, it is `partial` until the implementation is executable, differentially tested
558
+ > against the live product with the **estimator and feature extraction scored as separate layers**, and
559
+ > the inputs + observed outputs are frozen as re-runnable fixtures. Record the per-layer pass rates.
560
+
512
561
  > **Self-check before writing `status: complete`:** count the verbatim artifacts in `raw/`. If that count is **zero**, the dimension is `partial` no matter how good the prose is — you have written an essay, not a capture. If a Finding names a number, a path, a version, or a field, open the file that contains it; if no such file exists, write it now (§5.3).
513
562
 
514
563
  **Summary-first + bounded, visible fan-out (never go silent long enough to look dead).** Write a `status: partial` `_summary.md` with whatever is mined so far **before** any long-tail fetch loop (downloading many chunks, crawling many pages, deep pagination), then enrich it in place and flip to `complete`. **Bound** every fan-out — cap it by count / total bytes / wall-time (e.g. ≤40 items or ≤90 s) and record the remainder as a `gap` rather than fetching exhaustively; emit a progress note per batch. A collector that fetches everything before writing anything can run many times longer than its siblings and read as hung to the orchestrator, forcing a needless salvage. Partial-but-finalized beats complete-but-silent.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "etna",
3
3
  "name": "etna",
4
- "version": "1.5.11",
4
+ "version": "1.5.12",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -10,5 +10,5 @@
10
10
  "seeds": [],
11
11
  "tools": [],
12
12
  "docsRoot": "docs",
13
- "digest": "227d2ebbe014"
13
+ "digest": "b9aaab03fa33"
14
14
  }
@@ -9,10 +9,10 @@
9
9
  | Regime | During the work | Proven |
10
10
  | --- | --- | --- |
11
11
  | **Plan-driven build** | No new test files. Code only — the loop stays fast | At the verification gate, before `Status: Complete` |
12
- | **Bug fix** — a defect in shipped behavior | The regression test ships with the fix | Immediately — it fails before the change, passes after |
13
- | **Ad-hoc / non-plan change** | The test ships with the change **when it alters promised behavior** — layout, copy, and config tweaks owe none | Immediately, same discipline as a bug fix |
12
+ | **Bug fix** — a defect in shipped behavior | Fix it, drive it, then write its regression test — in the same unit of work | Before the unit ends — the pin is written once, against the fixed code |
13
+ | **Ad-hoc / non-plan change** | Make the change, drive it, then write its test **when it alters promised behavior** — layout, copy, and config tweaks owe none | Before the unit ends, same discipline as a bug fix |
14
14
 
15
- - **A bug fix cannot defer** — "fails before, passes after" is provable afterward only by reverting to the pre-fix ref, a cost nobody pays; capture the property at fix time or lose it.
15
+ - **A bug fix cannot defer past its own unit of work — but its pin comes after the fix is driven, never beside the first attempt.** A test written while the fix is still moving is rewritten on every iteration, and written by the fix's author beside the fix it proves only that the two agree. Write it once, against the fixed code; where the defect was subtle, run it once against the pre-fix code (stash the fix) so the pin is shown to bite — that is one command, not an iteration.
16
16
  - **Ad-hoc work cannot defer — there is no ledger to defer into.** A non-plan change that alters no promised behavior — a pure refactor, a rename — owes no test.
17
17
 
18
18
  ## During the loop
@@ -21,16 +21,18 @@ Rules for the plan regime between the plan gate and the verification gate:
21
21
 
22
22
  - **No new test files** — obligations wait in the plan's ledger (written at the plan gate by the `testing` skill).
23
23
  - **Existing tests broken by the plan's intended behavior change are updated to the new contract before any mid-plan commit** — the shared branch never carries a red suite, and an update is never a weakening (§ Discipline).
24
- - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it with its regression test now — deferring it to the gate loses "fails before" — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
24
+ - **A defect in the plan's own in-flux code is the loop iterating** — no test, no ledger row. **A pre-existing bug in shipped behavior is the bug-fix regime even mid-plan**: fix it now and pin it at the build pass's pin step, with the unit's other pins — or send it to the backlog via Out-of-Scope Discovery. Never fix silently.
25
25
  - **The ledger is amendable while the plan is open** — the gate discharges whatever it holds at gate time.
26
26
  - **A mid-plan commit is a checkpoint, not a verification claim.**
27
27
 
28
28
  ## The gate
29
29
 
30
- **A discrete, user-triggered step.** When implementation is complete, report it and offer the gate — never run it unbidden, and never flip `Status: Complete` without it. An explicit user acceptance of finished plan work — "ship it", "commit", "looks good" — counts as the trigger; open the gate without asking again. A plan with outstanding obligations stays open, whatever the code does. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
30
+ **The tail of every build pass, never a separate ask.** When the unit's code is written the gate runs — drive the real surface, fix what driving finds, pin, discharge — and the session does not stop to ask whether it should. What the user decides is the freeze and the commit: "ship it", "commit", "looks good" close a plan whose gate has already run; they never open one. Never flip `Status: Complete` without the gate. A plan with outstanding obligations stays open, whatever the code does.
31
+
32
+ - **Inside the build pass the order is fixed — code → drive → fix → pin.** Tests written while the code is still moving are rewritten on every iteration, and written by the code's author beside the code they pass by construction; a judged drive is what finds the defects (below). Pinning is the last step and happens once, against code the drive has already shown to be right. The procedure — checklist, drive-then-pin ladder, row discharge, what earns a durable test — is the `testing` skill (gate mode).
31
33
 
32
34
  - **Precondition: the ledger exists.** A plan with no Test Obligations section is blocked at the gate — run the `testing` skill (plan-gate mode) on it first; an empty ledger passes vacuously and the gap surfaces only after the file is frozen.
33
- - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **Authoring test files is dispatched fan-out by default** — at any nesting level, sub-agents on the cheapest capable tier write the pins from the checklist and ledger rows while the gating agent keeps the checklist, the driving, the cold-shell suite run, and every discharge: a sub-agent's green claim is a report, and the verdict is the re-run. Only a lone regression test riding a bug fix stays inline — briefing a sub-agent costs more than the test.
35
+ - **The verdict is never delegated** (the root policy file § Delegation), and where browser work is main-session-only (its § Runtime Notes), the driving is too. **The pins are written inline, by the agent that drove the surface** — the drive is what tells it which behaviors earned a test and what each one must assert, and a sub-agent briefed from the ledger alone holds neither. Nothing in the gate is dispatched: the checklist, the driving, the pinning, the cold-shell suite run and every discharge stay with one agent, so the state of the gate is never somewhere nobody is looking.
34
36
  - **The gate needs no stronger tier than the session default** — a standard-tier session suffices whatever tier built the plan; the plan and its ledger carry all the state the gate needs, so gating in a fresh session loses nothing.
35
37
  - **On a rendered surface, browser driving LEADS the gate — it is not its final rung.** The order inverted deliberately: the defects that reach users through an interface are geometric and compositional, and a simulated DOM computes no layout, so a suite that is entirely green says nothing about whether anything is where it should be. **Reach the browser Chrome-CDP-first and Playwright second** — CDP drives a real browser interactively and needs no script written in advance, which is what discovery requires; Playwright is the fallback where CDP is unavailable and the tool of record for whatever must run unattended afterwards. Cheap oracles run in the same pass and are what the drive's findings get pinned into; they are no longer a gate to pass before looking. A surface with nothing rendered — a CLI, a service, a library — drives its own real binary or wire instead, and this clause does not apply.
36
38
  - **A judged drive discovers; a scripted assertion guards.** Only the first finds a defect nobody has seen — a script asserting a control's value passes over a control drawn on top of its own label. Scripts are written after a judged drive names the class of defect, never generated ahead of one, and **a red script is never regenerated** — regeneration re-derives the assertion from the surface as it currently is, which turns a defect into the asserted truth with everything green.
@@ -63,13 +63,13 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
63
63
 
64
64
  **The doc cross-check is free and you are the only one who can make it.** You already hold the touch list; resolving those paths against the ownership index and comparing the result to the plan's **Doc Obligations** rows costs one lookup. The plan's author wrote that ledger, so it is the one gate artifact nobody independently checked — a `None` that contradicts your touch list is the failure this section exists to catch. Report the gap; never edit the ledger yourself.
65
65
 
66
- **BLOCK** = any CRITICAL. HIGH findings yield **PASS WITH AMENDMENTS** — fold the amendments into the plan before coding. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the entry's safe-change sequence.
66
+ **BLOCK** = any CRITICAL. HIGH findings yield **PASS WITH AMENDMENTS** — the invoking session folds the amendments into the plan in the same pass, before the plan is shown as finished. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the entry's safe-change sequence.
67
67
 
68
68
  6. **Record the verdict in the plan's `Gates:` line.** Rewrite only your own segment, to exactly `Boundary: passed YYYY-MM-DD` (PASS, or PASS WITH AMENDMENTS once the amendments are folded) or `Boundary: blocked YYYY-MM-DD` (BLOCK). The compliance hook greps exactly this segment — implementation edits inside the plan's scope stay blocked while it reads `Boundary: pending` (the other gates are enforced by section presence, not segment text). A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
69
69
 
70
70
  ## Rules
71
71
 
72
- - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the user folds your amendments into the plan. The single write you own is the plan's `Gates:` line (step 6), your segment only.
72
+ - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the invoking session folds your amendments into the plan in the same pass, then writes the segment to `passed`; a plan is not finished until it does. The single write you own is the plan's `Gates:` line (step 6), your segment only.
73
73
  - **Verify in source.** Never flag from plan text alone — read both sides of every finding and cite them: code as `file:line`, doctrine as the doc path.
74
74
  - **No other side, no violation.** An intersection with no traced consumer and no doctrine behind it isn't a violation — it's a **new edge**: report it in its own section with the hardening its mechanism prescribes (version the cache key now, make the enum append-only now), so the fragile edge is born safe.
75
75
  - **A clean report is valid.** Zero violations means say so — the coverage table is the evidence it was checked, not skipped. Don't pad findings.
@@ -1,6 +1,6 @@
1
1
  # Plan (docs/history/plans/YYYY-MM-DD-feature-name.md)
2
2
 
3
- Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; after approval the plan gates (`boundary`, then `testing` plan-gate mode) run against the still-`Draft` file, the status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
3
+ Record. Use for: every implementation plan. Plans are created here directly with `Status: Draft`; the plan gates (`boundary`, then `testing` plan-gate mode) run in the same pass that writes the plan, against the still-`Draft` file — a plan is not finished, and is not shown as finished, until its `Gates:` line carries every verdict, so what the user approves is the gated plan. The status flips to `Status: In Progress` at the first implementation step, and the file freezes at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes. The plan records the journey; the truth it implemented lives on in the feature doc and any AD it touched.
4
4
 
5
5
  The `boundary` skill parses the **Proposed Changes** sections to check boundary impact before execution, and the `testing` skill (plan-gate mode) writes a **Test Obligations** section into the plan at the same gate. Keep that structure stable — section headings and bullet shape are load-bearing for the parsers, and the Test Obligations table is the ledger the verification gate discharges before the plan may reach `Status: Complete`.
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.20.3",
3
+ "version": "0.20.5",
4
4
  "description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,5 +42,5 @@
42
42
  "agent",
43
43
  "plugin"
44
44
  ],
45
- "etnaFingerprint": "d54acc9dc88e"
45
+ "etnaFingerprint": "e8ec199f3a00"
46
46
  }