@nurix/etna 0.20.29 → 0.20.30
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/code/CLAUDE.md +4 -4
- package/data/harnesses/code/agents/bookkeeper.md +2 -2
- package/data/harnesses/code/agents/change-review.md +3 -3
- package/data/harnesses/code/agents/lld-mode.md +3 -3
- package/data/harnesses/code/agents/maintenance.md +22 -19
- package/data/harnesses/code/agents/polygraph-finder.md +3 -3
- package/data/harnesses/code/agents/polygraph.md +4 -4
- package/data/harnesses/code/agents/retro.md +1 -1
- package/data/harnesses/code/codex/agents/bookkeeper.toml +7 -3
- package/data/harnesses/code/codex/agents/change-review.toml +3 -3
- package/data/harnesses/code/codex/agents/lld-mode.toml +3 -3
- package/data/harnesses/code/codex/agents/maintenance.toml +60 -37
- package/data/harnesses/code/codex/agents/polygraph-finder.toml +6 -2
- package/data/harnesses/code/codex/agents/polygraph.toml +4 -4
- package/data/harnesses/code/codex/agents/retro.toml +1 -1
- package/data/harnesses/code/docs/structure.md +15 -15
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/lib/ownership.mjs +12 -13
- package/data/harnesses/code/hooks/lib/sweep.mjs +1 -1
- package/data/harnesses/code/skills/documentation/SKILL.md +17 -27
- package/data/harnesses/code/skills/documentation/references/frontmatter.md +56 -62
- package/data/harnesses/code/skills/documentation/references/style-guide.md +2 -2
- package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/docs-readme.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/doctrine.md +2 -2
- package/data/harnesses/code/skills/documentation/templates/feature.md +3 -4
- package/data/harnesses/code/skills/documentation/templates/package.md +2 -3
- package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/system.md +2 -4
- package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +4 -4
- package/data/harnesses/delivery/agents/lld-mode.md +3 -3
- package/data/harnesses/delivery/agents/maintenance.md +22 -19
- package/data/harnesses/delivery/agents/retro.md +1 -1
- package/data/harnesses/delivery/codex/agents/lld-mode.toml +3 -3
- package/data/harnesses/delivery/codex/agents/maintenance.toml +60 -37
- package/data/harnesses/delivery/codex/agents/retro.toml +1 -1
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/documentation/SKILL.md +17 -27
- package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +56 -62
- package/data/harnesses/delivery/skills/documentation/references/style-guide.md +2 -2
- package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +2 -2
- package/data/harnesses/delivery/skills/documentation/templates/feature.md +3 -4
- package/data/harnesses/delivery/skills/documentation/templates/package.md +2 -3
- package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/system.md +2 -4
- package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +4 -4
- package/data/harnesses/etna/agents/change-review.md +3 -3
- package/data/harnesses/etna/agents/lld-mode.md +3 -3
- package/data/harnesses/etna/agents/maintenance.md +22 -19
- package/data/harnesses/etna/agents/retro.md +1 -1
- package/data/harnesses/etna/codex/agents/change-review.toml +3 -3
- package/data/harnesses/etna/codex/agents/lld-mode.toml +3 -3
- package/data/harnesses/etna/codex/agents/maintenance.toml +60 -37
- package/data/harnesses/etna/codex/agents/retro.toml +1 -1
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/documentation/SKILL.md +17 -27
- package/data/harnesses/etna/skills/documentation/references/frontmatter.md +56 -62
- package/data/harnesses/etna/skills/documentation/references/style-guide.md +2 -2
- package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +1 -1
- package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/doctrine.md +2 -2
- package/data/harnesses/etna/skills/documentation/templates/feature.md +3 -4
- package/data/harnesses/etna/skills/documentation/templates/package.md +2 -3
- package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/system.md +2 -4
- package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +4 -4
- package/package.json +2 -2
|
@@ -21,7 +21,7 @@ You distill refinement history into documentation and harness feedback. Your inp
|
|
|
21
21
|
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
22
22
|
|
|
23
23
|
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
24
|
-
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the
|
|
24
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the files each feature doc speaks for (source headers naming it, and its transitional `owns:` region globs; glob `docs/features/`).
|
|
25
25
|
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
26
26
|
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
27
27
|
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
@@ -31,7 +31,7 @@ Parse these from the user's prompt; use the default when unstated.
|
|
|
31
31
|
|
|
32
32
|
1. If `./docs/memory/change-review.md` exists, read it for historical velocity snapshots, prior risk-zone flags, known concentration risks, and the project's **Module Taxonomy** / **Feature Taxonomy**.
|
|
33
33
|
2. If a CSV from a prior run already exists at the project root (`change-review-YYYY-MM-DD.csv`), prefer it as input and **skip Phase 1** — re-classify only when the requested window changed.
|
|
34
|
-
3. Build the ownership map
|
|
34
|
+
3. Build the ownership map — consult the injected ownership index (`glob → doc · module · objects · status`), or read each changed file's path header for the document it names, falling back to each feature doc's transitional `owns:` globs — to map churn to owning feature docs and their `module:` labels.
|
|
35
35
|
|
|
36
36
|
---
|
|
37
37
|
|
|
@@ -196,7 +196,7 @@ For each module with high churn (top quartile in the 1m window), check how contr
|
|
|
196
196
|
|
|
197
197
|
- Does its code own cross-cutting contract surfaces (schema/data access, wire handlers, auth/authz, event dispatch, env/config readers)? Skim the module's files to judge — contract-heavy churn is where silent breakage lives.
|
|
198
198
|
- Is the module's owning feature doc up to date? (cross-reference with the maintenance agent's last drift check if available)
|
|
199
|
-
- Do the module's
|
|
199
|
+
- Do the module's source files name a document in their headers, or fall under a feature doc's transitional `owns:` glob?
|
|
200
200
|
|
|
201
201
|
Flag as a risk zone: high churn × contract-heavy × low doc coverage.
|
|
202
202
|
|
|
@@ -219,7 +219,7 @@ Per module, list which authors made the most commits in the 3-month window. Surf
|
|
|
219
219
|
- **Risk zones**: top 5 high-churn modules that own contract-heavy surfaces, with the specific contracts at risk named
|
|
220
220
|
- **Stabilization signals**: modules where review overhead can decrease
|
|
221
221
|
- **Concentration risks**: bus-factor and review-coverage flags
|
|
222
|
-
- **Recommendations**: prioritized list — typically "run the `boundary` skill on changes touching X", "add
|
|
222
|
+
- **Recommendations**: prioritized list — typically "run the `boundary` skill on changes touching X", "add header pointers naming a feature doc to the files under Y", "spread reviews of Z across more authors"
|
|
223
223
|
|
|
224
224
|
### Update tracking
|
|
225
225
|
|
|
@@ -17,7 +17,7 @@ Map the documentation landscape — what exists, what is adjacent, how detailed
|
|
|
17
17
|
2. Locate the repo's feature-doc layer from `structure.md` — the standard shape is `./docs/features/`, but a repo may document components under their own subject folders. Read that layer's index if it has one; otherwise glob for docs carrying `owns:` frontmatter
|
|
18
18
|
3. If `./docs/memory/lld-mode.md` exists (or the legacy `./docs/memory/spec-mode.md`), read it for feature doc inventory, ownership conflict zones, and lessons from previous research
|
|
19
19
|
4. Read 1-2 existing feature LLDs from that layer to calibrate format and depth
|
|
20
|
-
5. Consult the **injected ownership index** (the generated `glob → doc · module ·
|
|
20
|
+
5. Consult the **injected ownership index** (the generated `glob → doc · module · objects · status` map — computed from source headers and the transitional `owns:` region globs) to build the ownership map. It is the source of truth for what code paths are already spoken for; a source file's path header names its document directly. If the index isn't present in context, glob the docs tree (excluding `docs/history/`) and read the `owns:` frontmatter of every doc that declares it.
|
|
21
21
|
|
|
22
22
|
## What You Research
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ Map the documentation landscape — what exists, what is adjacent, how detailed
|
|
|
26
26
|
3. **Affected modules** — Identify what files, routes, components, and data flows are relevant
|
|
27
27
|
4. **Current state** — Understand how the system works today in the area being specified
|
|
28
28
|
5. **Dependencies** — Map what this feature touches and what depends on it
|
|
29
|
-
6. **Ownership conflicts** — Compare the new feature's intended code paths against existing
|
|
29
|
+
6. **Ownership conflicts** — Compare the new feature's intended code paths against the documents those paths already reach — the documents their source headers name, and existing transitional `owns:` region globs. Report overlaps: paths another document already speaks for, or two region globs at equal specificity.
|
|
30
30
|
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.
|
|
31
31
|
|
|
32
32
|
## What You Return
|
|
@@ -38,7 +38,7 @@ Structure your findings as:
|
|
|
38
38
|
- **Affected modules**: Files, routes, components that will be involved
|
|
39
39
|
- **Current behavior**: How the relevant part of the system works today
|
|
40
40
|
- **Conventions**: Naming, structure, and patterns to follow based on existing code
|
|
41
|
-
- **Ownership conflicts**: Existing
|
|
41
|
+
- **Ownership conflicts**: Existing documents that already speak for the proposed feature's paths (by source header or transitional region glob). Include the conflicting paths and the owning doc name.
|
|
42
42
|
- **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.
|
|
43
43
|
- **Risks or concerns**: Anything the LLD should address or call out
|
|
44
44
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# dropped Claude tools: Read, Glob, Grep, Edit, Write, Bash
|
|
2
2
|
name = "maintenance"
|
|
3
|
-
description = "The single docs steward. Default behavior is the docs-vs-code coherence audit — detects and fixes docs drifting from code (stale docs, broken ownership, unowned source paths, architecture/backlog drift). An additive **baseline mode** layers
|
|
3
|
+
description = "The single docs steward. Default behavior is the docs-vs-code coherence audit — detects and fixes docs drifting from code (stale docs, broken ownership, unowned source paths, architecture/backlog drift). An additive **baseline mode** layers reconcile on top: when the repo's `harness-version` marker is missing or behind — **or its documents are behind their genre's current schema even though the folder tree is not** — it converges `docs/` to the installed harness (scaffold the standard tree, fold dissolved-shape artifacts forward, converge every truth document to its template's current schema while leaving frozen records alone, stamp the version, propose modules) before running the audit. Mode is auto-selected from the marker. Run weekly, after major changes, or to baseline/upgrade a repo. Cross-cutting contract analysis is the `boundary` skill (`check` for plans, `scan` for diffs) — it derives contracts dynamically from source; there are no persisted boundary docs to audit. Triggers on \"run maintenance\", \"docs health\", \"baseline this repo\", \"reconcile the harness\", \"upgrade the harness\", \"is this repo on the current harness\", \"/maintenance\"."
|
|
4
4
|
developer_instructions = '''
|
|
5
5
|
|
|
6
6
|
# Maintenance Agent
|
|
@@ -26,9 +26,9 @@ Decide the mode once, up front, from the version marker — then run.
|
|
|
26
26
|
| behind on minor/patch | **probe first**, below |
|
|
27
27
|
| equal to installed | **audit only** (the default spine) |
|
|
28
28
|
|
|
29
|
-
**The probe.** Run the Step B2 detection
|
|
29
|
+
**The probe.** Run the Step B2 **and B2b** detection passes read-only: if any `*.bkp.*` file sits under `docs/` (a fold awaiting its pass), **or** any **scaffolded file** in the target tree is missing (`docs/README.md`, `docs/structure.md`, `docs/history/CHANGELOG.md`, `docs/history/backlog.md`, `docs/memory/main.md`), **or B2b finds truth documents behind their genre's current schema**, the shape *did* change ⇒ **baseline mode**. Only when the probe finds nothing ⇒ re-stamp the version (no reshape), then audit.
|
|
30
30
|
|
|
31
|
-
|
|
31
|
+
**The third clause is not optional, and it is the one that used to be missing.** A repo can hold the current folder tree, every scaffold present, and still have every document in it written to a schema two minors old — because a genre's shape lives in its template, not in the directory layout. Probing only for absent scaffolds meant such a repo re-stamped its version and declared itself current, which is how a stamp comes to certify a tree nobody converged. **The version marker asserts the documents match the installed harness, not merely that the folders do.**
|
|
32
32
|
|
|
33
33
|
> **Never probe on a missing folder.** Git does not track empty directories, so an unused folder is absent on every clone — reading that as drift puts the repo in baseline mode *forever*. Only the five scaffolded files above are shape signals; every folder in the target tree is created on first use.
|
|
34
34
|
3. **Precondition for baseline mode:** a root `CLAUDE.md` must exist. If absent, **refuse the reshape** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconciling against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a hard gate on the audit.
|
|
@@ -42,24 +42,35 @@ Decide the mode once, up front, from the version marker — then run.
|
|
|
42
42
|
|
|
43
43
|
## Part A — Coherence audit (always runs)
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
Ownership is **computed, never typed**, per the `documentation` skill's `references/frontmatter.md`: a document names the objects it designs (`objects:`), and each source file's path header names the document that speaks for it. Until the harness's ownership scan switches to those edges, it reads a **transitional `owns:` region glob** on each owning document — the same source the SessionStart ownership index derives from today. There is no `docs/routing.md` and no precomputed file to regenerate; you rebuild the map from the source headers and the transitional globs.
|
|
46
46
|
|
|
47
47
|
### Step 1: Build the ownership map
|
|
48
48
|
|
|
49
49
|
1. Read `docs/structure.md` for the authority map.
|
|
50
|
-
2.
|
|
51
|
-
3.
|
|
50
|
+
2. Read each source file's path header for the `docs/…` path it names — the header pointer, the authored edge on the code's side.
|
|
51
|
+
3. Glob the docs tree for markdown carrying frontmatter, ignoring `*.bkp.*` files (installer backups awaiting the fold) and anything under `docs/history/` (frozen records quote retired globs as provenance). For each, parse `objects:`, `module:` and any transitional `owns:` region globs.
|
|
52
|
+
4. Build the map: path → the document its header names; where a header names none, the narrowest transitional glob that matches. Where the two disagree, report both — never pick one silently.
|
|
52
53
|
|
|
53
|
-
**Architecture-first fallback.** If no doc carries `owns:` yet (a fresh-baseline repo can carry thousands of LOC and zero feature docs), drive this pass's ownership/drift surface off `docs/architecture/**` file-references instead — they become the **primary** ownership map for Steps 2–5. The
|
|
54
|
+
**Architecture-first fallback.** If no source header names a document and no doc carries `owns:` yet (a fresh-baseline repo can carry thousands of LOC and zero feature docs), drive this pass's ownership/drift surface off `docs/architecture/**` file-references instead — they become the **primary** ownership map for Steps 2–5. The computed map becomes primary the moment any header or feature doc names ownership — this is a fallback, not a replacement.
|
|
54
55
|
|
|
55
56
|
### Step 2: Validate ownership
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
Across the header pointers and the transitional globs:
|
|
58
59
|
|
|
59
|
-
-
|
|
60
|
-
-
|
|
60
|
+
- **Header pointers:** a header naming a document that does not exist is remediation — correct the path. A source file whose header names no document, inside a region an owning document speaks for, is reported as a header to add, never invented.
|
|
61
|
+
- **Transitional globs:** verify each matches existing files; report globs matching nothing, deleted paths, and orphaned docs. A file-level `owns:` list is reduced to its region globs (remediation, not a question); the files it dropped are reported where their headers name no document.
|
|
62
|
+
- **Retired keys:** `applies:` and `keywords:` are removed wherever found (remediation); a doctrine the removed `applies:` named stays named in the document's Scope section.
|
|
63
|
+
- Flag **equal-specificity overlaps** — two feature docs whose transitional `owns:` globs claim the same paths at the same specificity (an ambiguous owner). `node .claude/hooks/check-ownership.mjs` reports these mechanically alongside dead globs (`overlaps()` in `lib/ownership.mjs`); a glob at strictly higher specificity carving out of a broader `**` is the designed layering and is never flagged. Surface a real overlap as a question — narrowing someone's glob is an author's call, not remediation.
|
|
61
64
|
- **Stamp `type:` where missing.** Every doc carries a `type:` genre key (enum = the `documentation` skill's template names); docs predating the key are stamped mechanically — the genre is readable from placement and shape (a `docs/features/` doc is `type: feature`, an AD is `type: architecture-decision`). Stamping is remediation, not a question; an ambiguous genre is backlogged instead.
|
|
62
65
|
|
|
66
|
+
**Then validate the doc→doc edge.** `node .claude/hooks/check-ownership.mjs` and the session-injected **doc edge index** carry `verifies:` and its generated inverse; read the edge index and check two things:
|
|
67
|
+
|
|
68
|
+
- **Dangling edges.** A `verifies:` naming a doc that does not exist is remediation, not a question — fix the path, or drop the edge when its target was deleted deliberately. The generated index marks these `← TARGET MISSING`.
|
|
69
|
+
- **Checklists with no `verifies:`.** Every `docs/tests/` file names the doc whose promises it proves. A checklist without one is unreachable — nothing implicates it when its subject moves — so it is the single highest-value backfill in the tree, and it is mechanical wherever a same-named feature doc exists (`docs/tests/auth.md` → `docs/features/auth.md`). Where the name does not match, ask rather than guess.
|
|
70
|
+
- **Doctrine with no `objects:`.** A `docs/architecture/common/` document that names no objects is reachable by nothing: the closure that links a doctrine to the surfaces it governs runs through the objects both name. Report the list; naming a doctrine's objects is its author's call.
|
|
71
|
+
|
|
72
|
+
**Never author an inverse to fix a gap.** A doc listing its own verifiers or consumers is a defect — the inverse is generated. If the index looks wrong, the frontmatter at the consuming end is what is wrong.
|
|
73
|
+
|
|
63
74
|
For each code symbol or path a doc explicitly **names** (function/export/route/type):
|
|
64
75
|
|
|
65
76
|
- Verify it resolves in the code, independent of git-churn — Step 3's churn gate is blind to churn-free false claims.
|
|
@@ -75,17 +86,15 @@ Also check the **env contract** when the repo declares a canonical `.env.example
|
|
|
75
86
|
|
|
76
87
|
Run `git log --since="2 weeks ago" --name-only --pretty=format:"%h %s"` to find changed source files. For each changed file:
|
|
77
88
|
|
|
78
|
-
- Match against the
|
|
79
|
-
- If
|
|
89
|
+
- Match against the map from Step 1 (the header pointer first, then the narrowest transitional glob) → identify the owning doc.
|
|
90
|
+
- If neither names a document → flag as **unowned**.
|
|
80
91
|
- If an owner exists → compare last-modified dates (`git log -1 --format="%ci" -- <path>`), flag docs where code changed more recently (14-day threshold).
|
|
81
92
|
|
|
82
93
|
**Audit priority.** Rank the docs to inspect by their `last-reviewed:` frontmatter (optional key): never-stamped first, then oldest-first. A doc reviewed last week rarely needs a re-read; one never stamped is the likeliest to have drifted.
|
|
83
94
|
|
|
84
95
|
### Step 4: Check architecture & backlog
|
|
85
96
|
|
|
86
|
-
**Unowned paths.** Compare the repo's actual top-level source directories (derive them — the top-level dirs that contain code, or the roots named across the
|
|
87
|
-
|
|
88
|
-
**Stale greenfield self-label.** If `structure.md` asserts the repo is greenfield — _"No source code or feature docs exist yet"_ or similar — **but a real source tree exists** (the derived source roots above are non-empty, e.g. a populated `packages/` of real workspaces), the self-label has gone stale. Raise it as a question (e.g. `structure.md says "No source code exists yet" but packages/ holds 5 workspaces — confirm the greenfield label should be retired`).
|
|
97
|
+
**Unowned paths.** Compare the repo's actual top-level source directories (derive them — the top-level dirs that contain code, or the roots named across the headers and the transitional globs; do not assume `src/`) against the map. Report directories whose files no header and no transitional glob reaches.
|
|
89
98
|
|
|
90
99
|
**Architecture drift.** Grep `docs/architecture/` for file-path references. Verify referenced paths still exist. Remove or update stale references.
|
|
91
100
|
|
|
@@ -99,7 +108,7 @@ For each stale doc: update the doc directly when the drift is clear (renamed fun
|
|
|
99
108
|
|
|
100
109
|
For each feature doc you verified accurate or updated this pass, stamp `last-reviewed:` in its frontmatter with today's date (add the key if absent). Never write review dates into the body — it's frontmatter metadata only.
|
|
101
110
|
|
|
102
|
-
For unowned code
|
|
111
|
+
For an unowned code **region**, append: `- **[P2]** No feature doc owns \`{dir}/\` — discovered by maintenance` (`{dir}` = the actual unowned source directory). The target is **every region has an owner**, never every file: an individual shared file that several features import is expected to be unowned, because its authority is the contract it exposes rather than any one consumer. Report a directory that no doc's region covers; never mint a row for a shared file, and never propose closing a gap by adding a file glob to whichever doc happens to import it.
|
|
103
112
|
|
|
104
113
|
**Declined realignment.** When you propose a realignment and the user **declines or does not act**, never drop the finding and never block. Append it to `docs/history/backlog.md` as `- **[P0–P3]** <finding> — discovered by maintenance`, priority = the finding's own severity **on the same P0–P3 scale as code items** — never a segregated "compliance" section, never auto-relegated to the lowest tier. Record once: dedupe against existing entries; if already present, leave it.
|
|
105
114
|
|
|
@@ -107,7 +116,7 @@ For unowned code paths, append: `- **[P2]** No feature doc owns \`{dir}/\` — d
|
|
|
107
116
|
|
|
108
117
|
### Step 6: Report & update tracking
|
|
109
118
|
|
|
110
|
-
1.
|
|
119
|
+
1. Append today's row to `docs/history/health-log.md` — **append to the end**, never date-sorted into the middle. Rows are positional: one may say "the row above is…", and an inserted row silently breaks that reference. A Health Log entry is a **generated row, not a narrative essay**: one line — date · counts (stale docs fixed, dead globs, unowned paths, backlog items created) · links to anything that needs a human.
|
|
111
120
|
2. Update `docs/memory/maintenance.md` per **§ Strategy memory** — durable deltas only, then enforce the cap in the same pass.
|
|
112
121
|
3. Report findings: stale docs, broken ownership, unowned code, architecture drift, backlog health.
|
|
113
122
|
|
|
@@ -122,11 +131,11 @@ Baseline mode converges the repo's `docs/` to the **installed** harness shape, t
|
|
|
122
131
|
```
|
|
123
132
|
docs/
|
|
124
133
|
├── README.md ✱ # Documentation root — quick links, section index
|
|
125
|
-
├── structure.md
|
|
134
|
+
├── structure.md # Harness-owned authority map — the installer writes it on every refresh; you stamp only `harness-version`
|
|
126
135
|
├── architecture/ # Cross-module design + steering layer
|
|
127
136
|
│ │ # domain-model, glossary, non-goals, references, open-questions
|
|
128
137
|
│ └── decisions/ # Architecture Decisions (ADs — one per subject, updated in place; journey in each AD's Decision Changelog)
|
|
129
|
-
├── features/ # Feature specs — the only first-class doc unit (flat; ownership
|
|
138
|
+
├── features/ # Feature specs — the only first-class doc unit (flat; ownership computed from each doc's `objects:` and the source headers)
|
|
130
139
|
│ └── {group}/ # browse-only subfolder for grouping; NEVER a module; may carry a Readme.md
|
|
131
140
|
├── operations/ # Setup, development, deployment, CI/CD
|
|
132
141
|
│ └── bookkeeping.md # the shared doc-sync work queue (hook-appended, bookkeeper-drained, walled at commit) — author-created, never scaffolded; treat rows as live work, never as drift
|
|
@@ -138,7 +147,6 @@ docs/
|
|
|
138
147
|
│ ├── plans/ # Implementation plans (Status field required)
|
|
139
148
|
│ ├── migrations/ # One-shot migration/upgrade runbooks (YYYY-MM-DD-{slug}.md; outcome-stamped then frozen)
|
|
140
149
|
│ ├── journal.md # Append-only mid-execution knowledge capture (one line per fact; resolves by landing in its owning doc) — author-created, never scaffolded
|
|
141
|
-
│ ├── sessions/ # Per-session gate logs (YYYY-MM-DD-{sid}.md) — machinery-written records, never drained, never edited down; created by the first gate event, never scaffolded
|
|
142
150
|
│ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
|
|
143
151
|
│ ├── research/ # Deep-research records ({topic}/ — README.md synthesis + findings.md + sources.md); frozen, cited, owns no code
|
|
144
152
|
│ └── backlog.md ✱ # Tracked work items by priority (P0-P3)
|
|
@@ -147,9 +155,9 @@ docs/
|
|
|
147
155
|
└── tests/ # Behavioral test checklists ({feature}.md, step → **Assert**), derived at plan Completion via the `documentation` skill; author-maintained
|
|
148
156
|
```
|
|
149
157
|
|
|
150
|
-
**✱ marks the
|
|
158
|
+
**✱ marks the scaffolded files — the only paths a baseline creates, and the only shape signals.** `docs/structure.md` is not one of them: the installer owns it and rewrites it on every install or refresh, so a missing or hand-edited `structure.md` means the harness needs refreshing (`npx @nurix/etna`), never a scaffold from a template — and its body is never converged, only its `harness-version` field stamped. Every **folder** in this tree is created on first use and is simply absent until it holds a file; git cannot track an empty directory, so a missing folder is never evidence of drift and is never scaffolded to satisfy the shape. Its role is already in `docs/structure.md`; a repo's own notes about legacy folders go in `docs/README.md` § Notes for this repository.
|
|
151
159
|
|
|
152
|
-
There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillars/`**, **no `docs/boundaries/`**. Code ownership
|
|
160
|
+
There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillars/`**, **no `docs/boundaries/`**. Code ownership is computed from `objects:` and source headers, with a transitional `owns:` region glob; a module is a `module:` label, not a folder; boundaries are diagnosed from source; brainstorm records live in `docs/research/` (active) and `docs/history/brainstorms/` (harvested).
|
|
153
161
|
|
|
154
162
|
> Brainstorm records are **author-created, never scaffolded**; legacy active folders carry the older `-brainstorming/` suffix — treat both spellings as canonical. **Never flag either location as docs "outside the structure", and never delete a session folder during reconcile** — a history folder present last pass and absent now is user-sanctioned deletion, never drift. Keep each folder's `Readme.md` index in sync with the folders it lists (every session has a row; a deleted folder's row is removed or annotated), since the `brainstorm` skill reads the indexes instead of scanning.
|
|
155
163
|
|
|
@@ -165,39 +173,51 @@ Detecting and folding old-shape artifacts is what makes a baseline more than a f
|
|
|
165
173
|
|
|
166
174
|
| If you find (old shape) | Fold to (current shape) |
|
|
167
175
|
| --- | --- |
|
|
168
|
-
| a persisted `docs/routing.md` ownership map | migrate each File-Pattern row's ownership into the owning feature doc's `owns:` frontmatter (Pattern → an `owns:` glob; Module column → the doc's `module:` label), then **delete `docs/routing.md`** |
|
|
169
|
-
| feature docs carrying `owns`/`touches`/`depends_on` legacy frontmatter | collapse to the single `owns:` key (drop `touches`/`depends_on`; their paths fold into `owns:` if the doc genuinely owns them, else drop) |
|
|
170
|
-
| a `docs/modules/{m}/` tree | move each module's `features/` flat into `docs/features/` with the module name as a `module:` tag on each doc; fold module-local `pillars/`/prose into `docs/architecture/`; delete the `docs/modules/` tree |
|
|
171
|
-
| repo-wide `docs/pillars/` | cross-module doctrine → `docs/architecture/`; delete the folder |
|
|
172
|
-
| `docs/boundaries/` (legacy persisted boundaries) | delete — boundary analysis is a plan-time diagnostic (the `boundary` skill reads contracts fresh from source); fold any human-authored knowledge (external consumers, intent, accepted exceptions) into `docs/architecture/` |
|
|
173
|
-
| `docs/OWNERSHIP_INDEX.md` (legacy derived ownership index) | delete — ownership is the union of feature `owns:` frontmatter, surfaced by the generated index |
|
|
174
|
-
| `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
|
|
175
|
-
| `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
|
|
176
|
-
| `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
|
|
177
|
-
| `docs/architecture/adr/` (legacy folder name), or `ADR-NNN-*.md` records anywhere under `docs/architecture/` | **rename to the AD genre.** The folder becomes `docs/architecture/decisions/`; each record file `ADR-NNN-{slug}.md` becomes `AD-NNN-{slug}.md`, keeping its number and slug. Inside each record, update the retired vocabulary — "ADR", "Architecture Decision Record", and any supersession framing ("once accepted, an ADR is never edited; a later ADR supersedes it") — to the AD model: one AD per subject, **updated in place**, its journey confined to a `Decision Changelog` tail. A record's **reasoning is never rewritten** by a reconcile; only its genre vocabulary, its own title/id, and paths it cites. The folder's `Readme.md` is an **index, not a record** — reframe its genre description while preserving authored content such as a candidate-decision list verbatim. Repoint live references **inside `docs/`**, including one AD citing another; leave frozen records' links as point-in-time. A live reference **outside** your write scope — most often the root `README.md`, which you never overwrite — cannot be repointed: record it as a backlog item naming the file and line rather than leaving the residue silent |
|
|
178
|
-
| a legacy `docs/brainstorm/{topic}/`, a singular `docs/history/brainstorm/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
|
|
179
176
|
| `*.bkp.*` files under `docs/` (the installer's first-contact backups of the project's pre-existing files) | **fold the content, then delete the backup.** Classify each backup's content by nature and land it in the current shape — a backed-up changelog's rows into `docs/history/CHANGELOG.md` and per-entry files, a backed-up structure/readme's real claims into the scaffolded truth doc, a backed-up feature doc's content merged into its sibling (or adopted whole if the sibling is a pristine seed). Content is folded, never discarded silently; what cannot be classified goes to the backlog with the backup kept. When the fold lands, delete the `.bkp` file |
|
|
180
177
|
| `*.bkp.*` files at the repo root or in config (`CLAUDE.bkp.md`, `.prettierrc.bkp.json`, …) | **never merge these.** Top-level config is harness-owned by design; list each one to the user as their call, and leave the file in place |
|
|
181
178
|
| no `harness-version` in `structure.md` | stamp it (Step B4) |
|
|
179
|
+
| `docs/tests/` checklists carrying **no frontmatter** (the shape before the graph — the genre was exempt) | **backfill `type: checklist` + `verifies:`.** Mechanical where a same-named feature or UX doc exists; where the name does not match, list the checklist to the user with your best candidate and let them confirm. This is the row that upgrades a repo from a tree of files to a graph — without it every checklist in an older repo stays unreachable, and nothing detects that |
|
|
180
|
+
| docs carrying a retired `applies:` or `keywords:` key, or a file-level `owns:` list | **remove the retired key; reduce `owns:` to its region globs.** Mechanical: a doctrine the removed `applies:` named stays named in the document's Scope; the files a reduced `owns:` dropped are reported where their headers name no document (`documentation` skill, `references/frontmatter.md`) |
|
|
181
|
+
|
|
182
|
+
**The support window: three past minor versions.** The fold table covers shapes at most three minors behind the installed harness — which today means the rows above, because every older dissolved construct (`docs/routing.md`, `docs/modules/`, pillars, the Refinement Ledger, the ADR genre, legacy brainstorm folders, …) predates the window. An older shape is **reported, never improvised**: name what the probe found, point the user at etna's dated migration runbooks (`docs/history/migrations/` in the forge), and recommend a fresh baseline over an archaeological fold — a repo more than three minors behind re-baselines rather than migrates.
|
|
183
|
+
|
|
184
|
+
### Step B2b — Converge documents to their genre's current schema
|
|
185
|
+
|
|
186
|
+
B2 folds artifacts whose **shape dissolved** — a file in the wrong place or the wrong genre. This step handles the other axis, and it is the one that silently rots a repo that otherwise looks current: a document in the **right folder with the right name** whose *internal* schema is behind. A changelog entry missing three of its seven required fields, a checklist with no `verifies:` edge, a feature doc predating `applies:`, an AD on the old key vocabulary — none of these move a folder, so nothing structural detects them, and a repo can pass every scaffold check while no document in it matches the installed harness.
|
|
187
|
+
|
|
188
|
+
**Read the schema from the `documentation` skill's templates, never from memory.** The template is the contract; your recollection of it is a version of unknown age. For each genre, take the required frontmatter keys and required sections from the template file itself, then check the repo's documents of that genre against them.
|
|
189
|
+
|
|
190
|
+
**The two natures split the treatment, and the split is absolute.**
|
|
191
|
+
|
|
192
|
+
| Nature | Genres | Treatment |
|
|
193
|
+
| --- | --- | --- |
|
|
194
|
+
| **Truth document** | features, ux, architecture, operations, `docs/tests/` checklists, READMEs (never `structure.md`, which the installer owns) | **Converge in place.** These state what is true now, so rewriting them to the current schema is not revision, it is the genre working as designed. Add missing frontmatter keys, add missing required sections, rename keys the template renamed |
|
|
195
|
+
| **Record** | plans, changelog entries, migration runbooks, brainstorm records | **Never rewritten.** A completed plan and a committed entry are frozen — immutability begins at commit, and a record edited to match a newer schema stops being evidence of what happened. Report non-conformance; repair only the **living index** that points at the record (an absent `docs/history/CHANGELOG.md` row is an index defect, not a record defect, and is backfilled with a note saying so) |
|
|
196
|
+
|
|
197
|
+
**Never invent content to satisfy a field.** A frozen changelog entry missing `Skills:` is missing the *judgement* that field carries, and no later session holds it — writing one is fabrication wearing a schema's clothes. Report it, backlog the pattern if it recurs, and leave the entry alone. The same restraint applies to a truth document: a genre's new section that needs knowledge the repo does not contain is raised as a question, not filled with plausible prose.
|
|
198
|
+
|
|
199
|
+
**Scale gate — confirm once, not per file.** Count the convergences first and fold them into B3's single reconcile table as `Fold` rows. Where the count is large (roughly **20+ files, or any change spanning more than one genre**), state the counts per genre in that table and take B3's one approval for the whole set — a per-file prompt turns a mechanical upgrade into an interrogation and gets abandoned halfway, which leaves a tree half-converged and a version marker that lies about it. Where a genre's convergence is judgement-heavy rather than mechanical, split it out as its own row so approval is informed rather than bundled.
|
|
182
200
|
|
|
183
201
|
### Step B3 — Present the reconcile plan, then execute
|
|
184
202
|
|
|
185
203
|
Table: `| File | Action | From | To | Reason |` (actions: `Move`, `Merge into {target}`, `Delete`, `Keep`, `Create`, `Fold`). For a fresh baseline this is mostly `Create`; for an upgrade it is mostly `Fold`/`Move`. Ask once: **"Approve this reconcile?"** — you own this interaction (the `documentation` skill is a library and has none).
|
|
186
204
|
|
|
187
|
-
On approval, execute: create the folder structure; move/fold/merge/delete per the plan; add `Status:` to plan files; for each feature doc, derive and write its `owns:` globs (+ `module:` label + `
|
|
205
|
+
On approval, execute: create the folder structure; move/fold/merge/delete per the plan; apply B2b's schema convergences to the truth documents (records are reported, never rewritten); add `Status:` to plan files; for each feature doc, derive and write its `owns:` globs (+ `module:` label + `objects:`) from the source it describes, and each checklist's `verifies:` edge, by calling the `documentation` skill's **frontmatter derivation**; merge scattered backlogs into `docs/history/backlog.md`; fix links broken by moves.
|
|
188
206
|
|
|
189
|
-
Scaffold missing mandated files **by calling the `documentation` skill for each template** — you orchestrate, the skill supplies templates: `docs/
|
|
207
|
+
Scaffold missing mandated files **by calling the `documentation` skill for each template** — you orchestrate, the skill supplies templates: `docs/history/CHANGELOG.md`, `docs/history/backlog.md`, `docs/memory/main.md`, `docs/operations/setup.md` (when the repo has a lockfile and a runnable root script; **never a second first-run doc** — propose a rename with a `note:` row if one exists under another name), and the repo-root `README.md` (an outward opening in a user's terms from the charter and vision documents, then orientation and routing filled from the manifests, the ownership index and the root scripts — **never overwrite an existing root README**).
|
|
190
208
|
|
|
191
209
|
### Step B4 — Stamp the version
|
|
192
210
|
|
|
193
211
|
Write `harness-version: <installed version>` (the semver from `.claude/harness.json`) into `docs/structure.md` frontmatter. This single field is the repo's baseline-and-version sentinel — there is no second marker (no `epoch`, no `docs/memory/index.md` "is-baselined" check).
|
|
194
212
|
|
|
213
|
+
**Stamp only what converged.** The marker asserts the repo's *documents* match the installed harness, not merely its folders — so it is written after B2b has run and its truth-document convergences have landed. Where B2b's set was too large to finish in one pass, stamp nothing and say what remains: a version marker ahead of the tree it describes is worse than an absent one, because every later probe trusts it and skips the work.
|
|
214
|
+
|
|
195
215
|
### Step B5 — Module proposal
|
|
196
216
|
|
|
197
217
|
Modules are **labels, declared, never inferred from physical layout**. Derive the repo's candidate bounded contexts directly from the code and docs: distinct wire surfaces (who owns routes/handlers), schema/data-access ownership, entry points and process units, plus any contexts `docs/architecture/` already names.
|
|
198
218
|
|
|
199
|
-
- Propose the derived contexts as candidate `module:` labels. For each, list which existing feature docs would carry that label (by
|
|
200
|
-
- **Propose — don't force.** Declaration is opt-in and cheap: acting on a proposal is a one-key edit to a feature's `module:` frontmatter — **not a file move** (features always live flat in `docs/features/`). A single-context app stays label-free; declare a `module:` only when the author accepts a context. A module is tied to code
|
|
219
|
+
- Propose the derived contexts as candidate `module:` labels. For each, list which existing feature docs would carry that label (by which of the context's files name them in their headers, or fall under their transitional globs).
|
|
220
|
+
- **Propose — don't force.** Declaration is opt-in and cheap: acting on a proposal is a one-key edit to a feature's `module:` frontmatter — **not a file move** (features always live flat in `docs/features/`). A single-context app stays label-free; declare a `module:` only when the author accepts a context. A module is tied to code through the documents that carry its label — the files their headers and transitional globs reach — **layout-blind** (a workspace is not a module; one workspace may hold several contexts; one context may span workspaces).
|
|
201
221
|
|
|
202
222
|
### Step B6 — Compact the agent memory
|
|
203
223
|
|
|
@@ -216,6 +236,9 @@ Apply the **§ Strategy memory** retirement procedure to `docs/memory/maintenanc
|
|
|
216
236
|
- **Enforce the memory cap on every run** (§ Strategy memory) — you are its only writer, so no one else can do it.
|
|
217
237
|
- **A clean report is valid** — do not invent issues.
|
|
218
238
|
- **Declarative, idempotent.** Re-running baseline mode on a current repo reshapes nothing — a second pass is just the audit plus the module proposal. Converge to the current shape; never replay a version ladder; never reconstruct a past shape.
|
|
239
|
+
- **Brownfield extraction (operator-ruled 2026-08-19).** When baseline mode meets a repo with a real source tree and few or no feature docs, the module *proposal* is not enough — run the extraction pass: produce feature docs for the recognized modules (docs/features/, full frontmatter: `objects:` · a transitional `owns:` region glob · `module:` · `status:` · `last-reviewed:` · `type: feature` · `derivation: "extracted (baseline YYYY-MM-DD, nustack graph + source read)"`), plus the architecture, tests, and operations layers. Use the `nustack-graph` skill where installed — localize through the index before reading; the docs record intent, the index answers facts. **Every extracted feature doc carries a `## History & Ownership` section** — top contributors with recency, churn posture, and bus-factor notes, dated "as of YYYY-MM-DD" (operator ruling: this section is mandatory in extraction output even though doc-lint flags dated narrative in truth docs; the findings are accepted for now, and a future harness version may retire the section in favor of live index pointers). `status:` is evidence-graded: `deprecated` only when history shows the area dead, never by guess. Scale by fan-out (one extraction lane per module, a completeness critic over the result) rather than one long cold read.
|
|
240
|
+
- **Diagrams ride the baseline (operator-ruled 2026-08-24).** Whenever baseline mode produces or converges the architecture layer, draw two ASCII diagrams from the real source, each in its own fenced code block: (1) an **architecture diagram** in the system-design/architecture doc — the actual processes, entry points, and wire surfaces as boxes, the calls/queues/files between them as labelled arrows; (2) a **DB ER diagram** wherever the repo declares a relational schema (DDL, migrations, an ORM schema) — one box per table listing its key columns, FK edges drawn to the table they reference, cardinality on the edge; it lands in the domain-model doc, or `docs/architecture/data-model.md` when none exists. Box-drawing characters (`┌─┐│└┘├┤`), width ≤ 100 columns. Derived only from what the code declares — a diagram never invents a component the source does not show, and a repo with no relational schema gets **no** ER diagram rather than an imagined one. Diagrams are truth-document sections: later baselines and audits converge them in place like any other section.
|
|
241
|
+
- **Tool tiers.** The SessionStart context names each manifest-declared tool with its tier; calibrate the run to it, never stall on it. **Present-fresh** (`Tool: nustack 0.9.0`): use it — localize every question through `nustack graph` before reading source, and never run an index step first: the family re-indexes a stale store before it answers, so the only freshness decision left is the deliberate `--no-refresh`. **Present-stale** (below the catalog minimum): still use it, but note the version gap and the upgrade command in the run report — a stale contract may lack answer shapes the skill assumes. **Absent** (`Tool: nustack MISSING`): fall back to the cold method (Glob/Grep/read), state in the run report that the tool was absent and give the install command — degraded output is acceptable, silent degradation is not.
|
|
219
242
|
- **One sentinel.** `docs/structure.md` `harness-version` is the only baseline/version marker.
|
|
220
243
|
- **Modules are labels, layout-blind.** Seed from the code's bounded contexts; never from `pnpm-workspace.yaml`/workspace walls. Propose, don't force; acting is a `module:` tag, never a folder.
|
|
221
244
|
- **You orchestrate docs; the `documentation` skill supplies templates.** It is a library — never expect it to baseline.
|
|
@@ -19,7 +19,7 @@ You distill refinement history into documentation and harness feedback. Your inp
|
|
|
19
19
|
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
20
20
|
|
|
21
21
|
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
22
|
-
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the
|
|
22
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the files each feature doc speaks for (source headers naming it, and its transitional `owns:` region globs; glob `docs/features/`).
|
|
23
23
|
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
24
24
|
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
25
25
|
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "etna",
|
|
3
3
|
"name": "etna",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.29",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -14,5 +14,5 @@
|
|
|
14
14
|
"origin": "https://cdn.nustack.io",
|
|
15
15
|
"track": "latest"
|
|
16
16
|
},
|
|
17
|
-
"digest": "
|
|
17
|
+
"digest": "26630babb6e4"
|
|
18
18
|
}
|
|
@@ -13,7 +13,7 @@ Document contracts and architecture, not implementation details. Signatures and
|
|
|
13
13
|
|
|
14
14
|
## Where a file's documentation lives
|
|
15
15
|
|
|
16
|
-
**In `docs/`, never in the file's comments** — and this skill is the half of that rule that makes it safe. A source file carries a repo-relative path header of two or three present-tense sentences and one third-person sentence above each non-obvious function; the shape is the harness's `CLAUDE.md` § File Structure, which is canonical and is not restated here. What lands **here** is everything that shape displaces: design rationale, the alternatives weighed, the measurement behind a constant, the reason an obvious-looking change is wrong.
|
|
16
|
+
**In `docs/`, never in the file's comments** — and this skill is the half of that rule that makes it safe. A source file carries a repo-relative path header of two or three present-tense sentences and one third-person sentence above each non-obvious function; the shape is the harness's `CLAUDE.md` § File Structure, which is canonical and is not restated here. That header's `docs/…` path is also the file's edge into the knowledge graph: the header pointer names the document that speaks for the file, which is how ownership is computed ([`references/frontmatter.md`](references/frontmatter.md)). What lands **here** is everything that shape displaces: design rationale, the alternatives weighed, the measurement behind a constant, the reason an obvious-looking change is wrong.
|
|
17
17
|
|
|
18
18
|
**Cutting a comment is a move, not a deletion.** A claim taken out of a source file is owed one of two things before the cut is done, and the choice is per claim, not per file:
|
|
19
19
|
|
|
@@ -92,8 +92,8 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
92
92
|
| Document feature/module (LLD) | [`templates/feature.md`](templates/feature.md) |
|
|
93
93
|
| Document data flow / state / Redux | [`templates/feature.md`](templates/feature.md) — they are sections of the feature doc |
|
|
94
94
|
| Document a workspace package (`docs/architecture/packages/{package}.md`) | [`templates/package.md`](templates/package.md) — the **residual** owner of `packages/{name}/**`: its manifest, build, entry, layout and every behavior no system or feature doc claims at higher specificity |
|
|
95
|
-
| Document one concern the platform handles everywhere (`docs/architecture/common/{concern}.md`) — authentication, storage, the API protocol | [`templates/doctrine.md`](templates/doctrine.md) — the design and its principles, no mechanism; owns no code, and surfaces
|
|
96
|
-
| Document one system spanning packages (`docs/architecture/systems/{system}.md`) | [`templates/system.md`](templates/system.md) — one machine end to end
|
|
95
|
+
| Document one concern the platform handles everywhere (`docs/architecture/common/{concern}.md`) — authentication, storage, the API protocol | [`templates/doctrine.md`](templates/doctrine.md) — the design and its principles, no mechanism; owns no code, and the surfaces bound by it are the ones that design or touch the objects it governs |
|
|
96
|
+
| Document one system spanning packages (`docs/architecture/systems/{system}.md`) | [`templates/system.md`](templates/system.md) — one machine end to end, the objects it owns or moves. Not a screen — a system doc written as a giant feature doc is the mistake it prevents |
|
|
97
97
|
| Create/update changelog entry | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record — one per unit of work; carries the refinement fields, frozen inside its commit, distilled by the `retro` agent) |
|
|
98
98
|
| Create/update plan | [`templates/plan.md`](templates/plan.md) (record) |
|
|
99
99
|
| Record/revise architecture decision | [`templates/architecture-decision.md`](templates/architecture-decision.md) — one AD per subject; revisions update it in place |
|
|
@@ -118,7 +118,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
118
118
|
| Add to protected files | [`templates/protected-files.md`](templates/protected-files.md) |
|
|
119
119
|
| Create/update root README (outward opening in a user's terms, then orientation and routing for the team and agents — no install, stack, tree or chrome) | [`templates/root-readme.md`](templates/root-readme.md) |
|
|
120
120
|
| Scaffold a standard doc (docs index, CHANGELOG, backlog, memory) | [`templates/Readme.md`](templates/Readme.md) — the index names each scaffold file; `structure.md` is the installer's, never scaffolded |
|
|
121
|
-
| Derive
|
|
121
|
+
| Derive or update a document's frontmatter (`objects:`, the header pointers, the transitional `owns:`) | [`references/frontmatter.md`](references/frontmatter.md) |
|
|
122
122
|
| Update existing doc | § Editing an existing doc (below) |
|
|
123
123
|
| Instruction file (`CLAUDE.md`, a rule, an agent, skill prose) | [`references/instruction-style.md`](references/instruction-style.md) — not these templates; every-load prose stays lean, and the present-tense rule still applies |
|
|
124
124
|
| Author or restructure a **skill** (fit, triggers, shape, anatomy, shipping) | The skill-authoring field guide — the `etna` repo (`nurixlabs/etna`), folder `docs/playbooks/skills/`, chapters `00`–`13`. **No etna checkout available ⇒ ask the user for access to the etna repo, or proceed from first principles** with [`references/instruction-style.md`](references/instruction-style.md) governing the prose. This row is the only place the playbook is referenced |
|
|
@@ -132,7 +132,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
132
132
|
|
|
133
133
|
1. **Determine the nature first.** A frozen record (a `Status: Complete`/`Abandoned` plan, a changelog entry, an executed runbook) is never edited — write a new dated record that links back.
|
|
134
134
|
2. **Preserve structure, not violations.** Keep the doc's existing section shape, but every section touched sheds history narration, progress markers, and stale tripwires on the way through (§ Present tense, always).
|
|
135
|
-
3. **Stamp and re-derive.** A substantive feature-doc update bumps `last-reviewed:`; if the
|
|
135
|
+
3. **Stamp and re-derive.** A substantive feature-doc update bumps `last-reviewed:`; if the objects it designs changed, update `objects:`, and remove any retired key on the way through ([`references/frontmatter.md`](references/frontmatter.md)).
|
|
136
136
|
|
|
137
137
|
---
|
|
138
138
|
|
|
@@ -157,27 +157,17 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
157
157
|
|
|
158
158
|
---
|
|
159
159
|
|
|
160
|
-
## Frontmatter
|
|
161
|
-
|
|
162
|
-
**Frontmatter is compulsory on every document this skill authors
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
without claiming it. A behavioral checklist (`docs/tests/`) carries
|
|
172
|
-
`type: checklist` and `verifies:` — the doc whose promises it proves. An acceptance-criteria doc
|
|
173
|
-
(`docs/acceptance/`) carries `type:` and `status:`.
|
|
174
|
-
|
|
175
|
-
**The frontmatter is where the docs tree's edges live**, and a doc that declares none is a node
|
|
176
|
-
nothing can reach: no change implicates it, so it rots without the rot being detectable. Deriving
|
|
177
|
-
every edge — `owns:` from code, `verifies:` and `applies:` from the docs they answer to — is
|
|
178
|
-
[`references/frontmatter.md`](references/frontmatter.md), and it carries the rule the whole graph
|
|
179
|
-
rests on: **declare once at the consuming end, generate every inverse.** Every doc create or
|
|
180
|
-
update, and the `maintenance` agent's baseline pass, route there.
|
|
160
|
+
## Frontmatter
|
|
161
|
+
|
|
162
|
+
**Frontmatter is compulsory on every document this skill authors**: `type:` (the genre) on every document, plus its genre's keys. There is no frontmatter-less genre. The keys follow the knowledge layer (`docs/architecture/systems/knowledge-layer.md` § Documents and code), and this skill stays in step with it:
|
|
163
|
+
|
|
164
|
+
- **`objects:` is a document's edge into the graph:** the product objects it designs, by their register names. Feature, system, package, doctrine and UX documents carry it, with `type:` and `status:`; a feature may add `module:`.
|
|
165
|
+
- **The code's edge is the source file's header pointer:** authored on the code's side, naming the document that holds the file's fuller account. Which document speaks for a path is computed from the pointers and the object closure, never typed into the document.
|
|
166
|
+
- **`owns:` is transitional:** region globs only, kept solely because the harness's ownership scan still reads it, and removed everywhere in the change that switches the scan. Never a list of files.
|
|
167
|
+
- **`applies:` is retired:** a document's governing doctrine is computed through the objects both name, and its Scope section names it for people.
|
|
168
|
+
- **`verifies:` stays on a behavioral checklist:** the document whose promises it proves.
|
|
169
|
+
|
|
170
|
+
Keys by genre, each key's rules, the retired keys, and the one rule the graph rests on (declare once, at the consuming end; generate every inverse) are [`references/frontmatter.md`](references/frontmatter.md). Every document create or update, and the `maintenance` agent's baseline pass, route there.
|
|
181
171
|
|
|
182
172
|
---
|
|
183
173
|
|
|
@@ -188,7 +178,7 @@ update, and the `maintenance` agent's baseline pass, route there.
|
|
|
188
178
|
| `templates/` | One file per template, indexed by [`Readme.md`](templates/Readme.md) — feature (LLD), changelog, plan, AD, steering docs, API reference, environment registry, operations procedure, migration runbook, protected files, READMEs, and the baseline scaffolds |
|
|
189
179
|
| `references/style-guide.md` | The writing-style authority: the eight principles, depth per genre, the outside-in shape and stability test, noun-phrase labels and third-person voice, the owning document's body and footer, the two-natures tense rules, diagrams, headings, reference-document detail |
|
|
190
180
|
| `references/instruction-style.md` | The style for instruction files (`CLAUDE.md`, rules, agents, skill prose) — the every-line test, armor vs. narration, voice, negative space |
|
|
191
|
-
| `references/frontmatter.md` |
|
|
181
|
+
| `references/frontmatter.md` | Frontmatter by genre, in step with the knowledge layer: `objects:`, the header pointer, the transitional `owns:`, the retired `applies:`, `verifies:` |
|
|
192
182
|
| `references/untemplated.md` | How to write a document no template covers (nature, placement, shape) + the co-authoring workflow |
|
|
193
183
|
| `references/examples.md` | Good vs bad documentation examples |
|
|
194
184
|
| `scripts/doc-lint.mjs` | Mechanical checks over written docs (tense narration, dates, stubs, redirects) — run over changed docs before finishing |
|