@nurix/etna 0.20.26 → 0.20.28

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.
Files changed (56) hide show
  1. package/README.md +15 -14
  2. package/bin/etna.js +61 -19
  3. package/data/harness-index.json +1 -1
  4. package/data/harnesses/code/codex/agents/bookkeeper.toml +1 -1
  5. package/data/harnesses/code/harness.json +6 -2
  6. package/data/harnesses/code/hooks/awareness.mjs +50 -2
  7. package/data/harnesses/code/hooks/hooks.json +1 -1
  8. package/data/harnesses/code/hooks/lib/backlog-detector.mjs +82 -0
  9. package/data/harnesses/code/hooks/lib/records-door.mjs +54 -0
  10. package/data/harnesses/code/hooks/mount.mjs +470 -0
  11. package/data/harnesses/code/skills/documentation/SKILL.md +6 -6
  12. package/data/harnesses/code/skills/documentation/references/examples.md +29 -25
  13. package/data/harnesses/code/skills/documentation/references/style-guide.md +211 -335
  14. package/data/harnesses/code/skills/documentation/references/untemplated.md +2 -1
  15. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +33 -17
  16. package/data/harnesses/code/skills/documentation/templates/doctrine.md +15 -16
  17. package/data/harnesses/code/skills/documentation/templates/feature.md +53 -17
  18. package/data/harnesses/code/skills/documentation/templates/handover.md +1 -1
  19. package/data/harnesses/code/skills/documentation/templates/package.md +38 -15
  20. package/data/harnesses/code/skills/documentation/templates/root-readme.md +16 -16
  21. package/data/harnesses/code/skills/documentation/templates/setup.md +1 -1
  22. package/data/harnesses/code/skills/documentation/templates/system.md +37 -15
  23. package/data/harnesses/delivery/harness.json +6 -2
  24. package/data/harnesses/delivery/skills/documentation/SKILL.md +6 -6
  25. package/data/harnesses/delivery/skills/documentation/references/examples.md +29 -25
  26. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +211 -335
  27. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +2 -1
  28. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +33 -17
  29. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +15 -16
  30. package/data/harnesses/delivery/skills/documentation/templates/feature.md +53 -17
  31. package/data/harnesses/delivery/skills/documentation/templates/handover.md +1 -1
  32. package/data/harnesses/delivery/skills/documentation/templates/package.md +38 -15
  33. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +16 -16
  34. package/data/harnesses/delivery/skills/documentation/templates/setup.md +1 -1
  35. package/data/harnesses/delivery/skills/documentation/templates/system.md +37 -15
  36. package/data/harnesses/discover/harness.json +4 -0
  37. package/data/harnesses/discussion/harness.json +4 -0
  38. package/data/harnesses/etna/harness.json +6 -2
  39. package/data/harnesses/etna/skills/documentation/SKILL.md +6 -6
  40. package/data/harnesses/etna/skills/documentation/references/examples.md +29 -25
  41. package/data/harnesses/etna/skills/documentation/references/style-guide.md +211 -335
  42. package/data/harnesses/etna/skills/documentation/references/untemplated.md +2 -1
  43. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +33 -17
  44. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +15 -16
  45. package/data/harnesses/etna/skills/documentation/templates/feature.md +53 -17
  46. package/data/harnesses/etna/skills/documentation/templates/handover.md +1 -1
  47. package/data/harnesses/etna/skills/documentation/templates/package.md +38 -15
  48. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +16 -16
  49. package/data/harnesses/etna/skills/documentation/templates/setup.md +1 -1
  50. package/data/harnesses/etna/skills/documentation/templates/system.md +37 -15
  51. package/data/harnesses/hr/harness.json +4 -0
  52. package/data/harnesses/kb-agi/harness.json +4 -0
  53. package/lib/install/materialize.mjs +51 -23
  54. package/lib/install/mount.mjs +448 -0
  55. package/lib/install/plan.mjs +24 -29
  56. package/package.json +6 -3
@@ -10,5 +10,9 @@
10
10
  "seeds": [],
11
11
  "tools": [],
12
12
  "docsRoot": "docs",
13
+ "mount": {
14
+ "origin": "https://cdn.nustack.io",
15
+ "track": "latest"
16
+ },
13
17
  "digest": "ed9548ee592a"
14
18
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "etna",
3
3
  "name": "etna",
4
- "version": "1.5.27",
4
+ "version": "1.5.28",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -10,5 +10,9 @@
10
10
  "seeds": [],
11
11
  "tools": [],
12
12
  "docsRoot": "docs",
13
- "digest": "bbde0394df6d"
13
+ "mount": {
14
+ "origin": "https://cdn.nustack.io",
15
+ "track": "latest"
16
+ },
17
+ "digest": "6a10dd14cf28"
14
18
  }
@@ -7,7 +7,7 @@ description: "Use when creating or substantively editing ANY markdown doc — in
7
7
 
8
8
  **This skill is a template & generator library, not an orchestrator.** It supplies the templates, the frontmatter-derivation generator, and the co-authoring workflow that _agents_ call to produce individual docs. It does **not** baseline, audit, or reconcile a repo's doc tree — that is the **`maintenance` agent (baseline mode)**, which calls this skill for each template it scaffolds. Reach here to generate _one_ doc from a template; reach for the `maintenance` agent (baseline mode) to bring a whole repo into shape.
9
9
 
10
- Document contracts and architecture, not implementation details. Signatures and API shapes belong in a reference document (an API reference, an environment registry); every other genre states design and promises and leaves mechanism to the code — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments stating why the field is dead now — never where it went or when it dies. Breaking changes belong in changelogs only, not module docs.
10
+ Document contracts and architecture, not implementation details. Signatures and API shapes belong in a reference document (an API reference, an environment registry); every other genre states design and promises and leaves mechanism to the code — never paste full implementations (they rot fast). A diagram sits beside the prose and never replaces it: ASCII for structure at rest, mermaid for behaviour over time (`references/style-guide.md` § Diagrams). Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments stating why the field is dead now — never where it went or when it dies. Breaking changes belong in changelogs only, not module docs.
11
11
 
12
12
  ---
13
13
 
@@ -42,9 +42,9 @@ Document contracts and architecture, not implementation details. Signatures and
42
42
  | "Folded in from the `NuStack-X` repo (2026-06-12)." | "Vendor-connector catalogue; one subpath per vendor." |
43
43
  | "was X, now Y", "the old worker", "Phase 2 softened this", "v1 → v2" | The current fact, with no predecessor named |
44
44
 
45
- The journey — dates, migrations, progress, supersessions — lives only in records (`docs/history/`); when reality changes, a truth document simply becomes correct. The full strip-list and the record-side rules: [`references/style-guide.md`](references/style-guide.md) § The Two Natures — Tense & History.
45
+ The journey — dates, migrations, progress, supersessions — lives only in records (`docs/history/`); when reality changes, a truth document simply becomes correct. The full strip-list and the record-side rules: [`references/style-guide.md`](references/style-guide.md) § The Two Natures — tense and history.
46
46
 
47
- **A date in a truth document is a defect, and the list of exceptions is closed.** Not a softened preference: a truth document carries no dated line at all, because a date answers *when did this happen*, which is a record's question, and a reader who needs the answer is reading the wrong file. The four exceptions, and there are no others: the frontmatter's tooling keys (`last-reviewed:`, `last-updated:`, `rev:` — written by tooling, never by you), an Architecture Decision's **Decision Changelog** tail, `docs/structure.md`'s **Health Log** tail, and a dated path inside a link or code span, which is a *citation* of a record rather than a claim about the present.
47
+ **A date in a truth document is a defect, and the list of exceptions is closed.** Not a softened preference: a truth document carries no dated line at all, because a date answers *when did this happen*, which is a record's question, and a reader who needs the answer is reading the wrong file. The three exceptions, and there are no others: the frontmatter's tooling keys (`last-reviewed:`, `last-updated:`, `rev:` — written by tooling, never by you), an Architecture Decision's **Decision Changelog** tail, and a dated path inside a link or code span, which is a *citation* of a record rather than a claim about the present. The `maintenance` agent's Health Log is a record of its own (`docs/history/health-log.md`), not a tail on a truth document.
48
48
 
49
49
  **Cite a record by what it is, never by when it was.** `the dev reset runbook` links to the file; "the 2026-09-13 reset" states a date the reader must now keep in their head and that goes stale as soon as a second reset happens. The link carries the date in its path, where it belongs, and the prose stays true forever.
50
50
 
@@ -74,9 +74,9 @@ The two guarantees are complementary and both break on mixing: a reader holding
74
74
  - **Indexes describe directories, never files.** `docs/README.md` — the top-level index of the documentation folder — is a description of its directories: one entry per folder saying what the folder holds, who reads it and how its files are named. It carries no file list and no file tree: not a per-file row, not a `├──` tree of files, not a tree at all — `docs/structure.md` is the one place the tree lives, as the authority on placement. The same holds for a `README.md` / `Readme.md` at any level of `docs/`. `ls` is the roster, and the ownership index is how a document is found for a path. A per-file row has to be edited on every add, rename and retirement, so the index's history records roster churn instead of what the index said, and a reader cannot tell when the index itself changed. The only files an index may link are the mandated scaffolds (`structure.md`, `operations/setup.md`, `history/CHANGELOG.md`, `history/backlog.md`, `memory/main.md`) and a sibling folder's own `Readme.md`. `scripts/doc-lint.mjs` blocks the rest as `index-lists-files`, and blocks a tree drawn in a folder index as `index-file-tree`. An inverse (which checklists verify a feature, which docs a folder holds) is generated, never written.
75
75
  - **Truth documents cite records for the _why_, never the _when_.** `Provenance: AD-002` is good; "decided in AD-002 and shipped 2026-06-13" is not. Routing/index docs point only to truth documents as a topic's authority — never a plan or changelog entry as the "read first" source. (An index _of the records themselves_ — a History section listing `plans/`, `changelog/` — is sanctioned.)
76
76
 
77
- **A document is intent and promises; facts are the graph's.** An owning document (feature, package, system) answers why the product is shaped this way and what it promises, and names the objects it designs in `objects:`. Every computable fact — a table's columns and vocabularies, a foreign key and its delete rule, which function writes which column, which route sits behind which guard, which code a refusal answers, which file holds what — is the code graph's to compute (`docs/architecture/systems/knowledge-layer.md`), and a hand-typed copy of it is the defect this rule removes: it reads as authoritative and is wrong the day the code moves. Mechanism stays in the code, reasons stay in the document, and the document points by object and symbol name, never by line number. `doc-lint` blocks the retired mechanism sections in an owning document (`mechanism-section`) and an owning document without `objects:`. `keywords:` is not a key: an object's name is its discovery term. **The body is read by people** — plain English a newcomer reads top to bottom, with code named only at a cross-cutting seam the graph would not lead a reader to from the feature's own files (a middleware, a gate, a hook, a shared store) and every other identifier in the closing **For the agent** footer; the owning genres read Why it exists · How it works · What was decided · What it promises · Known gaps · For the agent (`references/style-guide.md` § Documents are read by people; `doc-lint` warns `body-identifier`, `list-not-prose`, `formula-run`).
77
+ **A document is intent and promises; facts are the graph's.** An owning document (feature, package, system) answers why the product is shaped this way and what it promises, and names the objects it designs in `objects:`. Every computable fact — a table's columns and vocabularies, a foreign key and its delete rule, which function writes which column, which route sits behind which guard, which code a refusal answers, which file holds what — is the code graph's to compute (`docs/architecture/systems/knowledge-layer.md`), and a hand-typed copy of it is the defect this rule removes: it reads as authoritative and is wrong the day the code moves. Mechanism stays in the code, reasons stay in the document, and the document points by object and symbol name, never by line number. `doc-lint` blocks the retired mechanism sections in an owning document (`mechanism-section`) and an owning document without `objects:`. `keywords:` is not a key: an object's name is its discovery term. **The body is scanned by people** — sharp bullets under noun-phrase headings, each a bold noun-phrase label, a colon, then one or two plain sentences; code named only where a person types or sees it, or at a cross-cutting seam the graph would not lead a reader to (a middleware, a gate, a hook, a shared store); every other pointer in the closing **For the agent** footer. The owning genres read Scope · Flows (Flow for a system, Usage for a package) · Decisions · Promises · Gaps · For the agent (`references/style-guide.md` § Labels, § Owning documents — the body and the footer; `doc-lint` warns `body-identifier`, `clause-label` and `second-person`).
78
78
 
79
- **Every document that explains is written from the outside in, and every sentence passes the stability test.** Open on the question and its boundary, then the model with its numbered principles, then the parts and how they relate, then each part's decisions — and stop at the genre's deepest layer: decisions for doctrine, cross-package behaviour for a system, the public contract for a package, the full user-facing behaviour for a feature. A sentence that would have to change when a function is renamed, a file moves, or a route, column or error code changes is the code's, not the document's. The code is the authority on *what*; the document is the authority on *why*, and a disagreement on *why* is a defect to raise. The layers, the test and the per-genre depth table are [`references/style-guide.md`](references/style-guide.md) § Shape — the model first, the detail after.
79
+ **Every document that explains is written from the outside in, and every sentence passes the stability test.** Open on the question and its boundary, then the model with its numbered principles, then the parts and how they relate, then each part's decisions — and stop at the genre's deepest layer: decisions for doctrine, cross-package behaviour for a system, the public contract for a package, the full user-facing behaviour for a feature. A sentence that would have to change when a function is renamed, a file moves, or a route, column or error code changes is the code's, not the document's. The code is the authority on *what*; the document is the authority on *why*, and a disagreement on *why* is a defect to raise. **Every heading and every bold bullet label is a noun phrase** — it names; it has no verb, so it carries no tense, person or voice ("Decisions", never "What was decided"; "Organization user:", never "You already belong to an organization:"), and the sentence after it is third person ("user lands…", never "you land…"). The layers, the test, the label rule and the per-genre depth table are [`references/style-guide.md`](references/style-guide.md) § Shape — the model first, the detail after, and § Labels.
80
80
 
81
81
  **No empty stubs.** Never leave a template section as an empty placeholder — omit any section with nothing real to say (each template declares its required core; everything else is optional). Write an explicit "None" only where the absence itself is information (e.g., a plan's Cross-Module Contracts Affected, an LLD's Ownership Conflicts). An empty table stub reads as "not yet researched"; an omitted section reads as "doesn't apply" — keep those meanings distinct.
82
82
 
@@ -186,7 +186,7 @@ update, and the `maintenance` agent's baseline pass, route there.
186
186
  | File | Use For |
187
187
  | --- | --- |
188
188
  | `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
- | `references/style-guide.md` | Writing rules, formatting conventions, the two-natures tense rules |
189
+ | `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
190
  | `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
191
  | `references/frontmatter.md` | Deriving a feature doc's `objects:` / `owns:` / `module:` / `status:` from code |
192
192
  | `references/untemplated.md` | How to write a document no template covers (nature, placement, shape) + the co-authoring workflow |
@@ -146,37 +146,41 @@ Replaced change-tracking merge with version-based conflict resolution.
146
146
 
147
147
  ---
148
148
 
149
- ## Example 4: Data Flow
149
+ ## Example 4: Flow
150
150
 
151
- ### ❌ Bad: Prose Description
151
+ ### ❌ Bad: Mechanism narrated in a paragraph
152
152
 
153
153
  ```markdown
154
+ ## Data Flow
155
+
154
156
  When the page loads, the useAppInit hook calls the syncData function. This function first fetches data from the server using the API. Then it gets the local data from Redux. After that, it compares versions...
155
157
  ```
156
158
 
157
- ### ✅ Good: Diagram + Key Points
159
+ **Problems:** names a hook, a function and a store that a rename would invalidate (the stability test); runs parallel cases together in one paragraph; gives a scanning reader no label to land on; "Data Flow" is a retired mechanism section.
158
160
 
159
- ```markdown
160
- ## Data Flow
161
+ ### ✅ Good: Labelled bullets, a role-level diagram beside them
161
162
 
162
- ┌─────────────────────────────────────────┐
163
- │ DATA SYNC │
164
- ├─────────────────────────────────────────┤
165
- │ │
166
- │ ┌──────┐ ┌──────┐ ┌──────┐ │
167
- │ │Server│────▶│Merge │────▶│Redux │ │
168
- │ │ API │ │ │ │Store │ │
169
- │ └──────┘ └──────┘ └──────┘ │
170
- │ │ │
171
- │ ▼ │
172
- │ Version Check │
173
- │ │
174
- └─────────────────────────────────────────┘
175
-
176
- **Trigger:** `useAppInit()` on page load
177
-
178
- **Version Rule:** Match → local wins, Mismatch → server wins
163
+ ````markdown
164
+ ## Flows
165
+
166
+ ### Page load
167
+
168
+ - **Fresh data:** the page fetches the server's copy and the local copy on every load; nothing is cached between visits.
169
+ - **Matching versions:** local changes win and are kept.
170
+ - **Mismatched versions:** the server's copy wins and local changes are dropped.
171
+
172
+ ```mermaid
173
+ sequenceDiagram
174
+ participant Page
175
+ participant Server
176
+ participant Store
177
+ Page->>Server: fetch the server's copy
178
+ Page->>Store: read the local copy
179
+ Page->>Store: write the merged copy
179
180
  ```
181
+ ````
182
+
183
+ **Why it works:** every fact is in the bullets, so a reader who greps finds it without the diagram; the labels are noun phrases a scanning reader lands on; the diagram names roles, never a function or a file, so no rename touches it.
180
184
 
181
185
  ---
182
186
 
@@ -242,7 +246,7 @@ The feature doc states only what is:
242
246
  ```markdown
243
247
  ## Export Pipeline
244
248
 
245
- `src/export/run.js` renders every export format from one job queue. Output is
249
+ The exporter renders every export format from one job queue. Output is
246
250
  buffered per job (streaming is out of scope — see `docs/history/backlog.md`).
247
251
  ```
248
252
 
@@ -272,8 +276,8 @@ Extracted export logic from the `reports` worker into `src/export/`.
272
276
  | ---------- | -------------------- | --------------------------- |
273
277
  | Code | Full implementations | Signatures + contracts |
274
278
  | State | Every occurrence | Persistence points only |
275
- | Flows | Prose paragraphs | ASCII diagrams |
279
+ | Flows | Paragraphs naming functions | Labelled bullets in plain words, a role-level diagram beside them |
276
280
  | Changelogs | "Updated X" | Function names + migrations |
277
281
  | Decisions | New doc per revision | One AD per subject, updated in place |
278
282
  | History | Narrated in the doc | Present-tense doc + dated record |
279
- | Length | 100+ lines | 20-40 lines |
283
+ | Length | Padded with mechanism | The genre's own expectation; length is a signal, never a target |