@nurix/etna 0.20.25 → 0.20.27

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 (75) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/code/CLAUDE.md +4 -4
  3. package/data/harnesses/code/agents/bookkeeper.md +1 -1
  4. package/data/harnesses/code/agents/change-review.md +1 -1
  5. package/data/harnesses/code/agents/lld-mode.md +1 -1
  6. package/data/harnesses/code/agents/maintenance.md +7 -9
  7. package/data/harnesses/code/docs/structure.md +133 -71
  8. package/data/harnesses/code/harness.json +4 -4
  9. package/data/harnesses/code/hooks/awareness.mjs +0 -10
  10. package/data/harnesses/code/hooks/lib/ownership.mjs +4 -2
  11. package/data/harnesses/code/hooks/lib/sweep.mjs +4 -8
  12. package/data/harnesses/code/skills/documentation/SKILL.md +22 -11
  13. package/data/harnesses/code/skills/documentation/references/examples.md +29 -25
  14. package/data/harnesses/code/skills/documentation/references/frontmatter.md +3 -3
  15. package/data/harnesses/code/skills/documentation/references/style-guide.md +211 -292
  16. package/data/harnesses/code/skills/documentation/references/untemplated.md +4 -2
  17. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +104 -2
  18. package/data/harnesses/code/skills/documentation/templates/Readme.md +4 -3
  19. package/data/harnesses/code/skills/documentation/templates/bookkeeping.md +1 -1
  20. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +15 -36
  21. package/data/harnesses/code/skills/documentation/templates/doctrine.md +81 -0
  22. package/data/harnesses/code/skills/documentation/templates/feature.md +63 -119
  23. package/data/harnesses/code/skills/documentation/templates/handover.md +174 -0
  24. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +1 -1
  25. package/data/harnesses/code/skills/documentation/templates/package.md +49 -92
  26. package/data/harnesses/code/skills/documentation/templates/root-readme.md +103 -65
  27. package/data/harnesses/code/skills/documentation/templates/setup.md +138 -0
  28. package/data/harnesses/code/skills/documentation/templates/system.md +45 -107
  29. package/data/harnesses/delivery/agents/lld-mode.md +1 -1
  30. package/data/harnesses/delivery/agents/maintenance.md +7 -9
  31. package/data/harnesses/delivery/harness.json +2 -2
  32. package/data/harnesses/delivery/skills/documentation/SKILL.md +22 -11
  33. package/data/harnesses/delivery/skills/documentation/references/examples.md +29 -25
  34. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +3 -3
  35. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +211 -292
  36. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +4 -2
  37. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +104 -2
  38. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +4 -3
  39. package/data/harnesses/delivery/skills/documentation/templates/bookkeeping.md +1 -1
  40. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +15 -36
  41. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +81 -0
  42. package/data/harnesses/delivery/skills/documentation/templates/feature.md +63 -119
  43. package/data/harnesses/delivery/skills/documentation/templates/handover.md +174 -0
  44. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +1 -1
  45. package/data/harnesses/delivery/skills/documentation/templates/package.md +49 -92
  46. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +103 -65
  47. package/data/harnesses/delivery/skills/documentation/templates/setup.md +138 -0
  48. package/data/harnesses/delivery/skills/documentation/templates/system.md +45 -107
  49. package/data/harnesses/etna/agents/change-review.md +1 -1
  50. package/data/harnesses/etna/agents/lld-mode.md +1 -1
  51. package/data/harnesses/etna/agents/maintenance.md +7 -9
  52. package/data/harnesses/etna/harness.json +2 -2
  53. package/data/harnesses/etna/skills/documentation/SKILL.md +22 -11
  54. package/data/harnesses/etna/skills/documentation/references/examples.md +29 -25
  55. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +3 -3
  56. package/data/harnesses/etna/skills/documentation/references/style-guide.md +211 -292
  57. package/data/harnesses/etna/skills/documentation/references/untemplated.md +4 -2
  58. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +104 -2
  59. package/data/harnesses/etna/skills/documentation/templates/Readme.md +4 -3
  60. package/data/harnesses/etna/skills/documentation/templates/bookkeeping.md +1 -1
  61. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +15 -36
  62. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +81 -0
  63. package/data/harnesses/etna/skills/documentation/templates/feature.md +63 -119
  64. package/data/harnesses/etna/skills/documentation/templates/handover.md +174 -0
  65. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +1 -1
  66. package/data/harnesses/etna/skills/documentation/templates/package.md +49 -92
  67. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +103 -65
  68. package/data/harnesses/etna/skills/documentation/templates/setup.md +138 -0
  69. package/data/harnesses/etna/skills/documentation/templates/system.md +45 -107
  70. package/lib/install/materialize.mjs +4 -12
  71. package/lib/install/plan.mjs +4 -11
  72. package/package.json +3 -2
  73. package/data/harnesses/code/skills/documentation/templates/structure.md +0 -71
  74. package/data/harnesses/delivery/skills/documentation/templates/structure.md +0 -71
  75. package/data/harnesses/etna/skills/documentation/templates/structure.md +0 -71
@@ -1,115 +1,195 @@
1
+ <!-- doc-lint-disable: date-in-truth-doc, history-narration, stale-tripwire, progress-marker, temporal-hedge, predecessor-frame, status-glyph -->
2
+ <!-- reason: the style authority quotes the forbidden constructions verbatim in its ❌ columns; each match is an example of what not to write. -->
3
+
1
4
  # Documentation Style Guide
2
5
 
3
- Writing rules for clear, maintainable documentation.
6
+ This guide states how a document is written: every file under `docs/` and every README the `documentation` skill authors or edits. Two neighbouring authorities answer the questions beside it. [`instruction-style.md`](instruction-style.md) governs the files an agent obeys (`CLAUDE.md`, rules, agents, skill prose), which are paid for on every load and written lean; each template in [`templates/`](../templates/Readme.md) governs its genre's sections and fields. The first two sections of this guide are enough to write a correct document; the sections after them are the detail each principle unfolds into, and a reader who stops early holds a coarse picture that is still true.
4
7
 
5
- ---
8
+ ## The model
6
9
 
7
- ## Function Documentation
10
+ A document is read by a person who wants to understand something or to act on it, and it is scanned more often than it is read. Every rule below follows from eight principles; later sections cite them by number.
8
11
 
9
- ### Signature Format
12
+ ### Principles
10
13
 
11
- ```markdown
12
- ### `functionName(param1, param2, options)`
14
+ 1. **Two natures:** every document is a truth document (what is, now, rewritten in place) or a record (what happened, dated and frozen). A truth document never narrates history and a record is never edited to match the present, because a reader must be able to trust each without the other.
15
+ 2. **The outside-in shape:** an explaining document opens on the question it answers and its boundary, then the model with its numbered principles, then the parts and their relations, then each part's decisions, and stops at its genre's deepest layer. Each layer is complete on its own, so a reader who stops at any layer holds a picture that is coarse but true, never a teaser the next section completes.
16
+ 3. **The stability test:** a sentence that would have to change when a function is renamed, a file moves, a route, column, error code or cookie attribute changes, or a constant is retuned without the design changing belongs to the code, which the code graph computes on demand (`docs/architecture/systems/knowledge-layer.md`), and not to the document. A copy typed into a document is at best a duplicate of the code and at worst a stale one.
17
+ 4. **The authority split:** the code is the authority on *what*; the document is the authority on *why*. A disagreement on *what* means the document is stale and the code wins; a disagreement on *why* or on an invariant is a defect to raise, because one side is wrong on purpose.
18
+ 5. **Noun-phrase labels, third-person sentences:** every heading and every bold bullet label names something and contains no finite verb, so it carries no tense, person or voice. The sentence after a label is third person, present tense, active, with the actor as its subject.
19
+ 6. **A body scanned by people, a footer for the agent:** an owning document is bullets under noun-phrase headings, tables wherever the cases are parallel states, code named only where a person types or sees it or at a cross-cutting seam, and a closing "For the agent" footer that holds pointers, never an inventory.
20
+ 7. **Self-contained, never padded:** the body reads whole without opening another file, restating the one sentence of context a borrowed concept needs and citing the authority for the rest. Length is a signal of a document that has let mechanism in, never a target.
21
+ 8. **Depth per genre:** doctrine stops at decisions and reasons, a system at behaviour across packages, a package at its public contract, a feature runs deepest at its end in Promises, and a reference document or runbook keeps full detail because the detail is its content.
13
22
 
14
- **Goal:** One-line purpose
23
+ ## The genres
15
24
 
16
- **Input:**
25
+ Every genre takes the same shape (principle 2) and the same labels (principle 5); what differs is how deep it may go.
17
26
 
18
- - `param1` (type) - Description
19
- - `param2` (type, optional) - Description
27
+ | Genre | Nature | Deepest layer | Excluded |
28
+ | --- | --- | --- | --- |
29
+ | Doctrine (`docs/architecture/common/`) | Truth | The decisions behind each part and the reasons for them | Any mechanism. A doctrine document describes no code |
30
+ | System (`docs/architecture/systems/`) | Truth | The machine's behaviour across packages: the order it runs in, sequence and state diagrams at role level, the invariant at each place where parts meet, what re-drives a stall. No single file shows a cross-package flow, so this layer earns its place | Per-function steps, tables and columns, routes |
31
+ | Package (`docs/architecture/packages/`) | Truth | The public contract a consumer touches: commands and their flags, exports, what is installed and where. For a CLI the flags *are* the promise | Internal layout, the build's steps, which file holds what |
32
+ | Feature (`docs/features/`) | Truth | The behaviour a person meets, in full: each state the surface can be in, each edge case, what a refusal tells them, the wording where the wording is promised. This genre runs deepest toward its end, in Promises, because a promise is checked by a person or a test and the code cannot state it as intent | Columns, routes, guards, functions, files |
33
+ | Reference (API reference, environment registry) | Truth | The contract itself: signatures, shapes, variables | Nothing. The detail is the point |
34
+ | Operations procedure, migration runbook | Truth, record | The exact commands, in order, with their expected output | Nothing. The detail is the point |
35
+ | Record (plan, changelog entry, journal, memory) | Record | Its template's fields, as of the moment it describes | Nothing. Its prose follows § Voice and § Labels; the dates and the journey are its own |
20
36
 
21
- **Output:** `{ field1, field2 }`
37
+ - **Owning documents:** feature, package and system are the three genres that carry `owns:`. They take principles 5 and 6 in full, their sections are fixed (§ Owning documents — the body and the footer), and `doc-lint` reads them.
38
+ - **Doctrine:** the same shape and labels as an owning document, with no `owns:` and no mechanism. Its model layer may argue in paragraphs; below the model it is bullets like every other explaining document.
39
+ - **Reference documents and procedures:** the one place a signature, a shape, a variable table, a command list or a file path is the content. They keep the detail the owning genres hand to the graph (§ Reference documents).
40
+ - **Indexes:** a folder's `Readme.md` describes directories, never files; the root README follows `templates/root-readme.md`. Both take § Labels.
22
41
 
23
- **Side Effects:** State updates, API calls, etc.
24
- ```
42
+ ## Shape — the model first, the detail after
25
43
 
26
- ### Parameter Rules
44
+ Every truth document a person reads to understand something is written from the outside in (principle 2). The failure this prevents is a document written at one density from its first word: an inventory table before the reader knows what is being inventoried, and the principles that summarize it arriving last, where nobody reads them.
27
45
 
28
- - Name + type + one-line purpose
29
- - Mark optional params with `(type, optional)`
30
- - Nest object properties:
31
- ```markdown
32
- - `options` (object) - Configuration
33
- - `options.retry` (boolean) - Enable retries
34
- - `options.timeout` (number) - Timeout in ms
35
- ```
46
+ ### The layers
36
47
 
37
- ### Return Values
48
+ 1. **The question and its boundary:** the first paragraph says what question this document answers, and which neighbouring documents answer the questions next to it. No addresses, file paths or configuration in it.
49
+ 2. **The model:** what the thing is, in a page: the parties or parts, the one or two axes that organize them, and the invariants that hold everywhere, numbered, each with its reason, so later sections cite them ("principle 3").
50
+ 3. **The parts:** one table or diagram placing every part in the model, then how the parts relate: what they share, where they meet, what keeps them apart.
51
+ 4. **Each part in turn:** for each part, the decisions it rests on and why. A part's section opens with why the part exists, never with how it is built.
52
+ 5. **The genre's deepest layer:** the row for the genre in § The genres, and nothing deeper.
38
53
 
39
- Always specify:
54
+ ### The stability test
40
55
 
41
- - Type: `Array<Object>`, `boolean`, `{ merged, changes }`
42
- - Shape for objects/arrays
43
- - Meaning: "True if sync successful"
56
+ The test (principle 3) decides what a sentence may say. These survive it:
44
57
 
45
- ---
58
+ - **Reasons:** why the design is this way, and what would break otherwise.
59
+ - **Invariants:** what must hold everywhere.
60
+ - **Decisions:** the choice made, and the alternative a reader would reach for.
61
+ - **Promises:** what a person or a test can check.
62
+ - **Cross-component contracts:** what no single file shows, such as two clients that must classify the same answer identically.
63
+ - **Decided-but-unbuilt intent:** what the code cannot reveal because it does not yet do it, wrapped in `<!-- UNBUILT:START — {what, and the evidence it is not built} -->` … `<!-- UNBUILT:END -->` in plain words. A design decided *against* carries no marker.
46
64
 
47
- ## State Documentation
65
+ The authority split (principle 4) is stated in the opening of any document whose readers include agents, so a reader who finds the code and the document disagreeing knows which way to resolve it.
48
66
 
49
- ### When to Document State
67
+ ### Diagrams and length by layer
50
68
 
51
- ✅ Do:
69
+ - **A diagram's layer:** at the model and parts layers a diagram names roles ("the browser", "the auth service"), never a URL, a header or a file. A diagram drawn from the code's names belongs to the code graph.
70
+ - **Length as a signal:** a document whose reference tail is longer than its body is an inventory with an introduction. A doctrine document past about three hundred lines has usually let mechanism in; the per-genre expectations are each template's.
52
71
 
53
- - Redux persistence (localStorage, IndexedDB)
54
- - Database schemas
55
- - API request/response shapes
72
+ ## Labels
56
73
 
57
- ❌ Don't:
74
+ A heading, and the bold label that leads a bullet, is a noun phrase (principle 5). It names something. It never contains a finite verb, so it carries no tense, no person and no voice; the sentence that says what happens comes after the label, never inside it.
58
75
 
59
- - Component-level state
60
- - Derived/computed state
61
- - Temporary UI state
76
+ A clause used as a label is the recurring defect. Once a label has a verb it has to pick a tense ("What *was* decided" is past tense in a present-tense document), a person ("*You* already belong…") and a voice ("was decided" is passive). A noun phrase has none of these, so it cannot be wrong in any of them.
62
77
 
63
- ### Format
78
+ | ❌ Clause | Grammar | ✅ Noun phrase |
79
+ | --- | --- | --- |
80
+ | "How it works" | wh-clause, present tense | Flows |
81
+ | "What was decided" | wh-clause, passive voice, past tense | Decisions |
82
+ | "What it promises" | wh-clause | Promises |
83
+ | "Why it exists" | wh-clause | Scope, or nothing: its content is a decision |
84
+ | "Where a person lands" | wh-clause, third person | Landing |
85
+ | "Asking who you are" | gerund clause, second person | Identity check |
86
+ | "You already belong to an organization:" | declarative sentence, second person | Organization member: |
87
+ | "Run `nustack login`." | imperative sentence | `nustack login`: |
88
+ | "NuStack checks identity; it does not own it" | two declarative clauses | Identity: checked, not owned |
64
89
 
65
- ````markdown
66
- **Frontend (at persistence):**
90
+ - **Format:** `**Label:** sentence`. The bold label ends in a colon, then one or two plain sentences follow: "**Dead grant:** the stored item is deleted, and the person is prompted to sign in."
91
+ - **The label's job:** it names the case, the thing or the decision; the sentence says what happens. "**Unclaimed domain:** user gets a private organization…", never "**Nobody claims your domain:** …".
92
+ - **Reach:** the rule applies at every depth: `##`, `###` and `####` headings, table header cells, and the bold lead of every bullet or numbered item, in every document this guide governs.
93
+ - **Exemptions:** the goal line and running prose are full sentences. A heading whose text is itself the checkable claim (a behavioural checklist's section, an acceptance criterion) is content, not a label, and keeps its sentence, because the assertion is what the reader came for.
94
+ - **Lint:** `doc-lint` warns `clause-label` on a heading or bold label in an owning or doctrine document that opens with a wh-word or a personal pronoun, or that ends in a full stop.
67
95
 
68
- ```json
69
- {
70
- "activeField": "value"
71
- // "deprecated": null // UNUSED: dead key; kept so old persisted state rehydrates
72
- }
73
- ```
96
+ ## Voice
74
97
 
75
- **Storage:** localStorage key `state_key`
98
+ The sentence after a label, and every sentence of running prose, describes the product to whoever reads it; it does not address the reader.
76
99
 
77
- **Backend:**
100
+ - **Person and tense:** third person, present tense, active voice. The subject is the actor (user, machine, CLI, server, the organization): "**Organization user:** user lands in their existing organization", never "you land in the organization you already belong to". `doc-lint` warns `second-person` on "you" or "your" outside quoted copy, in an owning or doctrine document.
101
+ - **Quoted interface copy:** keeps its own wording, including its "you", because the product does address its user. Quote it exactly, in quotation marks.
102
+ - **Concision:** "Merges server data with local changes by version", never a sentence that restates its own subject twice. A function or a command is described by what it does ("Fetches data from the server", "Returns an array"), never by what it "is used to" do and never in the passive ("an array is returned").
103
+ - **Bold:** marks a bullet's label or a defined term's first appearance, never a noun mid-sentence.
104
+ - **Em-dash:** a budget of one per paragraph, never a joint between clauses.
105
+ - **Terms of art:** introduced in plain words the first time they appear, the term itself in parentheses where a reader will meet it elsewhere.
106
+ - **Inline code:** every identifier, filename, command, flag, environment variable and config key a document names is in backticks. Where a document may name code at all is § Owning documents — the body and the footer and § Reference documents.
107
+ - **Decoration:** ❌ / ✅ only inside banned/blessed lists and comparison tables, never as general decoration; no emoji in headings.
78
108
 
79
- ```ts
80
- export const table = pgTable('table', {
81
- id: text('id').primaryKey(),
82
- data: jsonb('data'),
83
- // old: text('old'), // UNUSED: dead column; nothing reads it
84
- });
85
- ```
86
- ````
109
+ ## Owning documents — the body and the footer
87
110
 
88
- ### Mark Unused Keys
111
+ A feature, package or system document is scanned more than read (principle 6). It takes the shape (§ Shape — the model first, the detail after) and the labels (§ Labels) above, and these rules.
89
112
 
90
- Always comment deprecated/unused fields. The annotation states why the field is dead _now_ — never where it went, what replaced it, or when it will be removed (no "Remove in v3", no "Migrated to newField"; that is history narration, § The Two Natures below):
113
+ ### Sections
91
114
 
92
- ```json
93
- {
94
- "active": [],
95
- // "legacy": {} // UNUSED: dead key; kept for rehydrate compatibility
96
- }
97
- ```
115
+ | Genre | Sections, in order |
116
+ | --- | --- |
117
+ | Feature | Goal line · Scope · Flows · Decisions · Promises · Gaps · For the agent |
118
+ | System | Opening paragraph (the machine defined) · Scope · Flow · Decisions · Promises · Gaps · For the agent |
119
+ | Package | Identity line · Goal line · Scope · Ownership · Usage · Decisions · Promises · Gaps · For the agent |
120
+
121
+ Nothing else. "Why it exists" is retired; its content is Scope or Decisions. Mechanism sections (Architecture, Key Functions, State, Files, Schema, Routes, Wire, and their kin) are the graph's, and `doc-lint` blocks them as `mechanism-section`. The templates say when each section is required and how long each genre runs.
98
122
 
99
- ---
123
+ ### The body
124
+
125
+ - **The opening:** the goal is the first paragraph under the title, after the one identity line a package carries. No plan link and no routing line above it.
126
+ - **Bullets:** each section is bullets under a noun-phrase heading; each bullet is a bold noun-phrase label, a colon, then one or two plain sentences saying what happens, what is decided or what is promised.
127
+ - **Tables:** a table replaces the bullets wherever the cases are parallel states, such as each refusal and the exact message it shows. Its header cells are noun phrases.
128
+ - **Paragraphs:** right for the goal, for a system's opening definition, and for a doctrine's model that needs an argument. Everywhere else, a paragraph is bullets that have not been cut yet.
129
+ - **Code in the body:** named only where a person types or sees it (a page, a command, a flag, an environment variable) or 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 scheduler tick, a shared store holding part of the feature's logic because that logic is global. Written once, by name, where the narrative leaves the feature. Everything else is a plain name: "the device registry", "the sign-off page", "the mirror". `doc-lint` warns `body-identifier` past three identifiers in a section.
130
+ - **Flows:** describe behaviour, never mechanism. A flow bullet says that a forgotten machine comes back on its next call, never which function re-mints the row. Behaviour in plain words is intent made legible; columns, routes, guards and signatures are the graph's.
131
+ - **Promises:** the deepest section of a feature document: every state, edge case and refusal, and the exact wording where the wording is promised, each checkable by a person or a test. A promise reads "a removed membership shows a panel, not a redirect", never which route answers it.
132
+ - **Gaps:** a gap the code does not close is one bullet under Gaps, or a backlog row. It is never a ledger row inside another section, and never a temporal hedge.
133
+
134
+ ### The footer
135
+
136
+ "For the agent" is a set of pointers, never an inventory. It holds four things:
137
+
138
+ 1. **Objects:** each with a one-line definition.
139
+ 2. **Code roots:** directories where the graph should start.
140
+ 3. **Seams:** the cross-cutting seams, by name.
141
+ 4. **Checklist and neighbours:** the checklist, and the neighbouring documents with a purpose for each.
142
+
143
+ A feature adds its pages, because an address is what a person points at; a package adds its commands, because those are its public contract. Tables, routes, symbol rosters and file lists belong in the footer no more than in the body; the footer obeys the stability test like every other line, and a footer that grows with every function is the inventory moved down the page.
144
+
145
+ ## The Two Natures — tense and history
146
+
147
+ Every document is a truth document or a record (principle 1); `SKILL.md` § The Two Natures gives the split, the folders and the lifecycle. The tense rules follow directly.
148
+
149
+ - **Truth documents:** everything outside `docs/history/`, `docs/research/` and `docs/memory/` states what the system *is* and how it works *today*, as if it had always been so. The journey (dates, migrations, progress) lives only in records.
150
+ - **The one bridge:** an Architecture Decision's **Decision Changelog** tail carries that decision's dated revision history while its body stays current-truth-only; head is truth, tail is provenance. No other truth document carries a dated line, apart from the frontmatter's tooling keys and a dated path inside a link or code span, which cites a record rather than claiming a date. The `maintenance` agent's Health Log is a record of its own (`docs/history/health-log.md`), not a tail.
151
+ - **Records:** never edited to match the present. A frozen plan stays wrong-in-hindsight; a changelog entry describes what shipped as it shipped. A scope change gets a new dated record that links back.
152
+
153
+ | ❌ Historical narration (a record's) | ✅ Present-tense fact (the truth document's) |
154
+ | --- | --- |
155
+ | "Folded in from the `NuStack-X` repo (2026-06-12)." | "Vendor-connector catalogue; one subpath per vendor." |
156
+ | "Built 2026-06-14; shipped + verified 2026-06-13." | "The session runs as an outer loop of turns over the agent loop." |
157
+ | "The legacy worker was deleted in the 2026-06-14 fold." | "One worker interprets every workflow definition." |
158
+ | "ex-`@nurix/mcp-runtime`, M9 Phase C; was X, now Y." | "The MCP client runtime, started by the agent trigger." |
159
+ | "Build Sequence phases 0–4 are complete." | Nothing; progress lives in the plan or backlog record |
160
+ | "There is no standalone `skills/components/` — treat any reference to it as stale." | Nothing; delete or repoint the stale references and state only the present design |
161
+ | "Read first: `docs/history/plans/2026-…-fold.md`" (routing) | "Read first: `docs/architecture/<current-truth-doc>.md`" |
162
+
163
+ - **Dates and progress:** nothing about *when* something shipped, was verified, folded or was removed, and no completion markers: no "phases 0–4 are complete", no per-item `✅ shipped` / `⏳ pending`. Progress tracking is a record's job (the plan, the backlog). `doc-lint` blocks `date-in-truth-doc`, `history-narration` and `progress-marker`, and warns `status-glyph`.
164
+ - **Stale-reference tripwires:** never "X is gone — treat references to X as stale"; that is a redirect document compressed into one sentence. Delete or repoint every stale reference instead (`stale-tripwire`, and `redirect-doc` for the file-sized version).
165
+ - **Version and phase framing:** no bare `v1`/`v2` label, no "Phase 1/2", no "the old X", no "supersedes the earlier". There is one design; describe it without its predecessors (`predecessor-frame`). A version naming an external present-tense fact stays: a schema literal like `design-tokens/v2`, a dependency pin like `@0.14.0`.
166
+ - **Temporal hedges:** "currently", "not yet", "still", "for now" smuggle a ⏳ into a truth document. State the fact without the hedge ("the hook is standalone; nothing in the mount path calls it") and let the backlog record carry the intention (`temporal-hedge`).
167
+ - **A published artifact's version surface:** release notes and upgrade guides for a shipped package may use version framing (`v1 → v2`), because that is the artifact's public contract. They live beside the artifact or under `docs/operations/`, never in `docs/features/` or `docs/architecture/`.
168
+ - **Record citations:** by what the record is, never by when it was. `Provenance: AD-002` points to the decision rationale; "decided in AD-002 and shipped 2026-06-13" states a date the reader must now carry. `the dev reset runbook` links to the file; "the 2026-09-13 reset" goes stale at the second reset.
169
+ - **Routing and index documents:** point only to truth documents as a topic's authority. A "read first" row whose target is a plan or changelog entry is a redirect-for-history; repoint it or drop it. An index *of the records themselves* (a History section listing `plans/`, `changelog/`) is sanctioned.
170
+ - **A changed system:** the change-story goes to `docs/history/` as a changelog entry, and the truth document simply becomes correct in present tense. The diff is never narrated in place.
171
+ - **A moved decision:** an edit, never a new document. The AD's affected sections are rewritten to the new truth and the revision appended to its Decision Changelog; no parallel document, no old choice narrated in the body.
172
+
173
+ Worked example of the strip-and-relocate move: [`examples.md`](examples.md) Example 6.
100
174
 
101
- ## ASCII Diagrams
175
+ ## Self-contained documents and the link surface
102
176
 
103
- ### When to Use
177
+ Instruction files stay lean because an agent pays for them on every load (`instruction-style.md`); a document is read on demand, so it carries what its reader needs to understand the page (principle 7).
104
178
 
105
- - Data flows
106
- - System architecture
107
- - Component interactions
108
- - Process flows
179
+ - **Completeness:** the one or two sentences of context a borrowed concept needs are restated where it is used, because a reader forced mid-paragraph into a second document loses the thread of the first.
180
+ - **Restatement and citation:** a changing detail (a version, a count, a path list) keeps one canonical home; the restatement carries what the page needs and points at the authority for the rest. Link-don't-copy governs where a fact is *owned*, not how readable the page that uses it must be.
181
+ - **Inline links:** the minimum that action requires. A link mid-prose is right only where the reader must go there to act on this page, which includes a Scope section's "Not here" pointers.
182
+ - **The closing link surface:** every other sister document belongs in the document's one closing section: "For the agent" (its neighbours line) in an owning or doctrine document, "Related" elsewhere. Deep relative paths (`../../../../…`) are fragile, since a folder move breaks every one, so they are confined to that block; body mentions use the plain name ("the boundary skill", "`structure.md`").
109
183
 
110
- **Docs only.** Diagrams belong in documents read on demand (feature docs, ADs, operations). Instruction files — `CLAUDE.md`, rules, agent definitions, `SKILL.md` prose — never carry them: they load on every turn or every invocation, and a table or a sentence carries the same information at a fraction of the tokens.
184
+ ## Diagrams
111
185
 
112
- ### Pattern
186
+ Structure at rest is ASCII; behaviour over time is mermaid. A file tree, an on-disk layout, a load-class split, a wireframe: box characters, because the diagram *is* the thing's shape. A sequence of turns, a state machine, a branching flow, a data flow: mermaid, because a renderer tracks the arrows better than a reader tracks them across box art, and the source stays diffable when a step is inserted.
187
+
188
+ - **Documents only:** a diagram belongs in a document read on demand (a feature, system or doctrine document, a procedure). Instruction files never carry one; they load on every turn or invocation, and a sentence or a table carries the same information at a fraction of the tokens.
189
+ - **Prose as the account:** a diagram restates structure for a reader who scans; a reader who greps must still find everything in the text. In an owning document the flow bullets are the account and the diagram sits beside them, never in their place.
190
+ - **Role level:** at the model and parts layers a diagram names roles, never a URL, a header or a file (§ Shape — the model first, the detail after).
191
+
192
+ ### ASCII
113
193
 
114
194
  ```
115
195
  ┌─────────────────────────────────────────┐
@@ -126,56 +206,23 @@ Always comment deprecated/unused fields. The annotation states why the field is
126
206
  └─────────────────────────────────────────┘
127
207
  ```
128
208
 
129
- ### Characters
130
-
131
- - Boxes: `┌─┐│└┘├┤┬┴┼`
132
- - Arrows: `───▶` `◀───` `│▼` `│▲`
133
- - Width: ~70 chars max
134
-
135
- ### UI Wireframes
209
+ - **Characters:** boxes `┌─┐│└┘├┤┬┴┼`; arrows `───▶` `◀───` `│▼` `│▲`.
210
+ - **Width:** about 70 characters at most.
211
+ - **Wireframes:** a screen layout carries its page and tab above the frame (`**Page:** /path/:id`, `**Tab:** Tab Name`), `[text]` for a clickable button or badge, `[i]` for an icon followed by its label or count, `v` / `^` for an expand or collapse indicator, and one frame per UI state (collapsed, expanded).
136
212
 
137
- For screen layouts (not data flows), use these conventions:
138
-
139
- ```
140
- **Route:** `path/:id`
141
- **Tab:** Tab Name
142
-
143
- ┌────────────────────────────────────┐
144
- │ Title [i]3 [Button]│
145
- │ [i]Label [Tag1][Tag2][+Add] │
146
- └────────────────────────────────────┘
147
- ```
213
+ ### Mermaid
148
214
 
149
- - `[text]` = clickable button/badge
150
- - `[i]` = icon (followed by label or count)
151
- - `v` / `^` = expand/collapse indicator
152
- - Show each UI state (collapsed/expanded) as separate diagrams
153
- - Include Route/Tab context above wireframe
154
-
155
- ---
156
-
157
- ## Mermaid Diagrams
158
-
159
- **Structure at rest is ASCII; behaviour over time is mermaid.** A file tree, an on-disk layout, a load-class split, a wireframe — draw with box characters, because the diagram *is* the thing's shape. A sequence of turns, a state machine, a branching flow — write mermaid, because a renderer tracks the arrows better than a reader tracks them across box art, and the source stays diffable when a step is inserted.
160
-
161
- **Docs only**, on the same reasoning as ASCII: a diagram never enters an instruction file.
162
-
163
- ### When to Use
164
-
165
- | Diagram | Use for |
215
+ | Diagram | Purpose |
166
216
  | --- | --- |
167
- | `sequenceDiagram` | Who calls whom in what order — a session turn, a hand-off between components |
168
- | `stateDiagram-v2` | Modes with transitions — a workflow, a record's lifecycle |
169
- | `flowchart` | A process with branches, gates, or fan-out |
170
- | `timeline` | A dated lineage, in records only — never in a truth document |
171
-
172
- ### Rules
217
+ | `sequenceDiagram` | Who calls whom in what order: a session turn, a hand-off between components |
218
+ | `stateDiagram-v2` | Modes with transitions: a workflow, a record's lifecycle |
219
+ | `flowchart` | A process with branches, gates or fan-out |
220
+ | `timeline` | A dated lineage, in records only, never in a truth document |
173
221
 
174
- - **At most 7 participants and 15 interactions** per diagram. Past that, split it — an unreadable diagram is worse than the prose it replaced.
175
- - **Labels under 8 words**, no trailing punctuation.
176
- - **Declare a direction** on every flowchart (`flowchart TD` / `LR`) so the render is stable.
177
- - **The diagram never carries a fact the prose omits.** It restates structure for a reader who scans; a reader who greps must still find everything in the text.
178
- - **No styling directives** — no `style`, no `classDef`, no theme overrides. Rendering is the reader's; the source stays portable across GitHub, Obsidian, and a plain editor.
222
+ - **Size:** at most 7 participants and 15 interactions per diagram. Past that, split it; an unreadable diagram is worse than the bullets it restates.
223
+ - **Labels:** under 8 words, no trailing punctuation.
224
+ - **Direction:** declared on every flowchart (`flowchart TD` / `LR`) so the render is stable.
225
+ - **Styling:** none. No `style`, no `classDef`, no theme overrides; rendering is the reader's, and the source stays portable across GitHub, Obsidian and a plain editor.
179
226
 
180
227
  ```
181
228
  flowchart LR
@@ -185,200 +232,72 @@ flowchart LR
185
232
  D --> E[Implement]
186
233
  ```
187
234
 
188
- ---
189
-
190
- ## Code Examples
191
-
192
- ### Rules
193
-
194
- - Under 15 lines
195
- - Show contracts, not implementations
196
- - Use pseudocode for algorithms
197
-
198
- ✅ Good:
199
-
200
- ```javascript
201
- // Critical: Balanced brace matching
202
- function extract(json) {
203
- // Track brace depth
204
- // Ignore braces inside strings
205
- // Return complete objects only
206
- }
207
- ```
208
-
209
- ❌ Bad: Full 50-line implementation
210
-
211
- (Worked example: [`examples.md`](examples.md) Example 1.)
212
-
213
- ---
214
-
215
- ## Writing Style
216
-
217
- ### Voice
218
-
219
- Use imperative/active:
220
-
221
- - ✅ "Fetches data from server"
222
- - ✅ "Returns array of objects"
223
- - ❌ "This function is used to fetch"
224
- - ❌ "An array is returned"
225
-
226
- ### When Prose Adds Value
227
-
228
- Prose is valuable for context that contracts can't capture:
229
-
230
- | Use Prose For | Example |
231
- | --- | --- |
232
- | Section intros | "When the editor mounts, `useAppInit` is called with the `appId` from URL." |
233
- | Non-obvious behavior | "The hook always fetches fresh data. There is no caching or version checking." |
234
- | Design rationale | "Why parallel fetches? Each entity type is independent, reducing load time." |
235
- | Edge cases | "If created then deleted before save, it's removed from `added[]` without adding to `removed[]`." |
236
- | Limitations, stated as facts | "`useAppInit` is standalone — nothing in the mount path calls it." |
237
- | Usage context | "Used to show 'Unsaved' badge, warn before navigation, enable save buttons." |
238
-
239
- ### When to Avoid Prose
240
-
241
- - Describing WHAT code does (use signatures instead)
242
- - Step-by-step flows (use diagrams instead)
243
- - Structured comparisons (use tables instead)
244
-
245
- ### Conciseness
246
-
247
- One line when possible:
248
-
249
- - ✅ "Merge server data with local changes using version-based conflict resolution"
250
- - ❌ "This function takes the data from the server and also takes the local data..."
251
-
252
- ### Tables
253
-
254
- Use for structured info:
255
-
256
- ```markdown
257
- | Parameter | Type | Description |
258
- | --------- | ------ | -------------- |
259
- | `data` | object | Fresh from API |
260
- | `local` | object | Current state |
261
- ```
262
-
263
- ---
264
-
265
- ## Self-Contained Documents & References
266
-
267
- Two verbosity regimes, split by who pays for the words. **Instruction files** (`CLAUDE.md`, rules, agents, skill prose) load into an agent's context on every turn or invocation — they stay lean, per [`instruction-style.md`](instruction-style.md). **Documents** are read on demand, by humans and agents alike — they are written **verbose and self-contained**, and the cost of a reader hopping files exceeds the cost of extra words on the page.
268
-
269
- - **The body reads whole without opening another file.** Restate the one or two sentences of context a borrowed concept needs, right where it's used — a reader forced mid-paragraph into a second document loses the thread of the first.
270
- - **Restate for readability, cite for authority — never fork the fact.** A changing detail (a version, a count, a path list) keeps one canonical home; the restatement carries what the page needs to be understood and points at the authority for the rest. Link-don't-copy governs where a fact is *owned*, not how readable the page that uses it must be.
271
- - **Inline links are the minimum that action requires.** Link mid-prose only where the reader must go there to act on this page. Every other sister document — everything the topic touches — belongs in one **Related** (or **References**) section at the document's end.
272
- - **The Related tail is the document's entire link surface.** Deep relative paths (`../../../../…`) are fragile — a folder move breaks every one — so they are confined to that one block, where a path change touches one place; body mentions use the plain name (`the boundary skill`, `structure.md`) instead of a link.
273
-
274
- ---
275
-
276
- ## The Two Natures — Tense & History
235
+ ## Headings and layout
277
236
 
278
- Every document is a **truth document** (states current absolutes, updated in place) or a **record** (dated account of activity, frozen or append-only) — see `SKILL.md` § The Two Natures. The tense rules follow directly:
279
-
280
- **Truth documents describe the present, not the past.** Everything outside `docs/history/` states what the system _is_ and how it works _today_. It must not narrate how it got there. The journey — the dates, the migrations — lives **only** in records (`docs/history/`: changelog, plans, migrations). Three sanctioned exceptions: `docs/memory/` is the agent's own dated ledger; an AD's **Decision Changelog** tail carries that decision's dated revision history; and `docs/structure.md`'s **Health Log** tail carries the maintenance agent's tooling-stamped audit rows. In both tail bridges the body stays current-truth-only — head is truth, tail is provenance.
281
-
282
- **Records are never edited to match the present.** A frozen plan stays wrong-in-hindsight; a changelog entry describes what shipped as it shipped. A scope change gets a new dated record that links back.
283
-
284
- Strip this language from truth documents:
285
-
286
- | ❌ Historical narration (belongs in a record) | ✅ Present-tense fact (belongs in the truth doc) |
287
- | --- | --- |
288
- | "Folded in from the `NuStack-X` repo (2026-06-12)." | "Vendor-connector catalogue; one subpath per vendor." |
289
- | "Built 2026-06-14; shipped + verified 2026-06-13." | "`agentSessionWorkflow` runs an outer turn loop over `runAgentLoop`." |
290
- | "The legacy worker was deleted in the 2026-06-14 fold." | "One worker interprets `WorkflowDefinition`." |
291
- | "ex-`@nurix/mcp-runtime`, M9 Phase C; was X, now Y." | "MCP client runtime, wired into `agentTriggerWorkflow`." |
292
- | "Build Sequence phases 0–4 are complete." | Nothing — progress lives in the plan/backlog record; the doc describes what exists |
293
- | "There is no standalone `skills/components/` — treat any reference to it as stale." | Nothing — delete or repoint the stale references; state only the present design |
294
- | "Read first: `docs/history/plans/2026-…-fold.md`" (routing) | "Read first: `docs/architecture/<current-truth-doc>.md`" |
295
-
296
- Rules:
297
-
298
- - **No dates and no progress narration in truth documents.** Nothing about _when_ something shipped, was verified, folded, or was removed — and no completion markers either: no "phases 0–4 are complete", no per-item `✅ shipped` / `⏳ pending`. Progress tracking is a **record's** job (the plan, the backlog); a truth document describes what exists, as if it had always been so.
299
- - **No stale-reference tripwires.** Never write "X is gone — treat references to X as stale"; that is a redirect doc compressed into one sentence. Delete or repoint every stale reference instead (same rule as the **No redirect docs** rule in `SKILL.md` § The Two Natures) and state only the present fact.
300
- - **No version or phase framing.** A bare `v1`/`v2` as a label, "Phase 1/2", "the old X", "supersedes the earlier" — there is one design; describe it without its predecessors. (A version naming an external present-tense fact stays: a schema literal like `design-tokens/v2`, a dependency pin like `@0.14.0`.)
301
- - **Temporal hedges are progress markers in prose.** "currently", "not yet", "still", "for now" smuggle a ⏳ into a truth document — state the fact without the hedge ("the hook is standalone; nothing in the mount path calls it") and let the backlog record carry the intention.
302
- - **A published artifact's own version surface is external fact.** Release notes and upgrade guides for a shipped package may use version framing (`v1 → v2`) — that is the artifact's public contract, not the doc narrating its own past. They live beside the artifact or under `docs/operations/`, never in `docs/features/` or `docs/architecture/`.
303
- - **Cite the AD for the _why_, never the _when_.** `Provenance: AD-002` is good (it points to the decision rationale). "Decided in AD-002 and shipped 2026-06-13" is not.
304
- - **Routing/index docs point only to truth documents as a topic's authority.** A row whose "read first" target for a topic is a historical plan or changelog is a redirect-for-history — repoint it to the current truth doc, or drop the row. (An index _of the records themselves_ — a History section listing `plans/`, `changelog/` — is sanctioned: that indexes records, it doesn't route a topic.)
305
- - **When a doc changes because the system changed, the change-story goes in `docs/history/` (a changelog entry), and the truth document simply becomes correct in present tense.** Never leave the diff narrated in place.
306
- - **A decision that moves is an edit, not a new document.** Rewrite the AD's affected sections to the new truth and append the revision to its Decision Changelog — never mint a parallel doc and never leave the old choice narrated in the body.
307
-
308
- Worked example of the strip-and-relocate move: [`examples.md`](examples.md) Example 6.
309
-
310
- ---
311
-
312
- ## Mechanics
313
-
314
- - Inline-code every identifier, filename, command, and config key.
315
- - Bullet rules take the form "**bold assertion** — explanation."
316
-
317
- ---
318
-
319
- ## Structure
320
-
321
- ### Headers
237
+ - **Hierarchy:** one H1, the document's title; `##` for major sections, `###` for subsections, `####` sparingly.
238
+ - **Fixed section names:** an owning document's `##` headings are its template's, bare and identical across every document of the genre (`## Scope`, `## Promises`, `## For the agent`), because readers and tooling find them by name.
239
+ - **Retrieval keys:** search and agents retrieve a section out of context, where a bare `### Failures` reads identically across every document. A generic `###` heading, and every heading in an untemplated document, is qualified by its topic (`### Sign-in failures`, `### Merge rules — data sync`) so it stands alone when retrieved. A short document whose H1 disambiguates can keep bare headings.
240
+ - **Sentence case:** headings are sentence case; a product, a proper name or a named concept (`The Two Natures`) keeps its own casing.
241
+ - **No hard-wrapped prose:** a paragraph is one line in the source (`.prettierrc.json` keeps `proseWrap: never`); the renderer wraps it.
242
+ - **No empty stubs:** a section with nothing real to say is omitted; an explicit "None" is written only where the absence itself is information (`SKILL.md` § The Two Natures).
243
+ - **No file rosters:** a file list belongs in no document. The ownership index and the code graph answer "which file" for every genre, and a folder index describes directories, never files.
244
+ - **The reference-document layout:** a document that is not an owning genre and whose content is the contract itself (an API reference, an environment registry, a procedure's appendix) opens on its goal, as a `**Goal:**` line or one sentence, and proceeds straight to its contract or procedure sections:
322
245
 
323
246
  ```markdown
324
- # Document Title (H1 - once)
247
+ # [Title]
325
248
 
326
- ## Major Section (H2)
249
+ **Goal:** One-line purpose
327
250
 
328
- ### Subsection (H3)
251
+ ## [Contract or procedure sections]
329
252
 
330
- #### Detail (H4 - sparingly)
253
+ [Signatures, shapes, steps: the content the reader came for]
331
254
  ```
332
255
 
333
- **Headings are retrieval keys.** Search and agents retrieve sections out of context, and a bare `## State` reads identically across every feature doc. In long docs, qualify generic headings with the feature name — `## State — invoice-pdf`, `### Merge rules — data sync` — so a section stands alone when retrieved. Short docs whose H1 disambiguates can keep bare headings.
256
+ ## Reference documents
334
257
 
335
- ### Standard Layout
258
+ A reference document is the deepest genre: signatures, shapes and variables are its content, so the stability test does not apply to it (§ The genres). These rules bind only there, and in a procedure's appendix; an owning document names a symbol nowhere but its footer, and then only as a seam.
259
+
260
+ ### Function signatures
336
261
 
337
262
  ```markdown
338
- # [Title]
263
+ ### `functionName(param1, param2, options)`
339
264
 
340
265
  **Goal:** One-line purpose
341
266
 
342
- ## Architecture
343
-
344
- [Diagram + explanation]
267
+ **Input:**
345
268
 
346
- ## Key Functions
269
+ - `param1` (type) - Description
270
+ - `param2` (type, optional) - Description
347
271
 
348
- [Signatures and contracts]
272
+ **Output:** `{ field1, field2 }`
349
273
 
350
- ## State
274
+ **Side effects:** State updates, API calls, etc.
275
+ ```
351
276
 
352
- [Persistence shapes]
277
+ - **Parameters:** name, type and one-line purpose; `(type, optional)` marks an optional parameter; an object's properties nest beneath it (`options.retry` (boolean), `options.timeout` (number)).
278
+ - **Return values:** type (`Array<Object>`, `boolean`, `{ merged, changes }`), shape for objects and arrays, and meaning ("true when the sync succeeded").
279
+ - **Parameter tables:** `| Parameter | Type | Description |` where the parameters are many and parallel.
353
280
 
354
- ## Files
281
+ ### State at persistence points
355
282
 
356
- [Source file list]
357
- ```
283
+ - **Documented state:** what crosses a persistence boundary: a persisted store's shape (localStorage, IndexedDB), a database schema, a request or response shape.
284
+ - **Undocumented state:** component-level state, derived or computed state, temporary UI state.
285
+ - **Format:** the persisted shape as a `json` block with its storage key beneath (`**Storage:** localStorage key `state_key``), the schema as the code that declares it.
286
+ - **Unused keys:** a deprecated field keeps a `// UNUSED:` comment stating why the field is dead *now*, never where it went, what replaced it or when it will be removed (no "Remove in v3", no "Migrated to newField"; that is history narration, § The Two Natures): `// "legacy": {} // UNUSED: dead key; kept for rehydrate compatibility`.
358
287
 
359
- ### File References
288
+ ### Code examples
360
289
 
361
- Always end with:
290
+ - **Size:** under 15 lines.
291
+ - **Content:** a contract, never an implementation; pseudocode for an algorithm, with the invariants as comments and the body left out.
292
+ - **Placement:** a reference document, a procedure, or a package's Usage section, where the code is a command a person types. A feature or system document carries no function body.
362
293
 
363
- ```markdown
364
- ## Files
365
-
366
- - `src/path/main.js` - Core logic
367
- - `src/path/hooks.js` - React hooks
294
+ ```javascript
295
+ // Critical: balanced brace matching
296
+ function extract(json) {
297
+ // Track brace depth
298
+ // Ignore braces inside strings
299
+ // Return complete objects only
300
+ }
368
301
  ```
369
302
 
370
- ---
371
-
372
- ## Summary
373
-
374
- | Aspect | Rule |
375
- | ---------- | ------------------------------- |
376
- | Functions | Always include signatures |
377
- | Parameters | Type + purpose |
378
- | Returns | Type + shape |
379
- | State | Persistence points only |
380
- | Diagrams | ASCII for structure at rest, mermaid for behaviour over time — docs only, never instruction files |
381
- | Code | Under 15 lines, contracts only |
382
- | Voice | Imperative/active |
383
- | Mechanics | Inline-code identifiers; bold-assertion bullets |
384
- | Length | Concise, one line when possible |
303
+ Worked example: [`examples.md`](examples.md) Example 1.