@nurix/etna 0.20.35 → 0.20.37

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 (233) hide show
  1. package/data/catalog/rules/changelog.md +1 -1
  2. package/data/catalog/skills/nustack/SKILL.md +2 -2
  3. package/data/catalog/skills/nustack/references/cli-design.md +35 -35
  4. package/data/catalog/skills/nustack/references/monorepo-master-list.md +6 -6
  5. package/data/catalog/skills/nustack/references/monorepo-setup.md +13 -13
  6. package/data/catalog/skills/nustack/references/publishing.md +40 -39
  7. package/data/harness-index.json +1 -1
  8. package/data/harnesses/code/CLAUDE.md +4 -4
  9. package/data/harnesses/code/agents/brainstorm.md +2 -2
  10. package/data/harnesses/code/agents/lld-mode.md +2 -2
  11. package/data/harnesses/code/agents/maintenance.md +17 -17
  12. package/data/harnesses/code/codex/agents/brainstorm.toml +6 -2
  13. package/data/harnesses/code/codex/agents/lld-mode.toml +2 -2
  14. package/data/harnesses/code/codex/agents/maintenance.toml +18 -17
  15. package/data/harnesses/code/docs/README.md +9 -17
  16. package/data/harnesses/code/docs/history/CHANGELOG.md +19 -18
  17. package/data/harnesses/code/docs/structure.md +60 -45
  18. package/data/harnesses/code/harness.json +2 -2
  19. package/data/harnesses/code/hooks/compliance.mjs +8 -2
  20. package/data/harnesses/code/hooks/lib/sweep.mjs +3 -2
  21. package/data/harnesses/code/rules/changelog.md +1 -1
  22. package/data/harnesses/code/skills/boundary/SKILL.md +33 -22
  23. package/data/harnesses/code/skills/boundary/references/index.md +2 -4
  24. package/data/harnesses/code/skills/boundary/references/mechanisms.md +3 -10
  25. package/data/harnesses/code/skills/boundary/references/packs/frontend.md +17 -17
  26. package/data/harnesses/code/skills/boundary/references/packs/generic-tail.md +1 -1
  27. package/data/harnesses/code/skills/brainstorm/README.md +11 -13
  28. package/data/harnesses/code/skills/brainstorm/SKILL.md +149 -130
  29. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +48 -51
  30. package/data/harnesses/code/skills/brainstorm/references/harvest.md +51 -57
  31. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +48 -42
  32. package/data/harnesses/code/skills/design/SKILL.md +31 -35
  33. package/data/harnesses/code/skills/design/data/iconography.md +2 -2
  34. package/data/harnesses/code/skills/design/references/compose.md +14 -16
  35. package/data/harnesses/code/skills/design/references/foundations.md +5 -5
  36. package/data/harnesses/code/skills/design/references/intake.md +6 -6
  37. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  38. package/data/harnesses/code/skills/design/references/ship-gate.md +5 -5
  39. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +4 -4
  40. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +1 -1
  41. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +1 -1
  42. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +1 -1
  43. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +1 -1
  44. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +2 -2
  45. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +1 -1
  46. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +1 -1
  47. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +1 -1
  48. package/data/harnesses/code/skills/documentation/SKILL.md +92 -143
  49. package/data/harnesses/code/skills/documentation/references/examples.md +45 -72
  50. package/data/harnesses/code/skills/documentation/references/frontmatter.md +8 -8
  51. package/data/harnesses/code/skills/documentation/references/instruction-style.md +3 -3
  52. package/data/harnesses/code/skills/documentation/references/source-comments.md +19 -0
  53. package/data/harnesses/code/skills/documentation/references/style-guide.md +25 -11
  54. package/data/harnesses/code/skills/documentation/references/untemplated.md +11 -10
  55. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +181 -40
  56. package/data/harnesses/code/skills/documentation/templates/Readme.md +68 -41
  57. package/data/harnesses/code/skills/documentation/templates/acceptance-criteria.md +11 -19
  58. package/data/harnesses/code/skills/documentation/templates/api-reference.md +8 -3
  59. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +8 -12
  60. package/data/harnesses/code/skills/documentation/templates/backlog.md +2 -2
  61. package/data/harnesses/code/skills/documentation/templates/behavioral-checklist.md +10 -17
  62. package/data/harnesses/code/skills/documentation/templates/bookkeeping.md +2 -2
  63. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +2 -2
  64. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +21 -29
  65. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +4 -4
  66. package/data/harnesses/code/skills/documentation/templates/doctrine.md +3 -3
  67. package/data/harnesses/code/skills/documentation/templates/domain-model.md +10 -5
  68. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +7 -2
  69. package/data/harnesses/code/skills/documentation/templates/feature.md +6 -6
  70. package/data/harnesses/code/skills/documentation/templates/glossary.md +6 -1
  71. package/data/harnesses/code/skills/documentation/templates/handover.md +17 -17
  72. package/data/harnesses/code/skills/documentation/templates/implementation-map.md +10 -5
  73. package/data/harnesses/code/skills/documentation/templates/journal.md +2 -2
  74. package/data/harnesses/code/skills/documentation/templates/memory-main.md +2 -2
  75. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +1 -1
  76. package/data/harnesses/code/skills/documentation/templates/non-goals.md +8 -3
  77. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +8 -3
  78. package/data/harnesses/code/skills/documentation/templates/package.md +5 -9
  79. package/data/harnesses/code/skills/documentation/templates/plan.md +5 -11
  80. package/data/harnesses/code/skills/documentation/templates/protected-files.md +7 -2
  81. package/data/harnesses/code/skills/documentation/templates/root-readme.md +5 -5
  82. package/data/harnesses/code/skills/documentation/templates/security-overview.md +9 -4
  83. package/data/harnesses/code/skills/documentation/templates/setup.md +6 -6
  84. package/data/harnesses/code/skills/documentation/templates/system-overview.md +12 -7
  85. package/data/harnesses/code/skills/documentation/templates/system.md +2 -2
  86. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +10 -5
  87. package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +14 -5
  88. package/data/harnesses/code/skills/issue-bridge/SKILL.md +51 -16
  89. package/data/harnesses/code/skills/issue-bridge/references/trackers/github.md +5 -5
  90. package/data/harnesses/code/skills/issue-bridge/references/trackers/jira.md +11 -8
  91. package/data/harnesses/code/skills/issue-bridge/references/trackers/linear.md +16 -11
  92. package/data/harnesses/code/skills/nustack-graph/SKILL.md +38 -29
  93. package/data/harnesses/code/skills/polygraph/references/dispatch.md +31 -18
  94. package/data/harnesses/code/skills/polygraph/references/rows.md +11 -6
  95. package/data/harnesses/code/skills/schema-design/SKILL.md +39 -41
  96. package/data/harnesses/code/skills/test/SKILL.md +38 -42
  97. package/data/harnesses/code/skills/testing/SKILL.md +83 -73
  98. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +156 -193
  99. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +15 -15
  100. package/data/harnesses/delivery/CLAUDE.md +1 -1
  101. package/data/harnesses/delivery/agents/brainstorm.md +2 -2
  102. package/data/harnesses/delivery/agents/lld-mode.md +2 -2
  103. package/data/harnesses/delivery/agents/maintenance.md +17 -17
  104. package/data/harnesses/delivery/codex/agents/brainstorm.toml +6 -2
  105. package/data/harnesses/delivery/codex/agents/lld-mode.toml +2 -2
  106. package/data/harnesses/delivery/codex/agents/maintenance.toml +18 -17
  107. package/data/harnesses/delivery/harness.json +2 -2
  108. package/data/harnesses/delivery/rules/changelog.md +1 -1
  109. package/data/harnesses/delivery/skills/brainstorm/README.md +11 -13
  110. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +149 -130
  111. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +48 -51
  112. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +51 -57
  113. package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +48 -42
  114. package/data/harnesses/delivery/skills/cost-report/SKILL.md +10 -10
  115. package/data/harnesses/delivery/skills/documentation/SKILL.md +92 -143
  116. package/data/harnesses/delivery/skills/documentation/references/examples.md +45 -72
  117. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +8 -8
  118. package/data/harnesses/delivery/skills/documentation/references/instruction-style.md +3 -3
  119. package/data/harnesses/delivery/skills/documentation/references/source-comments.md +19 -0
  120. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +25 -11
  121. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +11 -10
  122. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +181 -40
  123. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +68 -41
  124. package/data/harnesses/delivery/skills/documentation/templates/acceptance-criteria.md +11 -19
  125. package/data/harnesses/delivery/skills/documentation/templates/api-reference.md +8 -3
  126. package/data/harnesses/delivery/skills/documentation/templates/architecture-decision.md +8 -12
  127. package/data/harnesses/delivery/skills/documentation/templates/backlog.md +2 -2
  128. package/data/harnesses/delivery/skills/documentation/templates/behavioral-checklist.md +10 -17
  129. package/data/harnesses/delivery/skills/documentation/templates/bookkeeping.md +2 -2
  130. package/data/harnesses/delivery/skills/documentation/templates/changelog-entry.md +2 -2
  131. package/data/harnesses/delivery/skills/documentation/templates/changelog-index.md +21 -29
  132. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +4 -4
  133. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +3 -3
  134. package/data/harnesses/delivery/skills/documentation/templates/domain-model.md +10 -5
  135. package/data/harnesses/delivery/skills/documentation/templates/environment-registry.md +7 -2
  136. package/data/harnesses/delivery/skills/documentation/templates/feature.md +6 -6
  137. package/data/harnesses/delivery/skills/documentation/templates/glossary.md +6 -1
  138. package/data/harnesses/delivery/skills/documentation/templates/handover.md +17 -17
  139. package/data/harnesses/delivery/skills/documentation/templates/implementation-map.md +10 -5
  140. package/data/harnesses/delivery/skills/documentation/templates/journal.md +2 -2
  141. package/data/harnesses/delivery/skills/documentation/templates/memory-main.md +2 -2
  142. package/data/harnesses/delivery/skills/documentation/templates/migration-runbook.md +1 -1
  143. package/data/harnesses/delivery/skills/documentation/templates/non-goals.md +8 -3
  144. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +8 -3
  145. package/data/harnesses/delivery/skills/documentation/templates/package.md +5 -9
  146. package/data/harnesses/delivery/skills/documentation/templates/plan.md +5 -11
  147. package/data/harnesses/delivery/skills/documentation/templates/protected-files.md +7 -2
  148. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +5 -5
  149. package/data/harnesses/delivery/skills/documentation/templates/security-overview.md +9 -4
  150. package/data/harnesses/delivery/skills/documentation/templates/setup.md +6 -6
  151. package/data/harnesses/delivery/skills/documentation/templates/system-overview.md +12 -7
  152. package/data/harnesses/delivery/skills/documentation/templates/system.md +2 -2
  153. package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +10 -5
  154. package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +14 -5
  155. package/data/harnesses/delivery/skills/escalate/SKILL.md +11 -11
  156. package/data/harnesses/delivery/skills/prompt-eval/SKILL.md +8 -8
  157. package/data/harnesses/delivery/skills/prompt-library/SKILL.md +30 -9
  158. package/data/harnesses/delivery/skills/route/SKILL.md +8 -8
  159. package/data/harnesses/etna/CLAUDE.md +2 -2
  160. package/data/harnesses/etna/agents/brainstorm.md +2 -2
  161. package/data/harnesses/etna/agents/lld-mode.md +2 -2
  162. package/data/harnesses/etna/agents/maintenance.md +17 -17
  163. package/data/harnesses/etna/codex/agents/brainstorm.toml +6 -2
  164. package/data/harnesses/etna/codex/agents/lld-mode.toml +2 -2
  165. package/data/harnesses/etna/codex/agents/maintenance.toml +18 -17
  166. package/data/harnesses/etna/harness.json +2 -2
  167. package/data/harnesses/etna/rules/changelog.md +1 -1
  168. package/data/harnesses/etna/skills/boundary/SKILL.md +33 -22
  169. package/data/harnesses/etna/skills/boundary/references/index.md +2 -4
  170. package/data/harnesses/etna/skills/boundary/references/mechanisms.md +3 -10
  171. package/data/harnesses/etna/skills/boundary/references/packs/frontend.md +17 -17
  172. package/data/harnesses/etna/skills/boundary/references/packs/generic-tail.md +1 -1
  173. package/data/harnesses/etna/skills/brainstorm/README.md +11 -13
  174. package/data/harnesses/etna/skills/brainstorm/SKILL.md +149 -130
  175. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +48 -51
  176. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +51 -57
  177. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +48 -42
  178. package/data/harnesses/etna/skills/documentation/SKILL.md +92 -143
  179. package/data/harnesses/etna/skills/documentation/references/examples.md +45 -72
  180. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +8 -8
  181. package/data/harnesses/etna/skills/documentation/references/instruction-style.md +3 -3
  182. package/data/harnesses/etna/skills/documentation/references/source-comments.md +19 -0
  183. package/data/harnesses/etna/skills/documentation/references/style-guide.md +25 -11
  184. package/data/harnesses/etna/skills/documentation/references/untemplated.md +11 -10
  185. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +181 -40
  186. package/data/harnesses/etna/skills/documentation/templates/Readme.md +68 -41
  187. package/data/harnesses/etna/skills/documentation/templates/acceptance-criteria.md +11 -19
  188. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +8 -3
  189. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +8 -12
  190. package/data/harnesses/etna/skills/documentation/templates/backlog.md +2 -2
  191. package/data/harnesses/etna/skills/documentation/templates/behavioral-checklist.md +10 -17
  192. package/data/harnesses/etna/skills/documentation/templates/bookkeeping.md +2 -2
  193. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +2 -2
  194. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +21 -29
  195. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +4 -4
  196. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +3 -3
  197. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +10 -5
  198. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +7 -2
  199. package/data/harnesses/etna/skills/documentation/templates/feature.md +6 -6
  200. package/data/harnesses/etna/skills/documentation/templates/glossary.md +6 -1
  201. package/data/harnesses/etna/skills/documentation/templates/handover.md +17 -17
  202. package/data/harnesses/etna/skills/documentation/templates/implementation-map.md +10 -5
  203. package/data/harnesses/etna/skills/documentation/templates/journal.md +2 -2
  204. package/data/harnesses/etna/skills/documentation/templates/memory-main.md +2 -2
  205. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +1 -1
  206. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +8 -3
  207. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +8 -3
  208. package/data/harnesses/etna/skills/documentation/templates/package.md +5 -9
  209. package/data/harnesses/etna/skills/documentation/templates/plan.md +5 -11
  210. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +7 -2
  211. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +5 -5
  212. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +9 -4
  213. package/data/harnesses/etna/skills/documentation/templates/setup.md +6 -6
  214. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +12 -7
  215. package/data/harnesses/etna/skills/documentation/templates/system.md +2 -2
  216. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +10 -5
  217. package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +14 -5
  218. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +156 -193
  219. package/data/harnesses/etna/skills/workflow-mapper/references/patterns.md +15 -15
  220. package/data/harnesses/hr/harness.json +1 -1
  221. package/data/harnesses/hr/skills/evaluator/SKILL.md +71 -73
  222. package/data/harnesses/hr/skills/evaluator/criteria/code-quality.md +28 -47
  223. package/data/harnesses/hr/skills/evaluator/criteria/deployment-readiness.md +33 -43
  224. package/data/harnesses/hr/skills/evaluator/criteria/maintainability.md +34 -46
  225. package/data/harnesses/hr/skills/evaluator/criteria/mechanical-ambition.md +13 -13
  226. package/data/harnesses/hr/skills/evaluator/criteria/problem-substantiveness.md +7 -7
  227. package/data/harnesses/hr/skills/evaluator/criteria/testing.md +36 -41
  228. package/data/harnesses/hr/skills/evaluator/criteria/ux-mechanics.md +25 -11
  229. package/data/harnesses/hr/skills/evaluator/criteria/value-articulation.md +7 -7
  230. package/data/harnesses/hr/skills/evaluator/preflight.md +27 -46
  231. package/data/harnesses/hr/skills/interview-eval/SKILL.md +37 -42
  232. package/data/harnesses/hr/skills/interview-eval/rubric.md +21 -23
  233. package/package.json +2 -2
@@ -4,7 +4,7 @@ This file is the authority on **what belongs where** in `docs/`: the folder map,
4
4
 
5
5
  **This file is the harness's, not the project's.** The installer writes it on every install and refresh, so nothing in it describes one repository: a folder a repo does not use is simply absent on disk, and a repo's own notes — legacy folders kept as provenance, retired genres, local exceptions — live in [`README.md`](README.md) § Notes for this repository, never here. Hand edits are overwritten on the next refresh. The one field written in place is `harness-version` in the frontmatter, stamped by the `maintenance` agent after its baseline reconcile; its absence is what tells a session the repo has not been baselined against the installed harness.
6
6
 
7
- One canonical source per topic — link, don't copy. Only `CLAUDE.md`, `AGENTS.md`, and `README.md` live at the repo root.
7
+ One canonical source per topic — link, don't copy. Only `CLAUDE.md`, `AGENTS.md`, and `README.md` live at the repo root. Every per-genre fact this file does not need for placement — a genre's nature, its `type:` value, its required keys and sections — is the `documentation` skill's genre registry (`templates/Readme.md`), and `doc-lint` checks documents against it.
8
8
 
9
9
  ---
10
10
 
@@ -23,8 +23,8 @@ docs/
23
23
  │ ├── common/ # The enterprise plane — one `{concern}.md` per concern the platform handles
24
24
  │ │ # the same way everywhere. Owns no code
25
25
  │ └── decisions/ # ADs — `AD-NNN-{slug}.md`, one per subject, updated in place; the journey lives in
26
- │ # each file's Decision Changelog tail. Readme.md is the register: the current
27
- │ # decision per subject and whether it is built
26
+ │ # each file's Decision Changelog tail. Each AD's `description:` and `status:` say
27
+ │ # what it decides and whether it stands; Readme.md describes the folder, never a row per AD
28
28
  ├── features/ # Feature docs — `{feature}.md`, one per thing a person points at (an address, a command
29
29
  │ # family, a named control), cut by its objects (flat, no subfolders). One of three owning genres, beside
30
30
  │ # `architecture/packages/` and `architecture/systems/`; ownership is computed from `objects:` and source headers
@@ -32,7 +32,7 @@ docs/
32
32
  ├── operations/ # Procedures — `setup.md` (the one-time first run, incl. the stack), then development, deployment, signing, rotation, diagnostics;
33
33
  │ │ # one topic-named `{procedure}.md` each. Also holds bookkeeping.md, the shared
34
34
  │ │ # doc-sync work queue (hook-appended, bookkeeper-drained, a drained row deleted)
35
- │ ├── release-notes/ # One operator-facing note per release (`YYYY-MM-DD-vX.Y.Z.md`); its README.md indexes them
35
+ │ ├── release-notes/ # One operator-facing note per release (`YYYY-MM-DD-vX.Y.Z.md`); listing the folder is the index
36
36
  │ ├── issues/ # Local-tracker issue records (`type: issue`, `YYYY-MM-DD-{slug}.md`) — the
37
37
  │ │ # `issue-bridge` skill's local pack; `status:` is the lifecycle
38
38
  │ └── triage/ # Triage dossiers (`type: triage`, `YYYY-MM-DD-{slug}.md`) — one per investigated
@@ -40,41 +40,42 @@ docs/
40
40
  ├── tests/ # Behavioral test checklists (truth docs) — `{feature}.md`, step → **Assert**, named for
41
41
  │ # the doc whose promises it proves. `ls docs/tests/` is the roster
42
42
  ├── research/ # Records — in-progress brainstorm sessions (`{topic}-brainstorm/`), standing-research
43
- │ # folders (`{topic}/`) and loose standing-research notes (`{topic}.md`). Readme.md is the index
43
+ │ # folders (`{topic}/`) and loose standing-research notes (`{topic}.md`). The folder name is the topic
44
44
  ├── history/
45
- │ ├── CHANGELOG.md # Master changelog index
45
+ │ ├── CHANGELOG.md # The changelog guide: how entries are named, owed and read. Never appended to
46
46
  │ ├── changelog/ # Individual changelog entries, `YYYY-MM-DD-{three-words}.md` (frozen at commit)
47
47
  │ ├── plans/ # Dated implementation plans, `YYYY-MM-DD-{slug}.md` (Status: field; Complete/Abandoned = frozen)
48
48
  │ ├── migrations/ # One-shot migration runbooks, `YYYY-MM-DD-{slug}.md` — authored ahead, outcome-stamped, frozen
49
- │ ├── brainstorms/ # Harvested brainstorm sessions (`{topic}/`), kept as provenance; Readme.md is the index
49
+ │ ├── brainstorms/ # Harvested brainstorm sessions (`{topic}/`), kept as provenance; the folder name is the topic
50
50
  │ ├── research/ # Deep-research records (`{topic}/` — README.md synthesis + findings.md + sources.md).
51
51
  │ │ # Frozen, cited, owns no code. Distinct from research/ at the docs root
52
52
  │ ├── health-log.md # The maintenance agent's append-only pass record, one generated row per pass
53
- │ ├── journal.md # Append-only mid-execution knowledge capture, one line per fact; a line resolves by
54
- │ │ # landing in its owning doc (delete the row, cite it in the changelog entry)
55
- │ └── backlog.md # Tracked work items by priority (P0–P3)
56
- └── memory/ # Project knowledge + per-agent strategy memory
53
+ │ ├── journal.md # Queue — mid-execution facts, one line each; a line resolves by landing in its owning
54
+ │ │ # doc (delete the row, cite it in the changelog entry)
55
+ │ └── backlog.md # Queue — open work by priority (P0–P3); a finished item is deleted
56
+ └── memory/ # Queues — project knowledge + per-agent strategy memory, compacted by their writers
57
57
  ├── main.md # Main-agent project memory
58
58
  └── {agent}.md # One strategy-memory file per sub-agent that keeps one
59
59
  ```
60
60
 
61
61
  ## Doctrine every genre follows
62
62
 
63
+ - **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
+ - **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.
63
65
  - **`docs/architecture/`** is the design layer in four folders: **`packages/`** (one per project package — what it is and how it behaves), **`systems/`** (one per machine spanning packages), **`common/`** (the enterprise plane) and **`decisions/`** (the ADs, one per subject, updated in place, each journey confined to that file's Decision Changelog tail).
64
66
  **`common/` 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.
65
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 `common/` and owns nothing — 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.
66
68
  - **`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.
67
69
  - **`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.
68
- - **`docs/research/`** holds records, not authorities: its standing-research folders and loose notes ground plans and decisions, and its `Readme.md` lists every folder so the `brainstorm` skill reads it instead of scanning.
70
+ - **`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.
69
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/common/`. 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.
70
72
  **`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**.
71
73
  - **`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.
72
- - **`type:` is a required frontmatter key** on every doc that carries frontmatter — the genre stamp, its enum being the `documentation` skill's template names (`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.
73
- **No genre is frontmatter-less by policy; the gaps are the templates.** `architecture/common/**` carries `type: doctrine` with `status:` and `objects:` and no `owns:`, from the documentation skill's doctrine template. `architecture/Readme.md` carries no block, because its template ships none and a block is never manufactured on a doc whose template has none. `architecture/packages/**` and `architecture/systems/**` carry `type: package` / `type: system` with `objects:` and `status:`, plus the transitional `owns:` region glob the ownership scan reads until it switches to source headers. The `operations/` procedures carry a hand-authored `type: operations` block; the bookkeeping queue carries none. Docs written by a skill that ships a block (`issue-bridge`'s `type: issue` / `type: triage`) carry it.
74
+ - **`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.
74
75
  - **The docs tree is a graph, and nothing in it that can be computed is typed.** A document names the objects it designs (`objects:`); a source file names the document that speaks for it in its path header; the object closure computes the rest — which files a document speaks for, and which surfaces a doctrine governs. One doc → doc edge is authored, because nothing computes it: **`verifies:`** (checklist → the doc whose promises it proves). Its inverse is **generated** — `buildEdgeIndex()` in `.claude/hooks/lib/ownership.mjs`, injected at SessionStart beside the ownership index — and authoring an inverse by hand is a defect. `applies:` is retired; `owns:` is a transitional region glob (the `documentation` skill's `references/frontmatter.md`).
75
76
  - **`docs/acceptance/` holds the acceptance-criteria genre** — one `kebab-case.md` per capability, written at specification time, before implementation, holding stable `AC-n` assert lines that verification surfaces parse as claims to grade the built product against; each file is keyed to the checklist sections that grade it. The folder is created on first use and never scaffolded. The `AC-n:` line grammar is load-bearing: the key sits at line start, exactly `AC-<number>:`, followed by the assert sentence — tables, emphasis-wrapped keys, and nested bullets break the parse.
76
- - **The `ux` genre decides observable behavior; `docs/tests/` only verifies it.** A feature doc states what a feature is and which contracts it honours — all of which stay plausibly true through a rewrite of the surface — so a UX-behavior doc states what a person *observes*, and is written **before** the code. This repo holds no standalone `ux` document: what a person observes on a surface is a section of the feature doc that owns that surface's components and wire. A surface needing the genre gets `features/{surface}-ux.md`, named in the headers of the component files no other document speaks for; where a feature document already speaks for them, the UX document is named in its coordinated-edits row.
77
- - **`docs/history/journal.md` is the temporary lane, and `docs/memory/` is not.** The journal holds mid-execution facts one line each, each resolved by landing in its owning doc; memory holds only per-agent strategy and project knowledge no single doc owns. A fact an owning doc will eventually carry goes to the journal, never to memory — memory has no drain, so what lands there stays until somebody distils it.
77
+ - **The `ux` genre decides observable behavior; `docs/tests/` only verifies it.** A feature doc states what a feature is and which contracts it honours — all of which stay plausibly true through a rewrite of the surface — so a UX-behavior doc states what a person *observes*, and is written **before** the code. A surface needing the genre gets `features/{surface}-ux.md`, named in the headers of the component files no other document speaks for; where a feature document already speaks for them, the UX document is named in its For the agent **See also** line.
78
+ - **`docs/history/journal.md` drains into documents, and `docs/memory/` does not.** Both are queues. The journal holds mid-execution facts one line each, each resolved by landing in its owning doc; memory holds only per-agent strategy and project knowledge no single doc owns, compacted by its writer. A fact an owning doc will eventually carry goes to the journal, never to memory — nothing drains memory into a document, so what lands there stays until its writer retires it.
78
79
  - **There is no `docs/history/sessions/`.** Per-session gate logs are machine-local, written by `.claude/hooks/lib/session-log.mjs` into `.claude/state/sessions/` (self-ignored), so they never enter `docs/` or git. A `docs/history/sessions/` folder is residue, not shape.
79
80
  - **The repo-root `README.md` opens outward and turns inward.** What the product does, for whom and where it runs, in a user's terms; then, for the team and agents, how it works, a Map of top-level units with their owning doc, the rules that bite, where to go by intent, and at most four everyday commands. It carries no install, stack or tree — install and stack are `operations/setup.md`, the tree is this file's. Template: the `documentation` skill's `templates/root-readme.md`.
80
81
  - **`docs/README.md` describes directories, never files.** One entry per folder: what it holds, who reads it, how its files are named — no per-file rows, no tree. It closes with the repository's own notes, the one place project-specific placement facts live.
@@ -84,12 +85,12 @@ docs/
84
85
 
85
86
  ## Lifecycle
86
87
 
87
- - **Plans** (`history/plans/YYYY-MM-DD-{slug}.md`) carry a `Status:` field (`Draft` / `Ready` / `Active` / `Executed` / `Complete` / `Abandoned`). Once `Complete`/`Abandoned`, a plan is frozen — never edited; scope changes get a new dated plan that links back.
88
+ - **Plans** (`history/plans/YYYY-MM-DD-{slug}.md`) carry a `Status:` field (`Draft` / `In Progress` / `Complete` / `Abandoned`). Once `Complete`/`Abandoned`, a plan is frozen — never edited; scope changes get a new dated plan that links back.
88
89
  - **Migration runbooks** (`history/migrations/YYYY-MM-DD-{slug}.md`) are authored ahead of execution and record a one-shot infra/cutover procedure; once executed, the outcome is stamped into the file and it is frozen — a re-run gets a new dated runbook.
89
- - **Changelog** entries land in `history/changelog/` and are indexed in `history/CHANGELOG.md`.
90
- - **Backlog** items live in `history/backlog.md` under P0–P3 priorities (living, append-only).
91
- - **Brainstorm sessions** are author-created by the `brainstorm` skill: an active session at `docs/research/{topic}-brainstorm/` (older folders carry the legacy `-brainstorming/` suffix; both are canonical), moved to `docs/history/brainstorms/{topic}/` on a passed harvest — the move is the completion marker, and the moved folder's fate (delete or commit) is the author's call. Never scaffolded empty; each folder carries a `Readme.md` index.
92
- - **Source-of-truth audits** write nothing to `docs/`. The `polygraph` skill runs in two modes — **audit** on a named target (a doc, a feature, a folder, a code path) and **gate** at plan completion — and both keep their rows under `.claude/state/polygraph/{run}/`, machine-local, never tracked, deleted in the same turn as the report. What survives a run is the corrected document itself, the backlog rows it registered, and the plan's `Polygraph:` segment. Folders an earlier audit mode left behind are provenance a repo lists in its `README.md` notes, never a place anything writes.
90
+ - **Changelog** entries land in `history/changelog/`, one per unit of work, each opening on its one-line summary. `history/CHANGELOG.md` is the folder's guide and takes no row per entry; listing the folder is the index.
91
+ - **Backlog** items live in `history/backlog.md` under P0–P3 priorities — a queue: appended, and deleted when the work lands.
92
+ - **Brainstorm sessions** are author-created by the `brainstorm` skill: an active session at `docs/research/{topic}-brainstorm/` (older folders carry the legacy `-brainstorming/` suffix; both are canonical), moved to `docs/history/brainstorms/{topic}/` on a passed harvest — the move is the completion marker, and the moved folder's fate (delete or commit) is the author's call. Never scaffolded empty; no index keeps a row per session.
93
+ - **Source-of-truth audits** write nothing to `docs/`. The `polygraph` agent runs only when the user asks, on a named target (a doc, a feature, a folder, a code path or a plan), and keeps its rows under `.claude/state/polygraph/{run}/`, machine-local, never tracked, deleted in the same turn as the report. What survives a run is the corrected document itself and the backlog rows it registered; a run against a plan also leaves a `Polygraph:` segment on its `Gates:` line, which nothing reads.
93
94
  - **Boundaries** are a plan-time diagnostic — the `boundary` skill reads contracts fresh from source; there is no persisted `boundaries/` tree.
94
95
  - **Modules** are _declared labels_ (a `module:` key on a feature doc), never inferred from physical layout and never a folder. A feature always lives flat in `features/`.
95
96
 
@@ -97,31 +98,45 @@ docs/
97
98
 
98
99
  ## Add-a-doc decision table
99
100
 
100
- | You are adding… | It goes in… | Needs frontmatter? |
101
+ The `type:` column is the value the document carries; its required keys and sections are the genre registry's row for that type.
102
+
103
+ | You are adding… | It goes in… | `type:` |
101
104
  | --- | --- | --- |
102
- | A feature document — something a person points at (an address, a command family, a named control), cut by the objects it designs | `features/` (flat) | Yes — `type: feature`, `objects:`, `status:` (+ optional `module:`, `last-reviewed:`; a transitional `owns:` region glob) |
103
- | A package's behavior document | `architecture/packages/<package>.md`, one per package | Yes — `type: package`, `objects:`, `status:` (+ the transitional `owns:` over its tree, residually) |
104
- | A system's behavior document | `architecture/systems/{system}.md`, one per machine | Yes — `type: system`, `objects:`, `status:` (+ the transitional `owns:` over the machine's subtrees) |
105
- | Cross-cutting design / steering (doctrine) | `architecture/common/` | Yes — `type: doctrine`, `objects:`, `status:` |
106
- | An Architecture Decision (AD) | `architecture/decisions/` — one file per subject, updated in place; the journey lives in that file's Decision Changelog | Yes — `type: architecture-decision` (+ `title:`, `status:`, `created:`, `last-updated:`, `decision-owner:`, `tags:`) |
107
- | One-time machine setup, first run, stack, prerequisites, env files | `operations/setup.md` — fixed name, one per repo, linked from the root README; a diverging package gets a `### {unit}` subsection, never a second first-run doc | Yes — `type: operations` |
108
- | A recurring procedure (develop, deploy, rotate, diagnose, CI) | `operations/{procedure}.md` | Yes — `type: operations` |
109
- | A tracker issue held in the repo | `operations/issues/YYYY-MM-DD-{slug}.md` (via the `issue-bridge` skill's local pack) | Yes — `type: issue`, `id:`, `status:`, `labels:`, `author:`, `created:`, `github:` |
110
- | A triage dossier for an investigated issue | `operations/triage/YYYY-MM-DD-{slug}.md` (via the `issue-bridge` skill) | Yes — `type: triage`, `tracker:`, `issue:`, `date:`, `confidence:`. A dated working artifact: it never claims `owns:` and never masquerades as a feature doc |
111
- | A behavioral test checklist | `tests/{feature}.md` | Yes — `type: checklist`, `verifies:` (the doc(s) whose promises it proves; several values are legitimate). No `owns:` — it owns no code. Truth doc, present-tense; written at the verification gate before the driving, each section carrying a `Pinned:` trace |
112
- | 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 section of the owning feature doc where the surface has one owner; `architecture/common/` when it is cross-cutting | Yes — `type: ux` (+ the feature-doc keys when it lives in `features/`) |
113
- | Acceptance criteria for one capability | `acceptance/{capability}.md` — stable `AC-n` assert lines verification surfaces parse as claims; keys are never renumbered or reused, a retired criterion is marked retired in place | Yes — `type: acceptance-criteria`, `status:`; no `owns:` (owns no code) |
114
- | An in-progress brainstorm session | `research/{topic}-brainstorm/` (via the `brainstorm` skill) | No |
115
- | A source-of-truth audit | Nowhere in `docs/` — the `polygraph` skill (audit mode) corrects the target doc in place and keeps its rows under `.claude/state/polygraph/{run}/`, deleted with the report | No |
116
- | An implementation plan | `history/plans/YYYY-MM-DD-{slug}.md` | No (but `Status:` required) |
117
- | A one-shot migration runbook | `history/migrations/YYYY-MM-DD-{slug}.md` | No (authored ahead; outcome-stamped and frozen once executed) |
118
- | A deep-research record | `history/research/{topic}/` — `README.md` synthesis + `findings.md` + `sources.md`; frozen and cited, owns no code, never edited to stay current (a new question gets a new topic folder) | No |
119
- | A harvested brainstorm session | `history/brainstorms/{topic}/` (via the `brainstorm` skill's harvest) | No |
120
- | A changelog entry | `history/changelog/` + index in `CHANGELOG.md` | No |
121
- | A tracked work item | `history/backlog.md` | No |
122
- | A doc-sync debt row | `operations/bookkeeping.md` (hook-appended; drained by the `bookkeeper` agent, deleted on drain) | No |
123
- | A mid-execution fact worth keeping | `history/journal.md` (append-only; resolves by landing in its owning doc) | No |
124
- | Agent strategy / project memory | `memory/` | Yes — `type: project-memory` on `main.md` |
105
+ | 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; `architecture/common/` when it is cross-cutting | `type: ux` |
107
+ | A package's behavior document | `architecture/packages/{package}.md`, one per package | `type: package` |
108
+ | A system's behavior document | `architecture/systems/{system}.md`, one per machine | `type: system` |
109
+ | Cross-cutting design (doctrine) | `architecture/common/{concern}.md` | `type: doctrine` |
110
+ | The testing strategy | `architecture/common/testing.md` | `type: testing-strategy` |
111
+ | 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
+ | The system at a glance | `architecture/system-design.md` | `type: system-overview` |
113
+ | The domain model | `architecture/domain-model.md` | `type: domain-model` |
114
+ | The glossary | `architecture/glossary.md` | `type: glossary` |
115
+ | The non-goals | `architecture/non-goals.md` | `type: non-goals` |
116
+ | The security overview | `architecture/security.md` | `type: security-overview` |
117
+ | The API surface | `architecture/api.md` | `type: api-reference` |
118
+ | The environment variables | `operations/environment.md` | `type: environment-registry` |
119
+ | One-time machine setup, first run, stack, prerequisites, env files | `operations/setup.md` — fixed name, one per repo, linked from the root README; a diverging package gets a `### {unit}` subsection, never a second first-run doc | `type: operations` |
120
+ | A recurring procedure (develop, deploy, rotate, diagnose, CI) | `operations/{procedure}.md` | `type: operations` |
121
+ | The build order of a project built from its design | `operations/implementation-map.md` | `type: implementation-map` |
122
+ | The protected-files list | `operations/protected-files.md` | `type: protected-files` |
123
+ | A tracker issue held in the repo | `operations/issues/YYYY-MM-DD-{slug}.md` (via the `issue-bridge` skill's local pack) | `type: issue` |
124
+ | A triage dossier for an investigated issue | `operations/triage/YYYY-MM-DD-{slug}.md` (via the `issue-bridge` skill) — a dated working artifact that never claims `owns:` | `type: triage` |
125
+ | A behavioral test checklist | `tests/{feature}.md` — written at the verification gate before the driving, each section carrying a `Pinned:` trace; owns no code | `type: checklist` |
126
+ | Acceptance criteria for one capability | `acceptance/{capability}.md` — stable `AC-n` assert lines; keys are never renumbered or reused, a retired criterion is marked retired in place | `type: acceptance-criteria` |
127
+ | A folder's landing page | `{folder}/Readme.md` — describes the folder, never a row per file | `type: folder-index` |
128
+ | An in-progress brainstorm session | `research/{topic}-brainstorm/` (via the `brainstorm` skill) | none |
129
+ | A source-of-truth audit | Nowhere in `docs/` — the `polygraph` agent corrects the target doc in place | none |
130
+ | An implementation plan | `history/plans/YYYY-MM-DD-{slug}.md` (a `Status:` line is required) | none |
131
+ | A one-shot migration runbook | `history/migrations/YYYY-MM-DD-{slug}.md` (authored ahead; outcome-stamped and frozen once executed) | none |
132
+ | A hand-over at the end of an unattended or multi-session build | `history/handovers/YYYY-MM-DD-{slug}.md` | `type: handover` |
133
+ | A deep-research record | `history/research/{topic}/` — `README.md` synthesis + `findings.md` + `sources.md`; frozen and cited, a new question gets a new topic folder | none |
134
+ | A harvested brainstorm session | `history/brainstorms/{topic}/` (via the `brainstorm` skill's harvest) | none |
135
+ | A changelog entry | `history/changelog/YYYY-MM-DD-{three-words}.md`; `CHANGELOG.md` takes no row | none |
136
+ | A tracked work item | a row in `history/backlog.md` | none |
137
+ | A doc-sync debt row | a row in `operations/bookkeeping.md` (hook-appended; drained by the `bookkeeper` agent, deleted on drain) | none |
138
+ | A mid-execution fact worth keeping | a row in `history/journal.md` (resolves by landing in its owning doc) | none |
139
+ | Agent strategy / project memory | `memory/main.md`, `memory/{agent}.md` | `type: project-memory` on `main.md` |
125
140
 
126
141
  ---
127
142
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.20.6",
4
+ "version": "3.20.7",
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": "8aae863291c5"
32
+ "digest": "068ff439e1f9"
33
33
  }
@@ -145,13 +145,19 @@ function fileGate(projectDir, rel, sessionId) {
145
145
  // The gate binds the plan's own paths, so disjoint plans run in parallel.
146
146
  // A scopeless plan stays repo-wide — fail closed.
147
147
  if (plan.scope.length && !inPlanScope(rel, plan.scope)) continue;
148
- if (/Boundary:\s*pending/i.test(plan.gates)) {
148
+ // Only a passed verdict opens the gate: `pending` has no verdict yet, and `blocked` is a verdict against coding.
149
+ const boundary = /Boundary:\s*(\w+)/i.exec(plan.gates);
150
+ if (boundary && !/^passed$/i.test(boundary[1])) {
149
151
  return deny(
150
152
  projectDir,
151
153
  sessionId,
152
154
  "plan-gate",
153
155
  plan.file,
154
- `BLOCKED — plan gate. \`${plan.file}\` is open but its Gates line reads 'Boundary: pending'. Run the \`boundary\` skill and record its verdict in the plan before implementation edits.`
156
+ `BLOCKED — plan gate. \`${plan.file}\` is open but its Gates line reads 'Boundary: ${boundary[1]}'. ${
157
+ /^blocked$/i.test(boundary[1])
158
+ ? "Fold the `boundary` skill's amendments into the plan and re-run it until it records `passed`."
159
+ : "Run the `boundary` skill and record its verdict in the plan before implementation edits."
160
+ }`
155
161
  );
156
162
  }
157
163
  if (!plan.hasLedger) {
@@ -24,13 +24,14 @@ import { readSafe, docsRoot } from "./repo.mjs";
24
24
  import { resolveRows } from "./state.mjs";
25
25
  import { rejectedPackages } from "./approved.mjs";
26
26
 
27
- // Spawn the installed doc-lint over one file; returns finding lines (empty when absent/clean).
27
+ // Spawn the installed doc-lint over one file; returns its block-severity finding lines (empty when absent/clean),
28
+ // so a warning advises and only a blocking rule raises a row that walls the commit — as sourceLint() below.
28
29
  export function docLint(projectDir, rel) {
29
30
  const script = path.join(projectDir, ".claude", "skills", "documentation", "scripts", "doc-lint.mjs");
30
31
  if (!fs.existsSync(script)) return [];
31
32
  const res = spawnSync("node", [script, rel], { cwd: projectDir, encoding: "utf8", timeout: 5000 });
32
33
  const out = `${res.stdout || ""}`;
33
- return out.split("\n").filter((line) => /:\d+ \[(block|warn)\]/.test(line));
34
+ return out.split("\n").filter((line) => /:\d+ \[block\]/.test(line));
34
35
  }
35
36
 
36
37
  // True when the first path-shaped token in a source file's opening lines IS its repo-relative path.
@@ -1,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- Every unit of work leaves one record — `docs/history/changelog/YYYY-MM-DD-{three-words}.md` (the three words name the work, not the commit) — plus its row in `docs/history/CHANGELOG.md`, appended in the same pass so the index never trails the folder. Entry format, field rules, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`; this rule owns when an entry is owed and how it lives. An entry is never a commit summary — it carries the refinement context only the working session holds, which no diff reconstructs.
3
+ Every unit of work leaves one record — `docs/history/changelog/YYYY-MM-DD-{three-words}.md` (the three words name the work, not the commit). `docs/history/CHANGELOG.md` is the folder's guide, never appended to: the entry's own first line is its summary, and listing the folder is the index. Entry format, field rules, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`; this rule owns when an entry is owed and how it lives. An entry is never a commit summary — it carries the refinement context only the working session holds, which no diff reconstructs.
4
4
 
5
5
  ## When an entry is owed
6
6
 
@@ -7,35 +7,38 @@ description: "Use when a plan or diff might break a cross-cutting contract. Boun
7
7
 
8
8
  You diagnose whether a plan's changes would break an application boundary.
9
9
 
10
- A boundary is a contract between two pieces of code (or code and infra) that share an assumption with **no static link** between them: the column a raw SQL string names, the JSON envelope a client unwraps, the event string a dispatcher parses, the env var a deploy script writes. Changing one side ships green — compiles, lints, tests pass — and breaks the other at runtime. Your job is to find those edges in the plan's path _before_ execution.
10
+ A boundary is a contract between two pieces of code (or code and infra) that share an assumption with **no static link** between them: the column a raw SQL string names, the JSON envelope a client unwraps, the event string a dispatcher parses, the env var a deploy script writes. Changing one side ships green — compiles, lints, tests pass — and breaks the other at runtime. Find those edges in the plan's path _before_ execution.
11
11
 
12
- **The litmus is "would it ship green?"** An edge the compiler or an existing test already guards is not a boundary — a change that fails the build loudly needs no diagnostic. Spend your reading on the edges with no static link.
12
+ **The litmus is "would it ship green?"** An edge the compiler or an existing test already guards is not a boundary — spend your reading on the edges with no static link.
13
13
 
14
14
  ## Contract sources
15
15
 
16
16
  Three layers tell you what to look for; the code tells you what exists.
17
17
 
18
- - **The mechanisms** — [`references/mechanisms.md`](references/mechanisms.md) defines the seven failure mechanisms every boundary instantiates (rendezvous-string, serialized-shape, generated-artifact, dual-authority, config-elsewhere, trust-invariant, lifecycle-protocol), each with its trace strategy, universal safe-change pattern, and severity heuristic, plus the two stack-independent domain contracts (entity-model, tenancy). Load it on every check.
19
- - **The technology packs** — [`references/index.md`](references/index.md) routes to the packs under `references/packs/` by the signals in the touched code. Each pack carries the non-derivable payload for one technology area: exact detect patterns, expensive-to-learn gotchas, and safe-change sequences. Load **only the packs the touch list exhibits**; a technology no pack covers is still in scope — diagnose it from its mechanism.
20
- - **Repo doctrine** — `.claude/rules/`, `docs/architecture/` (including `decisions/`), and any contracts package name the repo's bespoke contracts (a documented response envelope, a schema-parity rule, an entity model). A documented contract is a real side of a boundary: a plan that contradicts one is a finding **even when no code consumer exists yet** — this is how greenfield plans, whose modules have no code to trace, still get checked.
21
-
22
- The packs are a floor, not a fence: report any contract that passes the ships-green litmus, pack entry or not.
18
+ - **The mechanisms** — [`references/mechanisms.md`](references/mechanisms.md): the seven failure mechanisms every boundary instantiates (rendezvous-string, serialized-shape, generated-artifact, dual-authority, config-elsewhere, trust-invariant, lifecycle-protocol), each with its trace strategy, universal fix, and severity, plus the two stack-independent domain contracts (entity-model, tenancy). Load it on every check.
19
+ - **The technology packs** — [`references/index.md`](references/index.md) routes to the packs under `references/packs/` by the signals in the touched code; each pack carries one technology area's detect patterns, gotchas, and safe-change sequences. Load **only** the packs the touch list exhibits. The packs are a floor, not a fence: a contract no pack covers is still in scope — diagnose it from its mechanism and report it if it passes the litmus.
20
+ - **Repo doctrine** — `.claude/rules/`, `docs/architecture/` (including `decisions/`), and any contracts package name the repo's bespoke contracts (a documented response envelope, a schema-parity rule, an entity model). A documented contract is a real side of a boundary: a plan that contradicts one is a finding **even when no code consumer exists yet** — this is how a greenfield plan, with no code to trace, still gets checked.
23
21
 
24
22
  ## Run
25
23
 
26
- **Input:** a plan path (given, or the newest in `docs/history/plans/`) — or a diff / named code area for non-plan work. Everything below is identical either way; a diff's hunks stand in for the plan's steps.
24
+ **Input:** a plan path (given, or the newest in `docs/history/plans/`) — or a diff or named code area for non-plan work, where the diff's hunks stand in for the plan's steps. Steps 1–5 are identical either way; the report's **Missing plan subsections** and **Docs the plan's ledger missed** sections, and step 6, apply only to a plan.
25
+
26
+ 1. **Build the touch list.** Parse the plan's Proposed Changes: files created or modified, entities or state added or changed, API changes, anything the author flags as a cross-module contract. Note missing subsections.
27
+
28
+ 2. **Identify the contracts.** Read each touched file and its immediate imports. Against the mechanisms, the routed packs, and the repo doctrine, list the contracts this code participates in — the schema it queries, the envelope it emits, the events it publishes or parses, the auth checks it sits behind, the env it reads.
27
29
 
28
- 1. **Build the touch list.** Parse the plan's Proposed Changes: files created or modified, entities/state added or changed, API changes, anything the author flags as a cross-module contract. Note missing subsections.
30
+ 3. **Trace the other side.** The danger lives on the side the plan _doesn't_ mention. For each contract, grep the shared name or shape across the repo — the column name in other SQL strings, the response field in client unwrappers, the event kind in subscribers, the route in fetch calls and scripts, the env key in deploy tooling. Record consumers as `file:line`, doctrine as the doc path. At ≳10 contracts, fan the tracing out to parallel sub-agents — one per pack area, each prompt self-contained with its contracts and grep targets — and judge the returned evidence yourself; a small diff traces inline.
29
31
 
30
- 2. **Identify the contracts.** Read each touched file (and its immediate imports). Against the mechanisms, the routed packs, and the repo doctrine, list the contracts this code participates in — the schema it queries, the envelope it emits, the events it publishes or parses, the auth checks it sits behind, the env it reads.
32
+ 4. **Judge each intersection.** Does the planned change alter a shape a traced consumer depends on, break an invariant the code or doctrine establishes (append-only vocabularies, idempotency keys, fail-closed checks, ordering guarantees), or introduce a new cross-module edge? Grade it:
31
33
 
32
- 3. **Trace the other side.** A boundary has two sides; the danger lives on the one the plan _doesn't_ mention. For each contract, grep the shared name or shape across the repo — the column name in other SQL strings, the response field in client unwrappers, the event kind in subscribers, the route in fetch calls and scripts, the env key in deploy tooling. Record consumers as `file:line`; record doctrine as the doc path. When the touch list is large (≳10 contracts), fan the tracing out to parallel sub-agents — one per pack area, each with a self-contained prompt naming its contracts and grep targets — and judge the returned evidence yourself; a small diff traces inline.
34
+ | Severity | Meaning |
35
+ | --- | --- |
36
+ | **CRITICAL** | Can corrupt persisted data, or open an auth/money path — trust-invariants and persisted or replayed shapes live here |
37
+ | **HIGH** | Silent cross-module breakage that ships green |
38
+ | **MEDIUM** | Drift-prone coupling not yet broken (string-matched, duplicated constants) |
39
+ | **LOW** | Smell |
33
40
 
34
- 4. **Judge each intersection.** Does the planned change alter a shape a traced consumer depends on, break an invariant the code or doctrine establishes (append-only vocabularies, idempotency keys, fail-closed checks, ordering guarantees), or introduce a new cross-module edge? Severity:
35
- - **CRITICAL** — can corrupt persisted data, or open an auth/money path.
36
- - **HIGH** — silent cross-module breakage that would ship green.
37
- - **MEDIUM** — drift-prone coupling (string-matched, duplicated constants).
38
- - **LOW** — smell. Loud, immediately-visible runtime breakage caps at HIGH.
41
+ Loud, immediately visible runtime breakage caps at HIGH. Severity is intrinsic to the finding, never curved — three genuine CRITICALs in a small repo is signal, not inflation.
39
42
 
40
43
  5. **Report in chat:**
41
44
 
@@ -61,15 +64,23 @@ The packs are a floor, not a fence: report any contract that passes the ships-gr
61
64
  | Feature doc | Owned path in the touch list | In Doc Obligations? |
62
65
  ```
63
66
 
64
- **The doc cross-check is free and you are the only one who can make it.** You already hold the touch list; resolving those paths against the ownership index and comparing the result to the plan's **Doc Obligations** rows costs one lookup. The plan's author wrote that ledger, so it is the one gate artifact nobody independently checked — a `None` that contradicts your touch list is the failure this section exists to catch. Report the gap; never edit the ledger yourself.
67
+ **Fill the doc cross-check from the touch list you already hold:** resolve its paths against the ownership index and compare the result to the plan's **Doc Obligations** rows. The plan's author wrote that ledger and nobody else checks it — a `None` that contradicts your touch list is the failure this section catches. Report the gap; **never** edit the ledger yourself.
68
+
69
+ **BLOCK** = any CRITICAL; a blocked plan folds the amendments and re-runs the check. HIGH findings yield **PASS WITH AMENDMENTS** — the invoking session folds the amendments into the plan in the same pass, before the plan is shown as finished. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the pack entry's **Safe change** or the mechanism's **Universal fix**.
70
+
71
+ 6. **Record the verdict in the plan's `Gates:` line.** Rewrite only your own segment, to exactly one of:
65
72
 
66
- **BLOCK** = any CRITICAL. HIGH findings yield **PASS WITH AMENDMENTS** — the invoking session folds the amendments into the plan in the same pass, before the plan is shown as finished. Order amendments sequencing-first: many violations dissolve by reordering steps (expand-then-contract, migrate-before-code) rather than changing what ships — prefer that fix, drawn from the entry's safe-change sequence.
73
+ | Verdict | Segment |
74
+ | --- | --- |
75
+ | PASS | `Boundary: passed YYYY-MM-DD` |
76
+ | PASS WITH AMENDMENTS | `Boundary: passed YYYY-MM-DD` — written only once the amendments are folded |
77
+ | BLOCK | `Boundary: blocked YYYY-MM-DD` |
67
78
 
68
- 6. **Record the verdict in the plan's `Gates:` line.** Rewrite only your own segment, to exactly `Boundary: passed YYYY-MM-DD` (PASS, or PASS WITH AMENDMENTS once the amendments are folded) or `Boundary: blocked YYYY-MM-DD` (BLOCK). The compliance hook greps exactly this segment — implementation edits inside the plan's scope stay blocked while it reads `Boundary: pending` (the other gates are enforced by section presence, not segment text). A plan with no `Gates:` line predates the format; add the line rather than skipping the write-back.
79
+ The compliance hook greps exactly this segment and blocks implementation edits inside the plan's scope until it reads `passed` — `pending` and `blocked` wall alike (the other gates are enforced by section presence, not segment text). A plan with no `Gates:` line gets one added; never skip the write-back.
69
80
 
70
81
  ## Rules
71
82
 
72
- - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the invoking session folds your amendments into the plan in the same pass, then writes the segment to `passed`; a plan is not finished until it does. The single write you own is the plan's `Gates:` line (step 6), your segment only.
73
- - **Verify in source.** Never flag from plan text alone — read both sides of every finding and cite them: code as `file:line`, doctrine as the doc path.
74
- - **No other side, no violation.** An intersection with no traced consumer and no doctrine behind it isn't a violation — it's a **new edge**: report it in its own section with the hardening its mechanism prescribes (version the cache key now, make the enum append-only now), so the fragile edge is born safe.
83
+ - **Read-only, one exception.** You never edit the plan's content, the code, or any doc — the invoking session folds your amendments into the plan; a plan is not finished until its segment reads `passed`. The single write you own is the plan's `Gates:` line (step 6), your segment only.
84
+ - **Verify in source.** **Never** flag from plan text alone — read both sides of every finding and cite them: code as `file:line`, doctrine as the doc path.
85
+ - **No other side, no violation.** An intersection with no traced consumer and no doctrine behind it is a **new edge**, not a violation: report it in its own section with the hardening its mechanism prescribes (version the cache key now, make the enum append-only now), so the fragile edge is born safe.
75
86
  - **A clean report is valid.** Zero violations means say so — the coverage table is the evidence it was checked, not skipped. Don't pad findings.
@@ -1,16 +1,14 @@
1
1
  # Pack routing index
2
2
 
3
- Load when: every boundary check, right after `mechanisms.md`. Match the touch list against the signals below and load **only** the packs whose signals appear in the touched files or the plan's Proposed Changes. Several packs matching is normal (a full-stack feature typically routes 2–4). A technology matching nothing here is still in scope — diagnose it from its mechanism, and check `packs/generic-tail.md` for a thin entry.
3
+ Load when: every boundary check, right after `mechanisms.md`. Match the touch list against the signals below and load **only** the packs whose signals appear in the touched files or the plan's Proposed Changes — a full-stack feature typically routes 2–4. A technology matching no row has a thin entry in `packs/generic-tail.md` or none; either way, diagnose it from its mechanism.
4
4
 
5
5
  | Pack | Load when the touch list shows |
6
6
  | --- | --- |
7
7
  | `packs/persistence.md` | `schema.ts`, `init.sql`, `sqliteTable(`, `drizzle-kit`, `pgTable`, migrations, `*.seed.sql`, seed generators, JSON columns, `pgEnum`, pgvector, Redis `get`/`set` caching |
8
8
  | `packs/wire-api.md` | Express routes/middleware (`app.use(`, `router.`), `res.json({ status`, zod schemas on requests, axios clients/interceptors, `cors(`, inbound webhooks, `rateLimit(` |
9
- | `packs/frontend.md` | `createSlice`/`configureStore`, RTK Query (`tagTypes`), react-router tables/`useParams`, Tailwind CSS (`@theme`, `personality.css`, `globals.css`), `vite.config.*` (alias, env), `@nurix/components`, localforage/redux-persist, date formatting |
9
+ | `packs/frontend.md` | `createSlice`/`configureStore`, RTK Query (`tagTypes`), react-router tables/`useParams`, Tailwind CSS (`@theme`, `personality.css`, `design.tokens.css`, `globals.css`), `vite.config.*` (alias, env), `@nurix/components`, localforage/redux-persist, date formatting |
10
10
  | `packs/auth.md` | `jwtVerify(`/jose, `betterAuth(`/`auth.api.`, session cookies, CSRF, OAuth callbacks/`redirect_uri`, `tenantId`/`organizationId` scoping, password hashing, auth middleware mounts |
11
11
  | `packs/cloudflare.md` | `wrangler.jsonc`/`wrangler.toml`, `env.X` bindings, `extends DurableObject`/`[[migrations]]`, KV/R2/D1/Queues, `scheduled(`/crons, `WorkerEntrypoint`, `compatibility_date`, static assets config |
12
12
  | `packs/async-messaging.md` | BullMQ (`new Queue(`/`new Worker(`), Redis pub/sub or Streams, WebSockets/socket.io, SSE (`text/event-stream`), channel-name templates, outbound webhook senders |
13
13
  | `packs/build-config-runtime.md` | `package.json` (deps/`exports`/scripts/`packageManager`), lockfiles, `.env*`, tsconfig `paths`, Dockerfiles/compose, `.github/workflows/`, pino config, `trust proxy`, ports/healthchecks |
14
14
  | `packs/generic-tail.md` | GraphQL, gRPC/protobuf, tRPC, OpenAPI codegen, Kafka/schema registry/CDC, workflow engines, event sourcing, Postgres RLS/pooling/collation, SSR/hydration, module federation, i18n, analytics plans, hosted feature flags, K8s probes/shutdown/limits, service mesh, IaC outputs, SAML, Lambda, IPC |
15
-
16
- Two files never route — they always load: `mechanisms.md` (the seven failure mechanisms + domain contracts) and this index.
@@ -1,10 +1,8 @@
1
1
  # Boundary Mechanisms
2
2
 
3
- Load when: every boundary check — this is the core reference. The technology packs under `packs/` instantiate these mechanisms with exact detect signals and gotchas; `index.md` routes to the packs the touched code exhibits.
3
+ Load when: every boundary check — this is the core reference. The packs under `packs/` instantiate these mechanisms with exact detect signals and gotchas.
4
4
 
5
- A boundary is a contract between two pieces of code (or code and infra) that share an assumption with **no static link** between them. The litmus is **"would it ship green?"** — change one side, everything compiles, lints, and tests pass, and the other side breaks at runtime. An edge the compiler or an existing test already guards is not a boundary.
6
-
7
- Every boundary instantiates one of seven mechanisms. The mechanism tells you what to grep for, what the universal fix is, and how bad a break is — including for technologies no pack covers. When touched code exhibits a contract that matches no pack entry, diagnose it from its mechanism.
5
+ Every boundary instantiates one of seven mechanisms. The mechanism tells you what to grep for, what the universal fix is, and how bad a break is — which is how you diagnose a technology no pack covers.
8
6
 
9
7
  ---
10
8
 
@@ -91,9 +89,4 @@ Two contracts come from the product's information architecture, not from any tec
91
89
 
92
90
  ## Severity recap
93
91
 
94
- - **CRITICAL** — can corrupt persisted data, or open an auth/money path. Trust-invariants and persisted/replayed shapes live here.
95
- - **HIGH** — silent cross-module breakage that ships green.
96
- - **MEDIUM** — drift-prone coupling (string-matched, duplicated constants) not yet broken.
97
- - **LOW** — smell. Loud, immediately-visible runtime breakage caps at HIGH; statically-guarded edges are out of scope entirely.
98
-
99
- Severity is intrinsic to the finding, not curved: three genuine CRITICALs in a small repo is correct signal, not inflation.
92
+ The scale is `SKILL.md` step 4; each mechanism's **Severity** line above places a finding on it.
@@ -1,6 +1,6 @@
1
1
  # Pack: frontend / client state / UI build
2
2
 
3
- Load when: the touch list exhibits Redux Toolkit (`createSlice`, `configureStore`), RTK Query tags, react-router route tables, Tailwind 4 CSS (`@theme`, `personality.css`, `globals.css`), Vite config (`resolve.alias`, env), `@nurix/components` imports, localforage/redux-persist, or date handling crossing the wire.
3
+ Load when: the touch list exhibits Redux Toolkit (`createSlice`, `configureStore`), RTK Query tags, react-router route tables, Tailwind 4 CSS (`@theme`, `personality.css`, `design.tokens.css`, `globals.css`), Vite config (`resolve.alias`, env), `@nurix/components` imports, localforage/redux-persist, or date handling crossing the wire.
4
4
 
5
5
  ## redux-persist-shape-migration — CRITICAL · serialized-shape
6
6
  **Contract:** State shapes frozen in the user's browser storage by redux-persist must be readable by the *current* reducers' `initialState` — `version`/`migrate` is the only bridge, and `whitelist`/`blacklist` reference reducer-map keys by literal string.
@@ -51,10 +51,10 @@ Load when: the touch list exhibits Redux Toolkit (`createSlice`, `configureStore
51
51
  **Safe change:** Grep both consumer forms — utility stems (`bg-old`, `text-old`) and `var(--…-old)` including `node_modules/@nurix/components` dist CSS; keep the old token as an alias for one release; visually diff themed screens after the rename.
52
52
 
53
53
  ## tailwind-theme-inline-indirection — HIGH · config-elsewhere
54
- **Contract:** `@theme inline { --color-primary: var(--primary) }` makes utilities emit the *referenced* variable (`background-color: var(--primary)`), resolved per-element at runtime — the org's theming (personality.css vars swapped under `[data-theme]`/`[data-style]`) only flows through utilities via the `inline` form.
55
- **Detect:** `@theme inline`, plain `@theme {`, token values that are `var(--…)`, `[data-theme=`/`[data-style=` blocks in `personality.css`
56
- **Ships green, breaks:** Adding a var-referencing token to a plain (non-`inline`) `@theme` block compiles and looks correct in the default theme; switching `data-theme`/`data-style` then silently fails to restyle those utilities, because the theme variable captured the referenced var's value as resolved at `:root` — subtree/attribute-scoped overrides never reach it. No warning, no error; only the alternate theme is wrong.
57
- **Safe change:** Any token whose value is `var(--app-var)` goes in the `@theme inline` block, raw literal values in plain `@theme`; after adding tokens, toggle `data-theme` and `data-style` in devtools and confirm the new utilities respond in both states.
54
+ **Contract:** `@theme inline { --color-primary: var(--primary) }` makes utilities emit the *referenced* variable (`background-color: var(--primary)`), resolved per-element at runtime — the org's theming (token values swapped under `.dark`, and the personality.css `:root`/`.dark` overrides) only flows through utilities via the `inline` form.
55
+ **Detect:** `@theme inline`, plain `@theme {`, token values that are `var(--…)`, `:root:not(.dark)`/`:root.dark` blocks in `design.tokens.css`, `:root`/`.dark` blocks in `personality.css`
56
+ **Ships green, breaks:** Adding a var-referencing token to a plain (non-`inline`) `@theme` block compiles and looks correct in light mode; toggling `.dark` or recompiling the personality then silently fails to restyle those utilities, because the theme variable captured the referenced var's value as resolved at `:root` — mode-scoped and subtree overrides never reach it. No warning, no error; only the alternate mode is wrong.
57
+ **Safe change:** Any token whose value is `var(--app-var)` goes in the `@theme inline` block, raw literal values in plain `@theme`; after adding tokens, toggle the `.dark` class on the root element in devtools and confirm the new utilities respond in both modes.
58
58
 
59
59
  ## tailwind-source-detection — HIGH · generated-artifact
60
60
  **Contract:** The generated stylesheet contains only class names that appear as complete, unbroken literal strings in scanned source files — the build-time scanner vs class names assembled at runtime; the default scan set skips `.gitignore`d paths and `node_modules`.
@@ -62,16 +62,16 @@ Load when: the touch list exhibits Redux Toolkit (`createSlice`, `configureStore
62
62
  **Ships green, breaks:** `bg-${color}-500` builds and renders unstyled — the utility is simply absent from the CSS. Class names stored in data or composed in unscanned code work only as long as some scanned file coincidentally contains the same literal — deleting that last literal usage breaks a "different" feature. Gitignored source directories are silently excluded from scanning.
63
63
  **Safe change:** Always write full class literals and select via lookup maps (`{primary: 'bg-blue-600'}[variant]`); safelist genuinely dynamic sets with `@source inline("…")` (v4.1+); add explicit `@source "…"` for out-of-tree or ignored directories.
64
64
 
65
- ## dark-variant-data-attributes — HIGH · rendezvous-string
66
- **Contract:** `@custom-variant dark (&:where([data-theme=dark] *))` and the personality selectors `[data-theme="…"]`/`[data-style="…"]` rendezvous on the exact attribute name+value that runtime JS stamps on `<html>` (`document.documentElement.dataset.theme/style`).
67
- **Detect:** `@custom-variant dark`, `[data-theme=`, `[data-style=`, `dataset.theme`, `setAttribute('data-theme'`, `classList.add('dark')`
68
- **Ships green, breaks:** Without the `@custom-variant dark` override, Tailwind's default `dark:` variant is the `prefers-color-scheme: dark` media query — every `dark:` class silently follows the OS setting and ignores the app's toggle entirely. A value or mechanism mismatch (JS writes `class="dark"` while CSS expects `[data-theme=dark]`, or a casing typo) leaves the alternate theme unreachable with zero errors. Org default is light: base tokens must stay scoped `:root, :root[data-theme="light"]` or unstamped pages render the wrong theme.
69
- **Safe change:** Define attribute name and values as one exported constant consumed by the toggle code; add `@custom-variant dark` the moment any `dark:` utility pairs with an attribute toggle; flip the attribute in devtools and verify both directions plus the no-attribute default.
65
+ ## dark-variant-class — HIGH · rendezvous-string
66
+ **Contract:** `@nurix/components` declares `@custom-variant dark (&:is(.dark *))` and ships its dark values compiled as `.dark { … }`; the app's toggle, its own `dark:` utilities and its token blocks (`:root.dark`) rendezvous on the exact class `dark` stamped on the root element (`document.documentElement.classList`).
67
+ **Detect:** `@custom-variant dark`, `classList.add('dark')`/`classList.toggle('dark'`, `:root.dark`, `.dark {`, and the mismatch signals `[data-theme=`, `dataset.theme`, `setAttribute('data-theme'`
68
+ **Ships green, breaks:** A toggle that stamps `data-theme="dark"` instead of the class renders half-flipped with zero errors: the app's own attribute-keyed tokens invert while every library surface — its `dark:` variants, its compiled `.dark { … }` values, its theme toggle and toaster — stays light, because the library's selectors are compiled into distributed CSS and cannot be re-keyed. Without `@custom-variant dark` in the CSS entry, the app's own `dark:` classes fall back to Tailwind's default `prefers-color-scheme: dark` media query and follow the OS setting instead of the toggle. Light is the org default: light values sit on `:root:not(.dark)`, so a page with no class renders light.
69
+ **Safe change:** Toggle only the `dark` class on the root element, from a pre-paint inline script plus the persisted-preference module; bind `@custom-variant dark (&:is(.dark *))` in the CSS entry; flip the class in devtools and verify both directions, plus the no-class default, on an app surface and a library component side by side.
70
70
 
71
71
  ## nurix-components-styles-tokens — HIGH · rendezvous-string
72
- **Contract:** `@nurix/components` is imported by subpath (`@nurix/components/button`) but styled through two separate channels — its own pre-built `styles.css` (imported in `globals.css`) and the app's semantic CSS variables (personality tokens like `--radius-*`, `--color-*`) that its rules read.
73
- **Detect:** `from '@nurix/components/`, the library `styles.css` `@import` line in `globals.css`, grep `var(--` in `node_modules/@nurix/components/**/styles.css`
74
- **Ships green, breaks:** Omitting the `styles.css` import renders every component fully functional but unstyled — no JS error, no build warning, no missing-module failure. Renaming or dropping a personality token the library reads silently degrades components to fallback/`initial` values (e.g. a flat archetype's `--radius-*: 0` re-assertion lost in a token refactor). The library is pre-built, so the app's Tailwind scanner never generates utilities for markup inside it — its shipped CSS is the only style source.
72
+ **Contract:** `@nurix/components` is imported by layered subpath (`@nurix/components/element/button`) but styled through two separate channels — its `styles.css` (CSS-`@import`ed in `globals.css`) and the CSS variables its rules read: the app's theme colors and `--radius`, the `--intent-*` family, and the personality layer (`--radius-scale`, `--density-*`, `--edge-*`, `--ring-*`, `--elevation-*`).
73
+ **Detect:** `from '@nurix/components/`, the library `styles.css` `@import` line in `globals.css`, grep `var(--` in `node_modules/@nurix/components/dist/styles.css`
74
+ **Ships green, breaks:** Omitting the `styles.css` import renders every component fully functional but unstyled — no JS error, no build warning, no missing-module failure. Renaming or dropping a token the library reads silently degrades components to fallback/`initial` values (e.g. a sharp-edge personality's `--radius-scale` override lost in a token refactor). The app's Tailwind compiles the library's utilities: `styles.css` omits `@import "tailwindcss"` and carries an `@source` over the compiled JS, so its classes resolve against the app's theme — a JS `import` of `styles.css` (in `main.tsx`) compiles it standalone with no theme loaded and fails the build.
75
75
  **Safe change:** Keep the `styles.css` import at its mandated position in `globals.css`; before touching any personality token, grep the library's dist CSS for `var(--that-token)`; smoke-render a themed library component after every `@nurix/components` upgrade.
76
76
 
77
77
  ## vite-alias-tsconfig-paths — MED · dual-authority
@@ -81,10 +81,10 @@ Load when: the touch list exhibits Redux Toolkit (`createSlice`, `configureStore
81
81
  **Safe change:** Single-source the mapping (`vite-tsconfig-paths`, or generate both from one constant); update both files in the same commit on any directory move; when suspicious, log `import.meta.url` from the module in dev to see which file actually loaded.
82
82
 
83
83
  ## css-import-order — MED · lifecycle-protocol
84
- **Contract:** `globals.css` must import in the fixed sequence `@import "./personality.css"` → `@import "tailwindcss"` → the library's `styles.css` → `@theme inline {…}` — cascade-layer order is fixed at first appearance of each `@layer` name, so file position *is* the styling contract between Tailwind, the component library, and the personality tokens.
85
- **Detect:** first ~10 lines of `globals.css`, `@import "tailwindcss"`, `@import` of `@nurix/components` styles, `@layer` declarations inside the library CSS
86
- **Ships green, breaks:** Any reorder compiles and mostly renders — the breakage is visual-only and theme/element-specific: importing the library's `styles.css` before `@import "tailwindcss"` lets preflight's `@layer base` resets land after (and wipe) library button/form styling at equal specificity, and flips which side wins app-utility-vs-library override wars. Nothing logs; a form-heavy screen just looks subtly wrong.
87
- **Safe change:** Treat the four-line header as frozen; insert new global stylesheets at a deliberate position relative to `tailwindcss` and the library import, never appended blindly; after any reorder, visual-diff a form-heavy screen in every `data-theme`/`data-style` combination.
84
+ **Contract:** The CSS entry (`globals.css`, or whatever the manifest names) must import in the fixed sequence `@import "./fonts.css"` → the project's `design.tokens.css` → `@import "tailwindcss"` → the library's `styles.css` → the project's `personality.css` → `@theme inline {…}` — cascade-layer order is fixed at first appearance of each `@layer` name, and `personality.css` is bare `:root`/`.dark` blocks that only *tie* the library's unlayered `:root`/`.dark` (0,1,0), so it wins only by following `styles.css`. File position *is* the styling contract between Tailwind, the component library, and the personality tokens.
85
+ **Detect:** first ~10 lines of the CSS entry, `@import "tailwindcss"`, `@import` of `@nurix/components` styles, the `personality.css` `@import`, `@layer` declarations inside the library CSS
86
+ **Ships green, breaks:** Any reorder compiles and mostly renders — the breakage is visual-only and theme/element-specific: importing the library's `styles.css` before `@import "tailwindcss"` lets preflight's `@layer base` resets land after (and wipe) library button/form styling at equal specificity, and flips which side wins app-utility-vs-library override wars; importing `personality.css` before `styles.css` lets the library's neutral personality defaults win the tie, so the product's density, motion, radius and depth silently revert to neutral. Nothing logs; a form-heavy screen just looks subtly wrong. (`design.tokens.css` writes `:root:not(.dark)`/`:root.dark` at (0,2,0) and wins wherever it sits.)
87
+ **Safe change:** Treat the header as frozen; insert new global stylesheets at a deliberate position relative to `tailwindcss` and the library import, never appended blindly; after any reorder, visual-diff a form-heavy screen in light and dark (`.dark`).
88
88
 
89
89
  ## date-fns-local-tz — HIGH · serialized-shape
90
90
  **Contract:** Datetimes cross the wire as UTC ISO strings or date-only `YYYY-MM-DD`, but date-fns `format()` and accessors operate in the runtime's local timezone — serializer and formatter must agree on the zone, and nothing checks that they do.
@@ -1,6 +1,6 @@
1
1
  # Generic tail — technologies outside the mandated stack
2
2
 
3
- Load when: the touched code exhibits one of these technologies and no dedicated pack covers it. Entries here are deliberately thin — one gotcha and the safe-change essence each; diagnose the rest from the mechanism (see `../mechanisms.md`). When the org adopts one of these seriously, promote its section into a full pack.
3
+ Load when: the touched code exhibits one of these technologies and no dedicated pack covers it. Each entry is one gotcha and the safe-change essence; diagnose the rest from its mechanism in `mechanisms.md`. A technology the org adopts seriously gets its section promoted into a full pack.
4
4
 
5
5
  ## API styles
6
6
 
@@ -12,8 +12,8 @@ commits it.
12
12
 
13
13
  ## The architecture — one capability, two seats
14
14
 
15
- Prose obligations decay in the conversing seat: the fleet audit behind v3 found the same rules
16
- dying in every real session, even the successful ones. So the capability is split:
15
+ Prose obligations decay in the conversing seat: an audit of real sessions finds the same rules
16
+ dying in every one, the successful ones included. So the capability is split:
17
17
 
18
18
  | Seat | Component | Owns |
19
19
  | --- | --- | --- |
@@ -27,17 +27,15 @@ line, the twin writes the result — so reconciliation is observable, never asse
27
27
 
28
28
  ## The session lifecycle
29
29
 
30
- ```
31
- /brainstorm start
32
- → basis gate (a document, an old session folder of any format, or a brain dump)
33
- → bootstrap docs/research/{topic}-brainstorm/ (ops/ untracked; twin writes the surface)
34
- → converse: dump / interview / probe / blindspot / converge — steerable in plain language
35
- → "let me read" anytime: compose on demand, read the thesis, come back
36
- /brainstorm stop
37
- → converge → manifest → ONE user approval → apply → uselessness test
38
- → folder moves to docs/history/brainstorms/{topic}/ (the completion marker)
39
- → the user decides: delete or commit
40
- ```
30
+ - **`/brainstorm start`**
31
+ 1. Basis gate — a document, a prior session folder in any format, or a brain dump.
32
+ 2. Bootstrap `docs/research/{topic}-brainstorm/` — `ops/` untracked; the twin writes the surface.
33
+ 3. Converse — dump, interview, probe, blindspot, converge — steerable in plain language.
34
+ 4. "Let me read" anytime — compose on demand, read the thesis, come back.
35
+ - **`/brainstorm stop`**
36
+ 1. Converge → manifest → **one** user approval → apply → uselessness test.
37
+ 2. The folder moves to `docs/history/brainstorms/{topic}/` — the completion marker.
38
+ 3. The user decides: delete or commit.
41
39
 
42
40
  The working surface: `thesis.md` (claim → argument → what changed, recomposed whole, stamped),
43
41
  `forks.md` (open questions with close conditions — the only convergence currency), `ledger.md`