@nurix/etna 0.19.38 → 0.19.39

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "088c311840d2",
2
+ "fingerprint": "a4419d09d415",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -36,7 +36,7 @@ Three peer modes, then a verification gate and a Completion step — enter where
36
36
  1. **The verification gate passes first** — user-triggered: when implementation completes, report it and offer the gate; never run it unbidden. It requires the plan's Test Obligations ledger to exist (proof the plan gates ran) and discharges every row, driving the real surface before pinning tests — `.claude/rules/verification.md`. A plan with outstanding obligations stays open, whatever the code does.
37
37
  2. Freeze the plan — `Status: Complete`, fill the Completed date. The file is now frozen.
38
38
  3. Flip the feature LLD to `status: active`; extend it in place with the how-it-works sections; confirm its `owns:` globs against the actual code.
39
- 4. Derive/update the behavioral checklist at `docs/tests/{feature}.md` via the `documentation` skill (a truth document — present-tense, referencing the LLD's promises, restating no intent), and record the gate's results in the changelog entry.
39
+ 4. 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.
40
40
 
41
41
  **On Brainstorm Close** (when a session ends, not when a plan completes): close + harvest is the skill's `stop` procedure — converge, a user-approved harvest manifest, apply, then a uselessness test; conclusions disperse by scope (architecture docs, decision records, backlog), the record moves from `docs/research/{topic}-brainstorm/` to `docs/history/brainstorms/{topic}/`, and the user decides whether the moved folder is deleted or committed.
42
42
 
@@ -72,7 +72,8 @@ Boundaries are **diagnosed, not documented** — the `boundary` skill derives th
72
72
  **Deferring tests is what keeps the build loop fast, and the ledger is what makes deferring safe.** A plan-driven build writes no new test files while the code is taking shape; obligations accumulate in the plan and are discharged in one pass at the **verification gate** — user-triggered, offered when implementation completes, mandatory before `Status: Complete`. The gate, the two regimes, the mid-loop rules, and what earns a durable test are `.claude/rules/verification.md`.
73
73
 
74
74
  - **Only a plan may defer.** A bug fix in shipped behavior and any ad-hoc change ship their test immediately — deferral needs a ledger and a gate, and non-plan work has neither.
75
- - **Drive the real surface before pinning tests.** Browser automation for web UI, the real CLI, HTTP against the running worker; the suite pins what must not regress afterward.
75
+ - **The checklist is the gate's first artifact, not its last.** Opening the gate derives or updates `docs/tests/{feature}.md` from the ledger and the LLD's promises (the `documentation` skill's `templates/behavioral-checklist.md`). It is the script rung 1 drives and the source rung 2's tests are drawn from — written after the driving it would be a report, and the tests would have no stated behavior to trace to.
76
+ - **Drive the real surface before pinning tests.** Browser automation for web UI, the real CLI, HTTP against the running worker; the suite then pins the checklist assertions that must not regress, and each section records which test now guards it.
76
77
  - **The gate's verdict is never delegated** — a sub-agent's summary is not verifiable ground truth (the Fan-out guardrail), and browser work is main-session-only where Runtime Notes say so.
77
78
 
78
79
  ### Documentation — close the loop
@@ -7,5 +7,5 @@
7
7
  ".prettierrc.json",
8
8
  ".vscode/settings.json"
9
9
  ],
10
- "digest": "500726b483fd"
10
+ "digest": "5dafd73481fb"
11
11
  }
@@ -41,10 +41,13 @@ Rules for the plan regime between the plan gate and the verification gate:
41
41
 
42
42
  | Rung | Mechanism | Proves |
43
43
  | --- | --- | --- |
44
+ | 0 | **Write the checklist** — `docs/tests/{feature}.md`, from the ledger and the LLD's promises | There is a stated behavior to drive against, and to trace a test back to |
44
45
  | 1 | **Drive the real surface** — browser automation for web UI, the actual CLI binary, HTTP against the running worker | The change works in the product, against real wiring |
45
46
  | 2 | **Pin the durable behaviors** as suite tests per [`testing.md`](testing.md) | The behavior survives the next change |
46
47
  | 3 | **Run the affected suite**, plus the project's e2e smoke gate where one is wired | Nothing else broke |
47
48
 
49
+ - **Rung 0 is what makes 1 and 2 repeatable.** The checklist is the script rung 1 executes and the menu rung 2 selects from — one `**Assert**` per observable, and the section records which test now guards it (or that none does, and why). Derived after the driving it is a report; derived before, it is the only artifact that survives the session and still says what the feature promises. Its shape is the `documentation` skill's `templates/behavioral-checklist.md`.
50
+ - **A failing checklist assertion is never softened to make a run green.** The checklist states the contract; a run that fails records the defect and sends it to the backlog.
48
51
  - **Browser automation is the default for a web surface, and needs no permission to use** — a rendered page driven through real interaction is the only oracle that catches wiring, styling, and state defects together.
49
52
  - **Where the runtime offers no browser automation**, rung 1's verdict belongs to the user: emit a browser-verification checklist (URLs, actions, expected outcomes), the user runs it and reports, the result lands in the changelog entry — and `Status: Complete` waits for it.
50
53
  - **A driven check is evidence, not an artifact.** It proves the change works today; it leaves nothing behind. That is why rung 2 exists.
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
71
71
  | Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
72
72
  | Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
73
73
  | Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
74
+ | Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
74
75
  | Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
75
76
  | One-shot migration/upgrade | [`templates/migration-runbook.md`](templates/migration-runbook.md) (record) |
76
77
  | Add to protected files | [`templates/protected-files.md`](templates/protected-files.md) |
@@ -14,6 +14,7 @@ One file per template. Every template is either a **truth document** (states cur
14
14
  | Environment registry | [environment-registry.md](environment-registry.md) | Truth |
15
15
  | Security overview | [security-overview.md](security-overview.md) | Truth |
16
16
  | Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
17
+ | Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
17
18
  | Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
18
19
  | Protected files | [protected-files.md](protected-files.md) | Truth |
19
20
  | Project root README | [root-readme.md](root-readme.md) | Truth |
@@ -0,0 +1,79 @@
1
+ # Behavioral Checklist (docs/tests/{feature}.md)
2
+
3
+ Truth document. Use for: **how to verify one feature's promised behavior by driving the real product** — the browser, the CLI binary, HTTP against the running service. One file per feature, named for the feature doc that owns the code (`docs/features/auth.md` → `docs/tests/auth.md`). No frontmatter; a checklist owns no code.
4
+
5
+ **This is the driving script, and it is the source the suite is drawn from.** At the verification gate it does double duty: rung 1 drives the real surface *against these steps*, and rung 2 pins the durable subset *of these assertions* as suite tests. Writing it is therefore not a report written afterwards — it is authored or updated **before** the driving, so the gate has something to execute and the tests have something to be derived from. Which assertions earn a permanent test is decided by `verification.md` § What earns a durable test, and each section records the answer on its `Pinned:` line.
6
+
7
+ A checklist outlives the tests it seeds. Where a Playwright script breaks on every selector change, a checklist states the behavior and lets the implementation move under it — so it is written in the product's own vocabulary (labels, URLs, rows) and never in the code's (function names, props, internal state).
8
+
9
+ Required: **Conventions**, at least one numbered behavior section, **Failure Report**. Optional: Test Inputs, Wait Strategy, Driving notes — include only when they carry real content.
10
+
11
+ ## Writing the assertions
12
+
13
+ - **A section is one behavior, its heading stated as a fact** — `3. A stale pointer falls back to the sole membership`, not `3. Test the resolver`. The heading is the promise; the steps are how you see it.
14
+ - **A step is an action; an `**Assert**` is the observable it must produce.** Interleave them in the order a person meets them, so the file reads as a session rather than a spec.
15
+ - **Assert what is observable, at the altitude a user meets it** — a visible label, a URL, a toast, a row in the database, a response envelope. Never a private function's return value: that is a unit test's job, and stating it here couples the checklist to code that will move.
16
+ - **Prefer exact literals** — the real prompt text, the real button label, the real count. A vague assertion passes a broken product.
17
+ - **Assert persistence separately from display.** "It appeared on screen" and "it was written" are two claims; a surface that streams unsaved content satisfies the first while failing the second.
18
+ - **State each section's trace.** `Pinned:` names the suite test that now guards it, or says `driven only` **with the reason** — an unmarked section is indistinguishable from an unexamined one.
19
+ - **A known-failing assertion stays written as the contract.** A checklist states what the feature promises; the *run* records the failure and the backlog carries the defect. Never soften an assertion to make a run go green.
20
+
21
+ ```
22
+ # {Feature} Test Plan
23
+
24
+ {What this covers, and what neighbouring checklists cover instead, with links. Close with:}
25
+ Each step is an action; each **Assert** is the observable it must produce.
26
+
27
+ ## Test Inputs
28
+
29
+ - **URL / entry point** — where the run starts
30
+ - **Identity** — the account or role required, and how it is obtained
31
+ - **State** — the fixture or seeded state the run assumes, stated as counts a reader can check
32
+
33
+ ## Conventions
34
+
35
+ - {The invariants a reader needs to interpret the assertions — the vocabulary, the scoping rule,
36
+ the guarantee that makes a surprising assertion correct. Not a restatement of the LLD.}
37
+
38
+ ---
39
+
40
+ ### 1. {The behavior, stated as a fact}
41
+
42
+ - [ ] {action}
43
+ - [ ] **Assert**: {the observable, with exact literals}
44
+ - [ ] **Assert**: {the persistence claim, where the behavior writes something}
45
+
46
+ > Pinned: `{tests/path/to/file.test.ts}` — or `driven only — {why no durable test is bought}`
47
+
48
+ ### 2. {The next behavior}
49
+
50
+ - [ ] {action}
51
+ - [ ] **Assert**: {observable}
52
+
53
+ > Pinned: {…}
54
+
55
+ ---
56
+
57
+ ## Wait Strategy
58
+
59
+ State-based signals, never fixed sleeps:
60
+
61
+ - **{Milestone}** — {the signal that proves it, as a selector or an observable}
62
+
63
+ Timeouts: {operation} **{n}s**.
64
+
65
+ ## Driving notes
66
+
67
+ - {Hard-won facts about driving this surface that cost someone an hour — an environment trap, a
68
+ harness quirk, a signal that lies. Not general advice.}
69
+
70
+ ## Failure Report
71
+
72
+ For each failed step, capture:
73
+
74
+ - Section and step name, and the expected signal
75
+ - The URL or command at the time of failure
76
+ - The state assertion's actual value, where the step checks one
77
+ - Any visible error, toast, or console exception
78
+ - A screenshot or transcript
79
+ ```
@@ -17,7 +17,8 @@ Testing spans three moments in the plan lifecycle. This skill owns **only the fi
17
17
  | --- | --- | --- |
18
18
  | **Plan gate** (here, after boundary) | Test Obligations section written into the plan | this skill |
19
19
  | **Verification gate** (before `Status: Complete`) | the obligated tests written and green, plus the driven checks against the real surface | the implementer at the gate (`.claude/rules/verification.md`) |
20
- | **Completion** | behavioral checklist at `docs/tests/{feature}.md`; record the gate's results in the changelog | the `documentation` skill + Completion steps |
20
+ | **Verification gate** | behavioral checklist at `docs/tests/{feature}.md`, derived from this ledger **before** the driving, then the tests it seeds | the gate + the `documentation` skill |
21
+ | **Completion** | the gate's results recorded in the changelog; each checklist section carrying its `Pinned:` trace | Completion steps |
21
22
 
22
23
  Writing tests *before* the code they cover either fabricates implementation coupling (labels/routes/copy the plan hasn't fixed) or leaves the suite red on the shared branch for the plan's whole duration. Writing them *during* the build loop taxes every iteration for behavior still in flux. So the plan gate emits obligations, the build loop stays free of test files, and the manifest is discharged in one pass at the verification gate.
23
24
 
@@ -7,5 +7,5 @@
7
7
  ".prettierrc.json",
8
8
  ".vscode/settings.json"
9
9
  ],
10
- "digest": "386f83082c31"
10
+ "digest": "6fb95b8c81d5"
11
11
  }
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
71
71
  | Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
72
72
  | Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
73
73
  | Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
74
+ | Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
74
75
  | Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
75
76
  | One-shot migration/upgrade | [`templates/migration-runbook.md`](templates/migration-runbook.md) (record) |
76
77
  | Add to protected files | [`templates/protected-files.md`](templates/protected-files.md) |
@@ -14,6 +14,7 @@ One file per template. Every template is either a **truth document** (states cur
14
14
  | Environment registry | [environment-registry.md](environment-registry.md) | Truth |
15
15
  | Security overview | [security-overview.md](security-overview.md) | Truth |
16
16
  | Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
17
+ | Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
17
18
  | Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
18
19
  | Protected files | [protected-files.md](protected-files.md) | Truth |
19
20
  | Project root README | [root-readme.md](root-readme.md) | Truth |
@@ -0,0 +1,79 @@
1
+ # Behavioral Checklist (docs/tests/{feature}.md)
2
+
3
+ Truth document. Use for: **how to verify one feature's promised behavior by driving the real product** — the browser, the CLI binary, HTTP against the running service. One file per feature, named for the feature doc that owns the code (`docs/features/auth.md` → `docs/tests/auth.md`). No frontmatter; a checklist owns no code.
4
+
5
+ **This is the driving script, and it is the source the suite is drawn from.** At the verification gate it does double duty: rung 1 drives the real surface *against these steps*, and rung 2 pins the durable subset *of these assertions* as suite tests. Writing it is therefore not a report written afterwards — it is authored or updated **before** the driving, so the gate has something to execute and the tests have something to be derived from. Which assertions earn a permanent test is decided by `verification.md` § What earns a durable test, and each section records the answer on its `Pinned:` line.
6
+
7
+ A checklist outlives the tests it seeds. Where a Playwright script breaks on every selector change, a checklist states the behavior and lets the implementation move under it — so it is written in the product's own vocabulary (labels, URLs, rows) and never in the code's (function names, props, internal state).
8
+
9
+ Required: **Conventions**, at least one numbered behavior section, **Failure Report**. Optional: Test Inputs, Wait Strategy, Driving notes — include only when they carry real content.
10
+
11
+ ## Writing the assertions
12
+
13
+ - **A section is one behavior, its heading stated as a fact** — `3. A stale pointer falls back to the sole membership`, not `3. Test the resolver`. The heading is the promise; the steps are how you see it.
14
+ - **A step is an action; an `**Assert**` is the observable it must produce.** Interleave them in the order a person meets them, so the file reads as a session rather than a spec.
15
+ - **Assert what is observable, at the altitude a user meets it** — a visible label, a URL, a toast, a row in the database, a response envelope. Never a private function's return value: that is a unit test's job, and stating it here couples the checklist to code that will move.
16
+ - **Prefer exact literals** — the real prompt text, the real button label, the real count. A vague assertion passes a broken product.
17
+ - **Assert persistence separately from display.** "It appeared on screen" and "it was written" are two claims; a surface that streams unsaved content satisfies the first while failing the second.
18
+ - **State each section's trace.** `Pinned:` names the suite test that now guards it, or says `driven only` **with the reason** — an unmarked section is indistinguishable from an unexamined one.
19
+ - **A known-failing assertion stays written as the contract.** A checklist states what the feature promises; the *run* records the failure and the backlog carries the defect. Never soften an assertion to make a run go green.
20
+
21
+ ```
22
+ # {Feature} Test Plan
23
+
24
+ {What this covers, and what neighbouring checklists cover instead, with links. Close with:}
25
+ Each step is an action; each **Assert** is the observable it must produce.
26
+
27
+ ## Test Inputs
28
+
29
+ - **URL / entry point** — where the run starts
30
+ - **Identity** — the account or role required, and how it is obtained
31
+ - **State** — the fixture or seeded state the run assumes, stated as counts a reader can check
32
+
33
+ ## Conventions
34
+
35
+ - {The invariants a reader needs to interpret the assertions — the vocabulary, the scoping rule,
36
+ the guarantee that makes a surprising assertion correct. Not a restatement of the LLD.}
37
+
38
+ ---
39
+
40
+ ### 1. {The behavior, stated as a fact}
41
+
42
+ - [ ] {action}
43
+ - [ ] **Assert**: {the observable, with exact literals}
44
+ - [ ] **Assert**: {the persistence claim, where the behavior writes something}
45
+
46
+ > Pinned: `{tests/path/to/file.test.ts}` — or `driven only — {why no durable test is bought}`
47
+
48
+ ### 2. {The next behavior}
49
+
50
+ - [ ] {action}
51
+ - [ ] **Assert**: {observable}
52
+
53
+ > Pinned: {…}
54
+
55
+ ---
56
+
57
+ ## Wait Strategy
58
+
59
+ State-based signals, never fixed sleeps:
60
+
61
+ - **{Milestone}** — {the signal that proves it, as a selector or an observable}
62
+
63
+ Timeouts: {operation} **{n}s**.
64
+
65
+ ## Driving notes
66
+
67
+ - {Hard-won facts about driving this surface that cost someone an hour — an environment trap, a
68
+ harness quirk, a signal that lies. Not general advice.}
69
+
70
+ ## Failure Report
71
+
72
+ For each failed step, capture:
73
+
74
+ - Section and step name, and the expected signal
75
+ - The URL or command at the time of failure
76
+ - The state assertion's actual value, where the step checks one
77
+ - Any visible error, toast, or console exception
78
+ - A screenshot or transcript
79
+ ```
@@ -7,5 +7,5 @@
7
7
  ".prettierrc.json",
8
8
  ".vscode/settings.json"
9
9
  ],
10
- "digest": "a8993d8c2d44"
10
+ "digest": "4e555d81995f"
11
11
  }
@@ -71,6 +71,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
71
71
  | Document env vars / config | [`templates/environment-registry.md`](templates/environment-registry.md) |
72
72
  | Security / threat model | [`templates/security-overview.md`](templates/security-overview.md) |
73
73
  | Testing strategy | [`templates/testing-strategy.md`](templates/testing-strategy.md) |
74
+ | Behavioral checklist for one feature (`docs/tests/{feature}.md`) | [`templates/behavioral-checklist.md`](templates/behavioral-checklist.md) — the verification gate's driving script, and the source its suite tests are drawn from |
74
75
  | Recurring procedure/setup | [`templates/operations-procedure.md`](templates/operations-procedure.md) |
75
76
  | One-shot migration/upgrade | [`templates/migration-runbook.md`](templates/migration-runbook.md) (record) |
76
77
  | Add to protected files | [`templates/protected-files.md`](templates/protected-files.md) |
@@ -14,6 +14,7 @@ One file per template. Every template is either a **truth document** (states cur
14
14
  | Environment registry | [environment-registry.md](environment-registry.md) | Truth |
15
15
  | Security overview | [security-overview.md](security-overview.md) | Truth |
16
16
  | Testing strategy | [testing-strategy.md](testing-strategy.md) | Truth |
17
+ | Behavioral checklist | [behavioral-checklist.md](behavioral-checklist.md) | Truth |
17
18
  | Operations procedure | [operations-procedure.md](operations-procedure.md) | Truth |
18
19
  | Protected files | [protected-files.md](protected-files.md) | Truth |
19
20
  | Project root README | [root-readme.md](root-readme.md) | Truth |
@@ -0,0 +1,79 @@
1
+ # Behavioral Checklist (docs/tests/{feature}.md)
2
+
3
+ Truth document. Use for: **how to verify one feature's promised behavior by driving the real product** — the browser, the CLI binary, HTTP against the running service. One file per feature, named for the feature doc that owns the code (`docs/features/auth.md` → `docs/tests/auth.md`). No frontmatter; a checklist owns no code.
4
+
5
+ **This is the driving script, and it is the source the suite is drawn from.** At the verification gate it does double duty: rung 1 drives the real surface *against these steps*, and rung 2 pins the durable subset *of these assertions* as suite tests. Writing it is therefore not a report written afterwards — it is authored or updated **before** the driving, so the gate has something to execute and the tests have something to be derived from. Which assertions earn a permanent test is decided by `verification.md` § What earns a durable test, and each section records the answer on its `Pinned:` line.
6
+
7
+ A checklist outlives the tests it seeds. Where a Playwright script breaks on every selector change, a checklist states the behavior and lets the implementation move under it — so it is written in the product's own vocabulary (labels, URLs, rows) and never in the code's (function names, props, internal state).
8
+
9
+ Required: **Conventions**, at least one numbered behavior section, **Failure Report**. Optional: Test Inputs, Wait Strategy, Driving notes — include only when they carry real content.
10
+
11
+ ## Writing the assertions
12
+
13
+ - **A section is one behavior, its heading stated as a fact** — `3. A stale pointer falls back to the sole membership`, not `3. Test the resolver`. The heading is the promise; the steps are how you see it.
14
+ - **A step is an action; an `**Assert**` is the observable it must produce.** Interleave them in the order a person meets them, so the file reads as a session rather than a spec.
15
+ - **Assert what is observable, at the altitude a user meets it** — a visible label, a URL, a toast, a row in the database, a response envelope. Never a private function's return value: that is a unit test's job, and stating it here couples the checklist to code that will move.
16
+ - **Prefer exact literals** — the real prompt text, the real button label, the real count. A vague assertion passes a broken product.
17
+ - **Assert persistence separately from display.** "It appeared on screen" and "it was written" are two claims; a surface that streams unsaved content satisfies the first while failing the second.
18
+ - **State each section's trace.** `Pinned:` names the suite test that now guards it, or says `driven only` **with the reason** — an unmarked section is indistinguishable from an unexamined one.
19
+ - **A known-failing assertion stays written as the contract.** A checklist states what the feature promises; the *run* records the failure and the backlog carries the defect. Never soften an assertion to make a run go green.
20
+
21
+ ```
22
+ # {Feature} Test Plan
23
+
24
+ {What this covers, and what neighbouring checklists cover instead, with links. Close with:}
25
+ Each step is an action; each **Assert** is the observable it must produce.
26
+
27
+ ## Test Inputs
28
+
29
+ - **URL / entry point** — where the run starts
30
+ - **Identity** — the account or role required, and how it is obtained
31
+ - **State** — the fixture or seeded state the run assumes, stated as counts a reader can check
32
+
33
+ ## Conventions
34
+
35
+ - {The invariants a reader needs to interpret the assertions — the vocabulary, the scoping rule,
36
+ the guarantee that makes a surprising assertion correct. Not a restatement of the LLD.}
37
+
38
+ ---
39
+
40
+ ### 1. {The behavior, stated as a fact}
41
+
42
+ - [ ] {action}
43
+ - [ ] **Assert**: {the observable, with exact literals}
44
+ - [ ] **Assert**: {the persistence claim, where the behavior writes something}
45
+
46
+ > Pinned: `{tests/path/to/file.test.ts}` — or `driven only — {why no durable test is bought}`
47
+
48
+ ### 2. {The next behavior}
49
+
50
+ - [ ] {action}
51
+ - [ ] **Assert**: {observable}
52
+
53
+ > Pinned: {…}
54
+
55
+ ---
56
+
57
+ ## Wait Strategy
58
+
59
+ State-based signals, never fixed sleeps:
60
+
61
+ - **{Milestone}** — {the signal that proves it, as a selector or an observable}
62
+
63
+ Timeouts: {operation} **{n}s**.
64
+
65
+ ## Driving notes
66
+
67
+ - {Hard-won facts about driving this surface that cost someone an hour — an environment trap, a
68
+ harness quirk, a signal that lies. Not general advice.}
69
+
70
+ ## Failure Report
71
+
72
+ For each failed step, capture:
73
+
74
+ - Section and step name, and the expected signal
75
+ - The URL or command at the time of failure
76
+ - The state assertion's actual value, where the step checks one
77
+ - Any visible error, toast, or console exception
78
+ - A screenshot or transcript
79
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.19.38",
3
+ "version": "0.19.39",
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": {
@@ -41,5 +41,5 @@
41
41
  "agent",
42
42
  "plugin"
43
43
  ],
44
- "etnaFingerprint": "088c311840d2"
44
+ "etnaFingerprint": "a4419d09d415"
45
45
  }