@nurix/etna 0.19.57 → 0.19.58
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.
- package/data/harness-index.json +1 -1
- package/data/harnesses/apollo/CLAUDE.md +1 -1
- package/data/harnesses/apollo/agents/lld-mode.md +2 -0
- package/data/harnesses/apollo/harness.json +2 -2
- package/data/harnesses/apollo/hooks/compliance.mjs +28 -2
- package/data/harnesses/apollo/skills/boundary/SKILL.md +4 -0
- package/data/harnesses/apollo/skills/documentation/templates/plan.md +18 -4
- package/data/harnesses/code/CLAUDE.md +1 -1
- package/data/harnesses/code/agents/lld-mode.md +2 -0
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/compliance.mjs +28 -2
- package/data/harnesses/code/skills/boundary/SKILL.md +4 -0
- package/data/harnesses/code/skills/documentation/templates/plan.md +18 -4
- package/data/harnesses/delivery/CLAUDE.md +1 -1
- package/data/harnesses/delivery/agents/lld-mode.md +2 -0
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/documentation/templates/plan.md +18 -4
- package/data/harnesses/etna/CLAUDE.md +1 -1
- package/data/harnesses/etna/agents/lld-mode.md +2 -0
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/boundary/SKILL.md +4 -0
- package/data/harnesses/etna/skills/documentation/templates/plan.md +18 -4
- package/package.json +2 -2
package/data/harness-index.json
CHANGED
|
@@ -39,7 +39,7 @@ Three peer modes, then a verification gate and a Completion step — enter where
|
|
|
39
39
|
|
|
40
40
|
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/testing.md`. A plan with outstanding obligations stays open, whatever the code does.
|
|
41
41
|
2. Freeze the plan — `Status: Complete`, fill the Completed date. The file is now frozen.
|
|
42
|
-
3.
|
|
42
|
+
3. **Discharge the plan's Doc Obligations ledger — every row, into exactly one outcome**: **updated** (the doc now states what the code does), **owes nothing** (with the reason), or **blocked** (→ a backlog item, so the debt outlives the frozen plan). For each row's doc: flip `status: active` if it was `draft`, extend it in place with the how-it-works sections, and confirm its `owns:` globs against the actual code. A plan spanning three features discharges three rows — the ledger, not memory, says how many.
|
|
43
43
|
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.
|
|
44
44
|
|
|
45
45
|
**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.
|
|
@@ -33,6 +33,7 @@ This tells you what already exists, what's adjacent, how detailed the LLD should
|
|
|
33
33
|
4. **Current state** — Understand how the system works today in the area being specified
|
|
34
34
|
5. **Dependencies** — Map what this feature touches and what depends on it
|
|
35
35
|
6. **Ownership conflicts** — Compare the new feature's intended code paths against existing feature docs' `owns:` globs. Report overlaps (two docs claiming the same paths at equal specificity).
|
|
36
|
+
7. **Invalidation** — a different question from conflict, and the one that gets missed. A conflict is two docs claiming one glob; an invalidation is **one existing doc whose stated behavior this feature makes false** — it may own entirely different paths and still be wrong once this ships. For every doc whose territory this feature touches or whose described flow it changes, name the specific claim that stops being true.
|
|
36
37
|
|
|
37
38
|
## What You Return
|
|
38
39
|
|
|
@@ -44,6 +45,7 @@ Structure your findings as:
|
|
|
44
45
|
- **Current behavior**: How the relevant part of the system works today
|
|
45
46
|
- **Conventions**: Naming, structure, and patterns to follow based on existing code
|
|
46
47
|
- **Ownership conflicts**: Existing feature docs whose `owns:` globs overlap with the proposed feature. Include the conflicting paths and the owning doc name.
|
|
48
|
+
- **Invalidated claims**: One row per existing doc this feature makes wrong — doc path, the claim, why it stops being true. This list seeds the plan's **Doc Obligations** ledger, so it is the research finding most likely to survive into an artifact; "none" is a real answer and says the feature is genuinely additive.
|
|
47
49
|
- **Risks or concerns**: Anything the LLD should address or call out
|
|
48
50
|
|
|
49
51
|
Use the documentation skill's style guide and conventions when structuring your findings — imperative voice, ASCII diagrams for flows, function signatures over implementations, concise.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "apollo",
|
|
3
3
|
"name": "apollo",
|
|
4
|
-
"version": "1.1
|
|
4
|
+
"version": "1.2.1",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -15,5 +15,5 @@
|
|
|
15
15
|
"docs/memory/main.md",
|
|
16
16
|
".mcp.json"
|
|
17
17
|
],
|
|
18
|
-
"digest": "
|
|
18
|
+
"digest": "6c0123cfa9ee"
|
|
19
19
|
}
|
|
@@ -75,6 +75,7 @@ function openGatedPlans(projectDir) {
|
|
|
75
75
|
status,
|
|
76
76
|
gates,
|
|
77
77
|
hasLedger: /^##\s+Test Obligations\b/m.test(text),
|
|
78
|
+
hasDocLedger: /^##\s+Doc Obligations\b/m.test(text),
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
return plans;
|
|
@@ -110,6 +111,12 @@ function fileGate(projectDir, rel, toolName) {
|
|
|
110
111
|
`BLOCKED — plan gate. \`${plan.file}\` has no \`## Test Obligations\` section. Run the \`testing\` skill (plan-gate mode); its ledger is what the verification gate discharges.`
|
|
111
112
|
);
|
|
112
113
|
}
|
|
114
|
+
if (!plan.hasDocLedger) {
|
|
115
|
+
return decision(
|
|
116
|
+
"deny",
|
|
117
|
+
`BLOCKED — plan gate. \`${plan.file}\` has no \`## Doc Obligations\` section. Resolve the Proposed Changes paths against the ownership index and fill the table yourself — it is a lookup, not a skill run. "None" is a valid row when the plan touches only unowned paths.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
113
120
|
}
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -301,6 +308,15 @@ function plansCompletedThisSession(projectDir, sessionId) {
|
|
|
301
308
|
return out;
|
|
302
309
|
}
|
|
303
310
|
|
|
311
|
+
// A completed plan whose Doc Obligations ledger was never discharged. Discharge is a judgment the
|
|
312
|
+
// hook cannot make — whether a doc was actually updated well is a human read — so what it checks is
|
|
313
|
+
// the one mechanical trace the act leaves: the Done Criteria checkbox that says every row was
|
|
314
|
+
// examined. Presence of the section is gated at the implementation-edit wall; this is the other end.
|
|
315
|
+
function docLedgerUndischarged(text) {
|
|
316
|
+
if (!/^##\s+Doc Obligations\b/m.test(text)) return false;
|
|
317
|
+
return /^\s*-\s*\[ \]\s*Every Doc Obligations row discharged/m.test(text);
|
|
318
|
+
}
|
|
319
|
+
|
|
304
320
|
// Whether some changelog entry already accounts for this plan.
|
|
305
321
|
//
|
|
306
322
|
// COMMITTED COUNTS. The test used to be `git status --porcelain docs/history/changelog/` — i.e. "is
|
|
@@ -381,9 +397,19 @@ function stopGate(projectDir, payload) {
|
|
|
381
397
|
};
|
|
382
398
|
}
|
|
383
399
|
|
|
384
|
-
const
|
|
385
|
-
|
|
400
|
+
const completed = plansCompletedThisSession(projectDir, payload.session_id);
|
|
401
|
+
|
|
402
|
+
const docsOpen = completed.filter((rel) =>
|
|
403
|
+
docLedgerUndischarged(readSafe(path.join(projectDir, rel)))
|
|
386
404
|
);
|
|
405
|
+
if (docsOpen.length > 0) {
|
|
406
|
+
return {
|
|
407
|
+
decision: "block",
|
|
408
|
+
reason: `Plan \`${docsOpen[0]}\` reached Status: Complete with its Doc Obligations rows undischarged. Walk each row — update the doc, or mark it owes nothing with the reason, or send it to the backlog as blocked — then tick the Done Criteria line. The feature docs are the only artifact the next session inherits.`,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const undocumented = completed.filter((rel) => !planHasChangelogEntry(projectDir, rel));
|
|
387
413
|
if (undocumented.length > 0) {
|
|
388
414
|
return {
|
|
389
415
|
decision: "block",
|
|
@@ -57,8 +57,12 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
|
|
|
57
57
|
|
|
58
58
|
## Suggested plan amendments
|
|
59
59
|
## Missing plan subsections
|
|
60
|
+
## Docs the plan's ledger missed
|
|
61
|
+
| Feature doc | Owned path in the touch list | In Doc Obligations? |
|
|
60
62
|
```
|
|
61
63
|
|
|
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
|
+
|
|
62
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.
|
|
63
67
|
|
|
64
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 these exact forms — implementation edits stay blocked while the segment reads `pending`. A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
|
|
@@ -4,14 +4,16 @@ Record. Use for: every implementation plan. Plans are created here directly with
|
|
|
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
|
|
|
7
|
-
|
|
7
|
+
**Doc Obligations is the one ledger the plan's author writes.** Deriving tests from behavior is judgment, which is why `testing` owns that section and it is marked never-hand-author; resolving Proposed Changes' file paths to the feature docs that own them is a **lookup** against the ownership index already injected at session start. Different work, different rule — fill it yourself, while the touch list is fresh.
|
|
8
|
+
|
|
9
|
+
The **`Gates:`** line is machine-read: the compliance hook greps exactly the forms below, and implementation edits are blocked while a segment reads `pending`. Each gate skill rewrites only its own segment when it runs — `boundary` to `Boundary: passed YYYY-MM-DD` or `Boundary: blocked YYYY-MM-DD`; `testing` (plan-gate mode) to `Test-plan: written YYYY-MM-DD (N rows)` — the segment label stays `Test-plan`, greppable. The author writes `Docs: mapped YYYY-MM-DD (N docs)` when the Doc Obligations table is filled. Never hand-edit the line to skip a gate.
|
|
8
10
|
|
|
9
11
|
```
|
|
10
12
|
# {Feature Name}
|
|
11
13
|
|
|
12
14
|
**Status:** Draft | In Progress | Complete | Abandoned
|
|
13
|
-
**Gates:** Boundary: pending · Test-plan: pending
|
|
14
|
-
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md)
|
|
15
|
+
**Gates:** Boundary: pending · Test-plan: pending · Docs: pending
|
|
16
|
+
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md) <!-- one line per feature doc this plan implements against; a plan spanning three features names three -->
|
|
15
17
|
**Started:** YYYY-MM-DD
|
|
16
18
|
**Completed:** YYYY-MM-DD <!-- fill when status flips to Complete -->
|
|
17
19
|
|
|
@@ -44,6 +46,18 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
44
46
|
- List which cross-cutting contracts this plan affects (db schema, wire envelope, auth, events, env/config, …)
|
|
45
47
|
- "None" is a valid answer and means the `boundary` check will pass cleanly
|
|
46
48
|
|
|
49
|
+
## Doc Obligations
|
|
50
|
+
|
|
51
|
+
<!-- One row per feature doc whose `owns:` globs intersect the Proposed Changes above — resolve
|
|
52
|
+
them against the injected ownership index. Hand-authored: this is a lookup, not research.
|
|
53
|
+
Amendable while the plan is open; discharged at Completion. -->
|
|
54
|
+
|
|
55
|
+
| Doc | Claim that changes | `owns:` still accurate? |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `docs/features/{feature}.md` | what it says today that this plan makes false | yes / no — new paths to add |
|
|
58
|
+
|
|
59
|
+
**"None" is valid** — a plan touching only unowned paths owes no doc update, and says so explicitly. It is not a free pass: `boundary` builds its own touch list from the same Proposed Changes and reports docs this table missed.
|
|
60
|
+
|
|
47
61
|
## Implementation Steps
|
|
48
62
|
|
|
49
63
|
1. Concrete, ordered, testable
|
|
@@ -60,7 +74,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
60
74
|
|
|
61
75
|
- [ ] Implementation complete
|
|
62
76
|
- [ ] Verification gate passed — every Test Obligations row discharged (satisfied / owes nothing / blocked → backlog), gate run date and results noted here
|
|
63
|
-
- [ ]
|
|
77
|
+
- [ ] Every Doc Obligations row discharged — **updated** / **owes nothing** (with the reason) / **blocked** (→ backlog item, so the debt outlives the frozen plan)
|
|
64
78
|
- [ ] Changelog entry created in `docs/history/changelog/`, carrying the gate's results
|
|
65
79
|
- [ ] Plan marked `Status: Complete`, **Completed:** date filled
|
|
66
80
|
|
|
@@ -37,7 +37,7 @@ Three peer modes, then a verification gate and a Completion step — enter where
|
|
|
37
37
|
|
|
38
38
|
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/testing.md`. A plan with outstanding obligations stays open, whatever the code does.
|
|
39
39
|
2. Freeze the plan — `Status: Complete`, fill the Completed date. The file is now frozen.
|
|
40
|
-
3.
|
|
40
|
+
3. **Discharge the plan's Doc Obligations ledger — every row, into exactly one outcome**: **updated** (the doc now states what the code does), **owes nothing** (with the reason), or **blocked** (→ a backlog item, so the debt outlives the frozen plan). For each row's doc: flip `status: active` if it was `draft`, extend it in place with the how-it-works sections, and confirm its `owns:` globs against the actual code. A plan spanning three features discharges three rows — the ledger, not memory, says how many.
|
|
41
41
|
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.
|
|
42
42
|
|
|
43
43
|
**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.
|
|
@@ -33,6 +33,7 @@ This tells you what already exists, what's adjacent, how detailed the LLD should
|
|
|
33
33
|
4. **Current state** — Understand how the system works today in the area being specified
|
|
34
34
|
5. **Dependencies** — Map what this feature touches and what depends on it
|
|
35
35
|
6. **Ownership conflicts** — Compare the new feature's intended code paths against existing feature docs' `owns:` globs. Report overlaps (two docs claiming the same paths at equal specificity).
|
|
36
|
+
7. **Invalidation** — a different question from conflict, and the one that gets missed. A conflict is two docs claiming one glob; an invalidation is **one existing doc whose stated behavior this feature makes false** — it may own entirely different paths and still be wrong once this ships. For every doc whose territory this feature touches or whose described flow it changes, name the specific claim that stops being true.
|
|
36
37
|
|
|
37
38
|
## What You Return
|
|
38
39
|
|
|
@@ -44,6 +45,7 @@ Structure your findings as:
|
|
|
44
45
|
- **Current behavior**: How the relevant part of the system works today
|
|
45
46
|
- **Conventions**: Naming, structure, and patterns to follow based on existing code
|
|
46
47
|
- **Ownership conflicts**: Existing feature docs whose `owns:` globs overlap with the proposed feature. Include the conflicting paths and the owning doc name.
|
|
48
|
+
- **Invalidated claims**: One row per existing doc this feature makes wrong — doc path, the claim, why it stops being true. This list seeds the plan's **Doc Obligations** ledger, so it is the research finding most likely to survive into an artifact; "none" is a real answer and says the feature is genuinely additive.
|
|
47
49
|
- **Risks or concerns**: Anything the LLD should address or call out
|
|
48
50
|
|
|
49
51
|
Use the documentation skill's style guide and conventions when structuring your findings — imperative voice, ASCII diagrams for flows, function signatures over implementations, concise.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "code",
|
|
3
3
|
"name": "code",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.7.1",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -10,5 +10,5 @@
|
|
|
10
10
|
"seeds": [
|
|
11
11
|
".mcp.json"
|
|
12
12
|
],
|
|
13
|
-
"digest": "
|
|
13
|
+
"digest": "ecbd84f05b8e"
|
|
14
14
|
}
|
|
@@ -75,6 +75,7 @@ function openGatedPlans(projectDir) {
|
|
|
75
75
|
status,
|
|
76
76
|
gates,
|
|
77
77
|
hasLedger: /^##\s+Test Obligations\b/m.test(text),
|
|
78
|
+
hasDocLedger: /^##\s+Doc Obligations\b/m.test(text),
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
return plans;
|
|
@@ -110,6 +111,12 @@ function fileGate(projectDir, rel, toolName) {
|
|
|
110
111
|
`BLOCKED — plan gate. \`${plan.file}\` has no \`## Test Obligations\` section. Run the \`testing\` skill (plan-gate mode); its ledger is what the verification gate discharges.`
|
|
111
112
|
);
|
|
112
113
|
}
|
|
114
|
+
if (!plan.hasDocLedger) {
|
|
115
|
+
return decision(
|
|
116
|
+
"deny",
|
|
117
|
+
`BLOCKED — plan gate. \`${plan.file}\` has no \`## Doc Obligations\` section. Resolve the Proposed Changes paths against the ownership index and fill the table yourself — it is a lookup, not a skill run. "None" is a valid row when the plan touches only unowned paths.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
113
120
|
}
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -301,6 +308,15 @@ function plansCompletedThisSession(projectDir, sessionId) {
|
|
|
301
308
|
return out;
|
|
302
309
|
}
|
|
303
310
|
|
|
311
|
+
// A completed plan whose Doc Obligations ledger was never discharged. Discharge is a judgment the
|
|
312
|
+
// hook cannot make — whether a doc was actually updated well is a human read — so what it checks is
|
|
313
|
+
// the one mechanical trace the act leaves: the Done Criteria checkbox that says every row was
|
|
314
|
+
// examined. Presence of the section is gated at the implementation-edit wall; this is the other end.
|
|
315
|
+
function docLedgerUndischarged(text) {
|
|
316
|
+
if (!/^##\s+Doc Obligations\b/m.test(text)) return false;
|
|
317
|
+
return /^\s*-\s*\[ \]\s*Every Doc Obligations row discharged/m.test(text);
|
|
318
|
+
}
|
|
319
|
+
|
|
304
320
|
// Whether some changelog entry already accounts for this plan.
|
|
305
321
|
//
|
|
306
322
|
// COMMITTED COUNTS. The test used to be `git status --porcelain docs/history/changelog/` — i.e. "is
|
|
@@ -381,9 +397,19 @@ function stopGate(projectDir, payload) {
|
|
|
381
397
|
};
|
|
382
398
|
}
|
|
383
399
|
|
|
384
|
-
const
|
|
385
|
-
|
|
400
|
+
const completed = plansCompletedThisSession(projectDir, payload.session_id);
|
|
401
|
+
|
|
402
|
+
const docsOpen = completed.filter((rel) =>
|
|
403
|
+
docLedgerUndischarged(readSafe(path.join(projectDir, rel)))
|
|
386
404
|
);
|
|
405
|
+
if (docsOpen.length > 0) {
|
|
406
|
+
return {
|
|
407
|
+
decision: "block",
|
|
408
|
+
reason: `Plan \`${docsOpen[0]}\` reached Status: Complete with its Doc Obligations rows undischarged. Walk each row — update the doc, or mark it owes nothing with the reason, or send it to the backlog as blocked — then tick the Done Criteria line. The feature docs are the only artifact the next session inherits.`,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const undocumented = completed.filter((rel) => !planHasChangelogEntry(projectDir, rel));
|
|
387
413
|
if (undocumented.length > 0) {
|
|
388
414
|
return {
|
|
389
415
|
decision: "block",
|
|
@@ -57,8 +57,12 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
|
|
|
57
57
|
|
|
58
58
|
## Suggested plan amendments
|
|
59
59
|
## Missing plan subsections
|
|
60
|
+
## Docs the plan's ledger missed
|
|
61
|
+
| Feature doc | Owned path in the touch list | In Doc Obligations? |
|
|
60
62
|
```
|
|
61
63
|
|
|
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
|
+
|
|
62
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.
|
|
63
67
|
|
|
64
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 these exact forms — implementation edits stay blocked while the segment reads `pending`. A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
|
|
@@ -4,14 +4,16 @@ Record. Use for: every implementation plan. Plans are created here directly with
|
|
|
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
|
|
|
7
|
-
|
|
7
|
+
**Doc Obligations is the one ledger the plan's author writes.** Deriving tests from behavior is judgment, which is why `testing` owns that section and it is marked never-hand-author; resolving Proposed Changes' file paths to the feature docs that own them is a **lookup** against the ownership index already injected at session start. Different work, different rule — fill it yourself, while the touch list is fresh.
|
|
8
|
+
|
|
9
|
+
The **`Gates:`** line is machine-read: the compliance hook greps exactly the forms below, and implementation edits are blocked while a segment reads `pending`. Each gate skill rewrites only its own segment when it runs — `boundary` to `Boundary: passed YYYY-MM-DD` or `Boundary: blocked YYYY-MM-DD`; `testing` (plan-gate mode) to `Test-plan: written YYYY-MM-DD (N rows)` — the segment label stays `Test-plan`, greppable. The author writes `Docs: mapped YYYY-MM-DD (N docs)` when the Doc Obligations table is filled. Never hand-edit the line to skip a gate.
|
|
8
10
|
|
|
9
11
|
```
|
|
10
12
|
# {Feature Name}
|
|
11
13
|
|
|
12
14
|
**Status:** Draft | In Progress | Complete | Abandoned
|
|
13
|
-
**Gates:** Boundary: pending · Test-plan: pending
|
|
14
|
-
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md)
|
|
15
|
+
**Gates:** Boundary: pending · Test-plan: pending · Docs: pending
|
|
16
|
+
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md) <!-- one line per feature doc this plan implements against; a plan spanning three features names three -->
|
|
15
17
|
**Started:** YYYY-MM-DD
|
|
16
18
|
**Completed:** YYYY-MM-DD <!-- fill when status flips to Complete -->
|
|
17
19
|
|
|
@@ -44,6 +46,18 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
44
46
|
- List which cross-cutting contracts this plan affects (db schema, wire envelope, auth, events, env/config, …)
|
|
45
47
|
- "None" is a valid answer and means the `boundary` check will pass cleanly
|
|
46
48
|
|
|
49
|
+
## Doc Obligations
|
|
50
|
+
|
|
51
|
+
<!-- One row per feature doc whose `owns:` globs intersect the Proposed Changes above — resolve
|
|
52
|
+
them against the injected ownership index. Hand-authored: this is a lookup, not research.
|
|
53
|
+
Amendable while the plan is open; discharged at Completion. -->
|
|
54
|
+
|
|
55
|
+
| Doc | Claim that changes | `owns:` still accurate? |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `docs/features/{feature}.md` | what it says today that this plan makes false | yes / no — new paths to add |
|
|
58
|
+
|
|
59
|
+
**"None" is valid** — a plan touching only unowned paths owes no doc update, and says so explicitly. It is not a free pass: `boundary` builds its own touch list from the same Proposed Changes and reports docs this table missed.
|
|
60
|
+
|
|
47
61
|
## Implementation Steps
|
|
48
62
|
|
|
49
63
|
1. Concrete, ordered, testable
|
|
@@ -60,7 +74,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
60
74
|
|
|
61
75
|
- [ ] Implementation complete
|
|
62
76
|
- [ ] Verification gate passed — every Test Obligations row discharged (satisfied / owes nothing / blocked → backlog), gate run date and results noted here
|
|
63
|
-
- [ ]
|
|
77
|
+
- [ ] Every Doc Obligations row discharged — **updated** / **owes nothing** (with the reason) / **blocked** (→ backlog item, so the debt outlives the frozen plan)
|
|
64
78
|
- [ ] Changelog entry created in `docs/history/changelog/`, carrying the gate's results
|
|
65
79
|
- [ ] Plan marked `Status: Complete`, **Completed:** date filled
|
|
66
80
|
|
|
@@ -55,7 +55,7 @@ Three peer modes plus a Completion step — enter wherever the user's thinking a
|
|
|
55
55
|
| **LLD** (low-level design) | a new prompt family, task type, or eval suite | `lld-mode` agent + `documentation` skill | Plan |
|
|
56
56
|
| **Plan** | an LLD is approved | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md` | Completion |
|
|
57
57
|
|
|
58
|
-
**On Plan Completion:** freeze the plan (`Status: Complete`, Completed date);
|
|
58
|
+
**On Plan Completion:** freeze the plan (`Status: Complete`, Completed date); discharge every Doc Obligations row into **updated**, **owes nothing** (with the reason), or **blocked** (→ backlog) — for each row's doc, flip `status: active`, extend it in place, and confirm its `owns:` globs against the actual prompt files; write the changelog entry as a draft immediately.
|
|
59
59
|
|
|
60
60
|
**On Brainstorm Close:** the skill's `stop` procedure — converge, a user-approved harvest manifest, apply, uselessness test; the record moves to `docs/history/brainstorms/{topic}/`.
|
|
61
61
|
|
|
@@ -33,6 +33,7 @@ This tells you what already exists, what's adjacent, how detailed the LLD should
|
|
|
33
33
|
4. **Current state** — Understand how the system works today in the area being specified
|
|
34
34
|
5. **Dependencies** — Map what this feature touches and what depends on it
|
|
35
35
|
6. **Ownership conflicts** — Compare the new feature's intended code paths against existing feature docs' `owns:` globs. Report overlaps (two docs claiming the same paths at equal specificity).
|
|
36
|
+
7. **Invalidation** — a different question from conflict, and the one that gets missed. A conflict is two docs claiming one glob; an invalidation is **one existing doc whose stated behavior this feature makes false** — it may own entirely different paths and still be wrong once this ships. For every doc whose territory this feature touches or whose described flow it changes, name the specific claim that stops being true.
|
|
36
37
|
|
|
37
38
|
## What You Return
|
|
38
39
|
|
|
@@ -44,6 +45,7 @@ Structure your findings as:
|
|
|
44
45
|
- **Current behavior**: How the relevant part of the system works today
|
|
45
46
|
- **Conventions**: Naming, structure, and patterns to follow based on existing code
|
|
46
47
|
- **Ownership conflicts**: Existing feature docs whose `owns:` globs overlap with the proposed feature. Include the conflicting paths and the owning doc name.
|
|
48
|
+
- **Invalidated claims**: One row per existing doc this feature makes wrong — doc path, the claim, why it stops being true. This list seeds the plan's **Doc Obligations** ledger, so it is the research finding most likely to survive into an artifact; "none" is a real answer and says the feature is genuinely additive.
|
|
47
49
|
- **Risks or concerns**: Anything the LLD should address or call out
|
|
48
50
|
|
|
49
51
|
Use the documentation skill's style guide and conventions when structuring your findings — imperative voice, ASCII diagrams for flows, function signatures over implementations, concise.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "delivery",
|
|
3
3
|
"name": "delivery",
|
|
4
|
-
"version": "0.1
|
|
4
|
+
"version": "0.2.1",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
8
8
|
".vscode/settings.json"
|
|
9
9
|
],
|
|
10
10
|
"seeds": [],
|
|
11
|
-
"digest": "
|
|
11
|
+
"digest": "a2c8df3022bd"
|
|
12
12
|
}
|
|
@@ -4,14 +4,16 @@ Record. Use for: every implementation plan. Plans are created here directly with
|
|
|
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
|
|
|
7
|
-
|
|
7
|
+
**Doc Obligations is the one ledger the plan's author writes.** Deriving tests from behavior is judgment, which is why `testing` owns that section and it is marked never-hand-author; resolving Proposed Changes' file paths to the feature docs that own them is a **lookup** against the ownership index already injected at session start. Different work, different rule — fill it yourself, while the touch list is fresh.
|
|
8
|
+
|
|
9
|
+
The **`Gates:`** line is machine-read: the compliance hook greps exactly the forms below, and implementation edits are blocked while a segment reads `pending`. Each gate skill rewrites only its own segment when it runs — `boundary` to `Boundary: passed YYYY-MM-DD` or `Boundary: blocked YYYY-MM-DD`; `testing` (plan-gate mode) to `Test-plan: written YYYY-MM-DD (N rows)` — the segment label stays `Test-plan`, greppable. The author writes `Docs: mapped YYYY-MM-DD (N docs)` when the Doc Obligations table is filled. Never hand-edit the line to skip a gate.
|
|
8
10
|
|
|
9
11
|
```
|
|
10
12
|
# {Feature Name}
|
|
11
13
|
|
|
12
14
|
**Status:** Draft | In Progress | Complete | Abandoned
|
|
13
|
-
**Gates:** Boundary: pending · Test-plan: pending
|
|
14
|
-
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md)
|
|
15
|
+
**Gates:** Boundary: pending · Test-plan: pending · Docs: pending
|
|
16
|
+
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md) <!-- one line per feature doc this plan implements against; a plan spanning three features names three -->
|
|
15
17
|
**Started:** YYYY-MM-DD
|
|
16
18
|
**Completed:** YYYY-MM-DD <!-- fill when status flips to Complete -->
|
|
17
19
|
|
|
@@ -44,6 +46,18 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
44
46
|
- List which cross-cutting contracts this plan affects (db schema, wire envelope, auth, events, env/config, …)
|
|
45
47
|
- "None" is a valid answer and means the `boundary` check will pass cleanly
|
|
46
48
|
|
|
49
|
+
## Doc Obligations
|
|
50
|
+
|
|
51
|
+
<!-- One row per feature doc whose `owns:` globs intersect the Proposed Changes above — resolve
|
|
52
|
+
them against the injected ownership index. Hand-authored: this is a lookup, not research.
|
|
53
|
+
Amendable while the plan is open; discharged at Completion. -->
|
|
54
|
+
|
|
55
|
+
| Doc | Claim that changes | `owns:` still accurate? |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `docs/features/{feature}.md` | what it says today that this plan makes false | yes / no — new paths to add |
|
|
58
|
+
|
|
59
|
+
**"None" is valid** — a plan touching only unowned paths owes no doc update, and says so explicitly. It is not a free pass: `boundary` builds its own touch list from the same Proposed Changes and reports docs this table missed.
|
|
60
|
+
|
|
47
61
|
## Implementation Steps
|
|
48
62
|
|
|
49
63
|
1. Concrete, ordered, testable
|
|
@@ -60,7 +74,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
60
74
|
|
|
61
75
|
- [ ] Implementation complete
|
|
62
76
|
- [ ] Verification gate passed — every Test Obligations row discharged (satisfied / owes nothing / blocked → backlog), gate run date and results noted here
|
|
63
|
-
- [ ]
|
|
77
|
+
- [ ] Every Doc Obligations row discharged — **updated** / **owes nothing** (with the reason) / **blocked** (→ backlog item, so the debt outlives the frozen plan)
|
|
64
78
|
- [ ] Changelog entry created in `docs/history/changelog/`, carrying the gate's results
|
|
65
79
|
- [ ] Plan marked `Status: Complete`, **Completed:** date filled
|
|
66
80
|
|
|
@@ -66,7 +66,7 @@ Three peer modes plus a Completion step — enter wherever the user's thinking a
|
|
|
66
66
|
**On Plan Completion:**
|
|
67
67
|
|
|
68
68
|
1. Freeze the plan — `Status: Complete`, fill the Completed date. The file is now frozen.
|
|
69
|
-
2.
|
|
69
|
+
2. **Discharge the plan's Doc Obligations ledger — every row, into exactly one outcome**: **updated**, **owes nothing** (with the reason), or **blocked** (→ backlog). For each row's doc: flip `status: active` if it was `draft`, extend it in place with the how-it-works sections, confirm its `owns:` globs against the actual components. The ledger, not memory, says how many docs this plan owes.
|
|
70
70
|
3. The `boundary` skill must already have gated this plan before its first implementation step — see Ownership, Boundaries & Documentation.
|
|
71
71
|
|
|
72
72
|
**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.
|
|
@@ -33,6 +33,7 @@ This tells you what already exists, what's adjacent, how detailed the LLD should
|
|
|
33
33
|
4. **Current state** — Understand how the system works today in the area being specified
|
|
34
34
|
5. **Dependencies** — Map what this feature touches and what depends on it
|
|
35
35
|
6. **Ownership conflicts** — Compare the new feature's intended code paths against existing feature docs' `owns:` globs. Report overlaps (two docs claiming the same paths at equal specificity).
|
|
36
|
+
7. **Invalidation** — a different question from conflict, and the one that gets missed. A conflict is two docs claiming one glob; an invalidation is **one existing doc whose stated behavior this feature makes false** — it may own entirely different paths and still be wrong once this ships. For every doc whose territory this feature touches or whose described flow it changes, name the specific claim that stops being true.
|
|
36
37
|
|
|
37
38
|
## What You Return
|
|
38
39
|
|
|
@@ -44,6 +45,7 @@ Structure your findings as:
|
|
|
44
45
|
- **Current behavior**: How the relevant part of the system works today
|
|
45
46
|
- **Conventions**: Naming, structure, and patterns to follow based on existing code
|
|
46
47
|
- **Ownership conflicts**: Existing feature docs whose `owns:` globs overlap with the proposed feature. Include the conflicting paths and the owning doc name.
|
|
48
|
+
- **Invalidated claims**: One row per existing doc this feature makes wrong — doc path, the claim, why it stops being true. This list seeds the plan's **Doc Obligations** ledger, so it is the research finding most likely to survive into an artifact; "none" is a real answer and says the feature is genuinely additive.
|
|
47
49
|
- **Risks or concerns**: Anything the LLD should address or call out
|
|
48
50
|
|
|
49
51
|
Use the documentation skill's style guide and conventions when structuring your findings — imperative voice, ASCII diagrams for flows, function signatures over implementations, concise.
|
|
@@ -57,8 +57,12 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
|
|
|
57
57
|
|
|
58
58
|
## Suggested plan amendments
|
|
59
59
|
## Missing plan subsections
|
|
60
|
+
## Docs the plan's ledger missed
|
|
61
|
+
| Feature doc | Owned path in the touch list | In Doc Obligations? |
|
|
60
62
|
```
|
|
61
63
|
|
|
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
|
+
|
|
62
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.
|
|
63
67
|
|
|
64
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 these exact forms — implementation edits stay blocked while the segment reads `pending`. A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
|
|
@@ -4,14 +4,16 @@ Record. Use for: every implementation plan. Plans are created here directly with
|
|
|
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
|
|
|
7
|
-
|
|
7
|
+
**Doc Obligations is the one ledger the plan's author writes.** Deriving tests from behavior is judgment, which is why `testing` owns that section and it is marked never-hand-author; resolving Proposed Changes' file paths to the feature docs that own them is a **lookup** against the ownership index already injected at session start. Different work, different rule — fill it yourself, while the touch list is fresh.
|
|
8
|
+
|
|
9
|
+
The **`Gates:`** line is machine-read: the compliance hook greps exactly the forms below, and implementation edits are blocked while a segment reads `pending`. Each gate skill rewrites only its own segment when it runs — `boundary` to `Boundary: passed YYYY-MM-DD` or `Boundary: blocked YYYY-MM-DD`; `testing` (plan-gate mode) to `Test-plan: written YYYY-MM-DD (N rows)` — the segment label stays `Test-plan`, greppable. The author writes `Docs: mapped YYYY-MM-DD (N docs)` when the Doc Obligations table is filled. Never hand-edit the line to skip a gate.
|
|
8
10
|
|
|
9
11
|
```
|
|
10
12
|
# {Feature Name}
|
|
11
13
|
|
|
12
14
|
**Status:** Draft | In Progress | Complete | Abandoned
|
|
13
|
-
**Gates:** Boundary: pending · Test-plan: pending
|
|
14
|
-
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md)
|
|
15
|
+
**Gates:** Boundary: pending · Test-plan: pending · Docs: pending
|
|
16
|
+
**Spec:** [docs/features/{feature}.md](../../features/{feature}.md) <!-- one line per feature doc this plan implements against; a plan spanning three features names three -->
|
|
15
17
|
**Started:** YYYY-MM-DD
|
|
16
18
|
**Completed:** YYYY-MM-DD <!-- fill when status flips to Complete -->
|
|
17
19
|
|
|
@@ -44,6 +46,18 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
44
46
|
- List which cross-cutting contracts this plan affects (db schema, wire envelope, auth, events, env/config, …)
|
|
45
47
|
- "None" is a valid answer and means the `boundary` check will pass cleanly
|
|
46
48
|
|
|
49
|
+
## Doc Obligations
|
|
50
|
+
|
|
51
|
+
<!-- One row per feature doc whose `owns:` globs intersect the Proposed Changes above — resolve
|
|
52
|
+
them against the injected ownership index. Hand-authored: this is a lookup, not research.
|
|
53
|
+
Amendable while the plan is open; discharged at Completion. -->
|
|
54
|
+
|
|
55
|
+
| Doc | Claim that changes | `owns:` still accurate? |
|
|
56
|
+
| --- | --- | --- |
|
|
57
|
+
| `docs/features/{feature}.md` | what it says today that this plan makes false | yes / no — new paths to add |
|
|
58
|
+
|
|
59
|
+
**"None" is valid** — a plan touching only unowned paths owes no doc update, and says so explicitly. It is not a free pass: `boundary` builds its own touch list from the same Proposed Changes and reports docs this table missed.
|
|
60
|
+
|
|
47
61
|
## Implementation Steps
|
|
48
62
|
|
|
49
63
|
1. Concrete, ordered, testable
|
|
@@ -60,7 +74,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
60
74
|
|
|
61
75
|
- [ ] Implementation complete
|
|
62
76
|
- [ ] Verification gate passed — every Test Obligations row discharged (satisfied / owes nothing / blocked → backlog), gate run date and results noted here
|
|
63
|
-
- [ ]
|
|
77
|
+
- [ ] Every Doc Obligations row discharged — **updated** / **owes nothing** (with the reason) / **blocked** (→ backlog item, so the debt outlives the frozen plan)
|
|
64
78
|
- [ ] Changelog entry created in `docs/history/changelog/`, carrying the gate's results
|
|
65
79
|
- [ ] Plan marked `Status: Complete`, **Completed:** date filled
|
|
66
80
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nurix/etna",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.58",
|
|
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": "
|
|
45
|
+
"etnaFingerprint": "411f905588e3"
|
|
46
46
|
}
|