@nurix/etna 0.20.46 → 0.20.48
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 +1 -1
- package/data/harnesses/code/agents/maintenance.md +5 -1
- package/data/harnesses/code/codex/agents/maintenance.toml +5 -1
- package/data/harnesses/code/docs/structure.md +13 -10
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/compliance.mjs +13 -672
- package/data/harnesses/code/hooks/hooks.json +1 -1
- package/data/harnesses/code/hooks/lib/backlog-detector.mjs +30 -10
- package/data/harnesses/code/hooks/lib/frozen.mjs +28 -11
- package/data/harnesses/code/hooks/lib/gates.mjs +633 -0
- package/data/harnesses/code/hooks/lib/ownership.mjs +4 -14
- package/data/harnesses/code/hooks/lib/protection-gate.mjs +208 -0
- package/data/harnesses/code/hooks/lib/records-door.mjs +12 -21
- package/data/harnesses/code/hooks/lib/repo.mjs +33 -7
- package/data/harnesses/code/hooks/lib/session-log.mjs +1 -2
- package/data/harnesses/code/hooks/lib/state.mjs +4 -10
- package/data/harnesses/code/hooks/lib/walls.mjs +2 -1
- package/data/harnesses/code/hooks/protection.mjs +53 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +11 -1
- package/data/harnesses/code/skills/documentation/references/style-guide.md +2 -1
- package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +3 -3
- package/data/harnesses/code/skills/documentation/templates/Readme.md +3 -2
- package/data/harnesses/code/skills/documentation/templates/doctrine.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/playbook.md +63 -0
- package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +1 -1
- package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +1 -1
- package/data/harnesses/delivery/agents/maintenance.md +5 -1
- package/data/harnesses/delivery/codex/agents/maintenance.toml +5 -1
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/documentation/SKILL.md +11 -1
- package/data/harnesses/delivery/skills/documentation/references/style-guide.md +2 -1
- package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +3 -3
- package/data/harnesses/delivery/skills/documentation/templates/Readme.md +3 -2
- package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/playbook.md +63 -0
- package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +1 -1
- package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +1 -1
- package/data/harnesses/etna/agents/maintenance.md +5 -1
- package/data/harnesses/etna/codex/agents/maintenance.toml +5 -1
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/documentation/SKILL.md +11 -1
- package/data/harnesses/etna/skills/documentation/references/style-guide.md +2 -1
- package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +3 -3
- package/data/harnesses/etna/skills/documentation/templates/Readme.md +3 -2
- package/data/harnesses/etna/skills/documentation/templates/doctrine.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/playbook.md +63 -0
- package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +1 -1
- package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +1 -1
- package/lib/install/plan.mjs +3 -1
- package/package.json +2 -2
package/data/harness-index.json
CHANGED
|
@@ -57,7 +57,7 @@ Three peer modes, then a verification gate and a Completion step — enter where
|
|
|
57
57
|
- **File the request, end the turn — never wait in the container.** Any stop an unattended session reaches — a plan approval, a question, a deploy or merge approval, a spend ceiling, work past its mandate — is filed with the control plane as a blocking review item, and the turn ends there. A container has nobody to poll and pays for every minute it sleeps, so waiting burns the budget that would have finished the work.
|
|
58
58
|
- **The mandate is injected, not inferred.** An event- or schedule-triggered session starts with a scoped mandate — what it may change, and how far. **Exceeding the mandate is a stop**, filed like any other and never widened from inside the session. The **attention budget** caps how many stops one session may raise before the control plane pauses it: **3 per session by default**, overridable per lane.
|
|
59
59
|
- **Run caps end a session; they never stretch it.** An unattended session carries a **spend ceiling** and a **wall-clock ceiling**. Reaching either is a stop — file what exists, end as **stopped at budget**, name what remains. A silent continuation past a cap is **never** permitted.
|
|
60
|
-
- **Hygiene fails open, authority fails closed.** Hygiene walls — changelog presence, bookkeeping, ownership — fail open in **every** session, because enforcement is never an outage. Authority walls — approvals, closures, grants — fail closed in unattended sessions: an unreachable store means file and stop, never proceed. A sign-off bound to a commit is read from the control plane before the gated step it guards, through the control plane's own command line (`nustack review check --commit <sha>`: `0` signed, `1` not signed, `2` unreachable or signed out), and `2` is a stop.
|
|
60
|
+
- **Hygiene fails open, authority fails closed.** Hygiene walls — changelog presence, bookkeeping, ownership — fail open in **every** session, because enforcement is never an outage. Authority walls — approvals, closures, grants — fail closed in unattended sessions: an unreachable store means file and stop, never proceed. Protection's block walls — frozen records, protected files — fail closed in **every** session on Claude Code from v2.1.295: a crashed `protection.mjs` blocks the call, and a timeout allows it. A sign-off bound to a commit is read from the control plane before the gated step it guards, through the control plane's own command line (`nustack review check --commit <sha>`: `0` signed, `1` not signed, `2` unreachable or signed out), and `2` is a stop.
|
|
61
61
|
|
|
62
62
|
---
|
|
63
63
|
|
|
@@ -70,7 +70,7 @@ Across the header pointers and the transitional globs:
|
|
|
70
70
|
|
|
71
71
|
- **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`.
|
|
72
72
|
- **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.
|
|
73
|
-
- **Doctrine with no `objects:`.** A `docs/architecture/
|
|
73
|
+
- **Doctrine with no `objects:`.** A `docs/architecture/doctrine/` or `docs/architecture/playbooks/` 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.
|
|
74
74
|
|
|
75
75
|
**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.
|
|
76
76
|
|
|
@@ -137,6 +137,8 @@ docs/
|
|
|
137
137
|
├── structure.md # Harness-owned authority map — the installer writes it on every refresh; you stamp only `harness-version`
|
|
138
138
|
├── architecture/ # Cross-module design + steering layer
|
|
139
139
|
│ │ # domain-model, glossary, non-goals, references, open-questions
|
|
140
|
+
│ ├── doctrine/ # Doctrine — one `{concern}.md` per concern every product handles; owns no code
|
|
141
|
+
│ ├── playbooks/ # Playbooks — one `{subject}.md` per shape every product builds; owns no code
|
|
140
142
|
│ └── decisions/ # Architecture Decisions (ADs — one per subject, updated in place; journey in each AD's Decision Changelog)
|
|
141
143
|
├── features/ # Feature specs — flat, no subfolders; ownership computed from each doc's `objects:` and the source headers
|
|
142
144
|
├── operations/ # Setup, development, deployment, CI/CD
|
|
@@ -180,6 +182,7 @@ Detecting and folding old-shape artifacts is what makes a baseline more than a f
|
|
|
180
182
|
| no `harness-version` in `structure.md` | stamp it (Step B4) |
|
|
181
183
|
| `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 |
|
|
182
184
|
| 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`) |
|
|
185
|
+
| a `docs/architecture/common/` folder (the doctrine folder's name before `doctrine/`) | **move it to `docs/architecture/doctrine/` with `git mv`, then repoint every reference.** Every markdown link, `objects:`-adjacent path, `Bound by` and Related-documents entry, and every source-file path header that points into `common/` is rewritten to `doctrine/`; frozen records under `docs/history/` keep the old path as provenance. Verify with a search: no reference into `docs/architecture/common/` remains outside `docs/history/` |
|
|
183
186
|
|
|
184
187
|
**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.
|
|
185
188
|
|
|
@@ -231,6 +234,7 @@ Apply the **§ Strategy memory** retirement procedure to `docs/memory/maintenanc
|
|
|
231
234
|
## Rules
|
|
232
235
|
|
|
233
236
|
- **Never delete feature docs** — only update or flag for review.
|
|
237
|
+
- **Never create a doctrine or playbook document.** A baseline folds, moves and converges the ones that exist; content that looks like a new standard goes to the backlog as a proposal for the user (the `documentation` skill § Doctrine and playbooks).
|
|
234
238
|
- **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
|
|
235
239
|
- **Preserve existing doc structure and formatting** when updating.
|
|
236
240
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
@@ -68,7 +68,7 @@ Across the header pointers and the transitional globs:
|
|
|
68
68
|
|
|
69
69
|
- **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`.
|
|
70
70
|
- **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.
|
|
71
|
-
- **Doctrine with no `objects:`.** A `docs/architecture/
|
|
71
|
+
- **Doctrine with no `objects:`.** A `docs/architecture/doctrine/` or `docs/architecture/playbooks/` 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.
|
|
72
72
|
|
|
73
73
|
**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.
|
|
74
74
|
|
|
@@ -135,6 +135,8 @@ docs/
|
|
|
135
135
|
├── structure.md # Harness-owned authority map — the installer writes it on every refresh; you stamp only `harness-version`
|
|
136
136
|
├── architecture/ # Cross-module design + steering layer
|
|
137
137
|
│ │ # domain-model, glossary, non-goals, references, open-questions
|
|
138
|
+
│ ├── doctrine/ # Doctrine — one `{concern}.md` per concern every product handles; owns no code
|
|
139
|
+
│ ├── playbooks/ # Playbooks — one `{subject}.md` per shape every product builds; owns no code
|
|
138
140
|
│ └── decisions/ # Architecture Decisions (ADs — one per subject, updated in place; journey in each AD's Decision Changelog)
|
|
139
141
|
├── features/ # Feature specs — flat, no subfolders; ownership computed from each doc's `objects:` and the source headers
|
|
140
142
|
├── operations/ # Setup, development, deployment, CI/CD
|
|
@@ -178,6 +180,7 @@ Detecting and folding old-shape artifacts is what makes a baseline more than a f
|
|
|
178
180
|
| no `harness-version` in `structure.md` | stamp it (Step B4) |
|
|
179
181
|
| `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
182
|
| 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`) |
|
|
183
|
+
| a `docs/architecture/common/` folder (the doctrine folder's name before `doctrine/`) | **move it to `docs/architecture/doctrine/` with `git mv`, then repoint every reference.** Every markdown link, `objects:`-adjacent path, `Bound by` and Related-documents entry, and every source-file path header that points into `common/` is rewritten to `doctrine/`; frozen records under `docs/history/` keep the old path as provenance. Verify with a search: no reference into `docs/architecture/common/` remains outside `docs/history/` |
|
|
181
184
|
|
|
182
185
|
**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
186
|
|
|
@@ -229,6 +232,7 @@ Apply the **§ Strategy memory** retirement procedure to `docs/memory/maintenanc
|
|
|
229
232
|
## Rules
|
|
230
233
|
|
|
231
234
|
- **Never delete feature docs** — only update or flag for review.
|
|
235
|
+
- **Never create a doctrine or playbook document.** A baseline folds, moves and converges the ones that exist; content that looks like a new standard goes to the backlog as a proposal for the user (the `documentation` skill § Doctrine and playbooks).
|
|
232
236
|
- **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
|
|
233
237
|
- **Preserve existing doc structure and formatting** when updating.
|
|
234
238
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
@@ -15,13 +15,15 @@ docs/
|
|
|
15
15
|
├── README.md # Documentation root — the product in a paragraph, what each folder holds, and the repo's
|
|
16
16
|
│ # own notes. Describes directories, never files or a tree — `ls` is the roster
|
|
17
17
|
├── structure.md # This file — harness-owned authority map; `harness-version` stamped after baseline
|
|
18
|
-
├── architecture/ # The design layer, in
|
|
18
|
+
├── architecture/ # The design layer, in five folders; Readme.md is its summary and names folders only
|
|
19
19
|
│ ├── packages/ # One `{package}.md` per project package: what it is, how it behaves. Speaks
|
|
20
20
|
│ │ # RESIDUALLY for `packages/<pkg>/**` — every file no narrower document speaks for
|
|
21
21
|
│ ├── systems/ # One `{machine}.md` per machine spanning packages. Speaks for its subtrees,
|
|
22
22
|
│ │ # more specific than a package's claim
|
|
23
|
-
│ ├──
|
|
24
|
-
│ │ # the same way everywhere. Owns no code
|
|
23
|
+
│ ├── doctrine/ # The enterprise plane — one `{concern}.md` per concern the platform handles
|
|
24
|
+
│ │ # the same way everywhere, in general form. Owns no code
|
|
25
|
+
│ ├── playbooks/ # One `{subject}.md` per interface or workflow shape every product builds (the shell,
|
|
26
|
+
│ │ # a settings area, a record's lifecycle), in general form. Owns no code
|
|
25
27
|
│ └── decisions/ # ADs — `AD-NNN-{slug}.md`, one per subject, updated in place; the journey lives in
|
|
26
28
|
│ # each file's Decision Changelog tail. Each AD's `description:` and `status:` say
|
|
27
29
|
│ # what it decides and whether it stands; Readme.md describes the folder, never a row per AD
|
|
@@ -62,13 +64,13 @@ docs/
|
|
|
62
64
|
|
|
63
65
|
- **Every document has one of three natures.** A **truth** document states what is true now and is rewritten in place, present tense, with no history in its body. A **record** states what happened, is dated, and is frozen at its terminal status. A **queue** holds work not done yet: rows are appended and deleted when resolved, and nothing else is edited — the backlog, the journal, the bookkeeping queue and `memory/`. Which genre has which nature is the genre registry's; the folders below follow it, with `history/` holding records and two queues.
|
|
64
66
|
- **No index keeps a row per file.** A folder's `Readme.md` describes what the folder holds and how its files are named; each file's `description:` is its own account, and listing the folder is the roster. Nothing appends to an index when a sibling file is added — not the changelog guide, not a decisions, research, brainstorms or release-notes folder.
|
|
65
|
-
- **`docs/architecture/`** is the design layer in
|
|
66
|
-
**`
|
|
67
|
-
**What earns which genre.** A project package earns a `packages/` document — one, always. A machine whose parts sit in several packages, which a reader asks about as one thing, earns a `systems/` document. A **feature** document exists for something a person points at — an address, a command family, a named control — and is cut by the objects it designs, never by the code's routers, tables, plans or packages; a machine nobody navigates to is a `systems/` document even when it owns tables, and a fragment whose central object is declared in a sibling merges into it. A concern handled the same way everywhere is `
|
|
67
|
+
- **`docs/architecture/`** is the design layer in five folders: **`packages/`** (one per project package — what it is and how it behaves), **`systems/`** (one per machine spanning packages), **`doctrine/`** (the enterprise plane), **`playbooks/`** (the shapes every product builds) and **`decisions/`** (the ADs, one per subject, updated in place, each journey confined to that file's Decision Changelog tail).
|
|
68
|
+
**`doctrine/`, `playbooks/` and `decisions/` own no code; `packages/` and `systems/` do.** Ownership is computed, not positional and not typed: a document names the objects it designs in `objects:`, each source file's path header names the document that speaks for it, and the object closure links the two; the more specific claim wins — a feature's beats a system's, a system's beats a package's. Until the ownership scan switches to those edges it reads a transitional `owns:` region glob on each of the three owning genres (the `documentation` skill's `references/frontmatter.md`). **A package document is the residual owner of its tree**, so a package's exhaustive behavior spec is that document, not a feature doc.
|
|
69
|
+
**What earns which genre.** A project package earns a `packages/` document — one, always. A machine whose parts sit in several packages, which a reader asks about as one thing, earns a `systems/` document. A **feature** document exists for something a person points at — an address, a command family, a named control — and is cut by the objects it designs, never by the code's routers, tables, plans or packages; a machine nobody navigates to is a `systems/` document even when it owns tables, and a fragment whose central object is declared in a sibling merges into it. A concern handled the same way everywhere is `doctrine/` and owns nothing; a shape every product's interface or workflow repeats is `playbooks/` and owns nothing. Both are written in general form, and a new one is created only with the user's approval (the `documentation` skill § Doctrine and playbooks) — including the governing-decisions register (fixed product decisions `F-###`, baseline defaults `B-###`, external boundaries, out-of-scope), which is authored doctrine the `boundary` skill never persists to.
|
|
68
70
|
- **`history/research/` is not legacy — it is the installed deep-research genre**, one `{topic}/` folder per research pass in the three-file shape. A record is frozen and cited, owns no code, and is never edited to stay current; a new question gets a new topic folder. Entries that predate the three-file convention — a single file or a single-report folder — are kept as authored.
|
|
69
71
|
- **`docs/features/` is flat — every feature authority is a file, and no subfolder exists.** A subject too large for one file is two files, not a folder: `objects:` and the source headers already state authority, and a nested doc is one the ownership scan and the index rows reach last.
|
|
70
72
|
- **`docs/research/`** holds records, not authorities: its standing-research folders and loose notes ground plans and decisions. The `brainstorm` skill finds a session by its folder name.
|
|
71
|
-
- **`docs/tests/`** holds behavioral test checklists — one `{feature}.md` per surface, written as `- [ ] step` → `- [ ] **Assert**` (how to verify a feature's promised behavior). A checklist is written or updated **at the verification gate, before the driving** — it is the script the real surface is driven against and the menu the pinned suite tests are drawn from, so each behavior section closes with a `> Pinned:` line naming the test that guards it, `driven only` with the reason, or `none yet` with the test it owes. **No section carries a date** — the *event* of driving (its date, environment, evidence, a `FAIL` and the backlog item it raised) belongs to the changelog entry of the unit that drove it. A section a drive cannot reach says `not reachable — {what blocks it}` on its trace line until the blocker is gone. **The gate that drives a checklist maintains it** — retiring dead sections and repairing traces is part of the run, because a checklist owns no code and no ownership glob implicates it. The cross-system testing strategy is doctrine in `architecture/
|
|
73
|
+
- **`docs/tests/`** holds behavioral test checklists — one `{feature}.md` per surface, written as `- [ ] step` → `- [ ] **Assert**` (how to verify a feature's promised behavior). A checklist is written or updated **at the verification gate, before the driving** — it is the script the real surface is driven against and the menu the pinned suite tests are drawn from, so each behavior section closes with a `> Pinned:` line naming the test that guards it, `driven only` with the reason, or `none yet` with the test it owes. **No section carries a date** — the *event* of driving (its date, environment, evidence, a `FAIL` and the backlog item it raised) belongs to the changelog entry of the unit that drove it. A section a drive cannot reach says `not reachable — {what blocks it}` on its trace line until the blocker is gone. **The gate that drives a checklist maintains it** — retiring dead sections and repairing traces is part of the run, because a checklist owns no code and no ownership glob implicates it. The cross-system testing strategy is doctrine in `architecture/doctrine/`. A checklist carries `type: checklist` plus `verifies:`, the doc(s) whose promises it proves; a target is legitimately a feature, a package or a system document, and several values are correct where one checklist proves promises two docs decide.
|
|
72
74
|
**`verifies:` is the load-bearing key, and the filename convention is not a substitute for it.** A same-named file is a coincidence no resolver can trust — it breaks the moment a checklist spans two docs or a feature is renamed. The inverse — which checklists cover a feature — is **generated, never listed in the feature doc**.
|
|
73
75
|
- **`docs/operations/bookkeeping.md`** is the shared doc-sync work queue — hooks append rows, the `bookkeeper` agent drains them, and the commit wall blocks while rows remain. It is **author-created, never scaffolded**, and its rows are **live work, never drift**: a drained row is deleted, so a fully drained file holds no rows at all. Read a waiver's referent before deleting it; deleting the record while the condition survives re-appends the finding as an `auto:` row that fails the wall the waiver passed.
|
|
74
76
|
- **`type:` is a required frontmatter key** on every doc that carries frontmatter — the genre stamp, its values the genre registry's `type:` column (`feature`, `architecture-decision`, `project-memory`, `ux`, `acceptance-criteria`, …). It is tooling metadata like `last-reviewed:` and `status:`: external tooling reads it, sessions **preserve it on edits** and never narrate it in the body. The `maintenance` agent stamps it on docs that lack it. The owning genres (`type: feature`, `type: package`, `type: system`) carry the transitional `owns:` region glob the ownership scan reads until it switches to source headers; `type: doctrine` carries `objects:` and owns no code; the bookkeeping queue carries no block. Docs written by a skill that ships a block (`issue-bridge`'s `type: issue` / `type: triage`) carry it.
|
|
@@ -103,11 +105,12 @@ The `type:` column is the value the document carries; its required keys and sect
|
|
|
103
105
|
| You are adding… | It goes in… | `type:` |
|
|
104
106
|
| --- | --- | --- |
|
|
105
107
|
| A feature document — something a person points at (an address, a command family, a named control), cut by the objects it designs | `features/{feature}.md` (flat) | `type: feature` |
|
|
106
|
-
| What a person sees and can do on a surface (UX behavior) | `features/{surface}-ux.md`, named in the headers of the component files no other document speaks for;
|
|
108
|
+
| What a person sees and can do on a surface (UX behavior) | `features/{surface}-ux.md`, named in the headers of the component files no other document speaks for; a shape every product repeats is a playbook | `type: ux` |
|
|
107
109
|
| A package's behavior document | `architecture/packages/{package}.md`, one per package | `type: package` |
|
|
108
110
|
| A system's behavior document | `architecture/systems/{system}.md`, one per machine | `type: system` |
|
|
109
|
-
| Cross-cutting design (doctrine) | `architecture/
|
|
110
|
-
|
|
|
111
|
+
| Cross-cutting design (doctrine) — with the user's approval, after extending an existing one is ruled out | `architecture/doctrine/{concern}.md` | `type: doctrine` |
|
|
112
|
+
| An interface or workflow shape every product builds (playbook) — with the user's approval, after extending an existing one is ruled out | `architecture/playbooks/{subject}.md` | `type: playbook` |
|
|
113
|
+
| The testing strategy | `architecture/doctrine/testing.md` | `type: testing-strategy` |
|
|
111
114
|
| An Architecture Decision (AD) | `architecture/decisions/AD-NNN-{subject}.md` — one file per subject, updated in place; the journey lives in its Decision Changelog | `type: architecture-decision` |
|
|
112
115
|
| The system at a glance | `architecture/system-design.md` | `type: system-overview` |
|
|
113
116
|
| The domain model | `architecture/domain-model.md` | `type: domain-model` |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"harness": "code",
|
|
3
3
|
"name": "code",
|
|
4
|
-
"version": "3.20.
|
|
4
|
+
"version": "3.20.18",
|
|
5
5
|
"files": [
|
|
6
6
|
".prettierignore",
|
|
7
7
|
".prettierrc.json",
|
|
@@ -29,5 +29,5 @@
|
|
|
29
29
|
"origin": "https://cdn.nustack.io",
|
|
30
30
|
"track": "latest"
|
|
31
31
|
},
|
|
32
|
-
"digest": "
|
|
32
|
+
"digest": "c0808ca0d11e"
|
|
33
33
|
}
|