@nurix/etna 0.20.36 → 0.20.38

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 (212) hide show
  1. package/data/catalog/rules/frontend.md +5 -5
  2. package/data/catalog/rules/pnpm.md +2 -2
  3. package/data/catalog/skills/nustack/SKILL.md +2 -2
  4. package/data/catalog/skills/nustack/references/cli-design.md +35 -35
  5. package/data/catalog/skills/nustack/references/monorepo-master-list.md +6 -6
  6. package/data/catalog/skills/nustack/references/monorepo-setup.md +13 -13
  7. package/data/catalog/skills/nustack/references/publishing.md +40 -39
  8. package/data/harness-index.json +1 -1
  9. package/data/harnesses/code/harness.json +2 -2
  10. package/data/harnesses/code/hooks/approved-packages.md +1 -2
  11. package/data/harnesses/code/rules/frontend.md +5 -5
  12. package/data/harnesses/code/rules/pnpm.md +2 -2
  13. package/data/harnesses/code/skills/boundary/SKILL.md +33 -22
  14. package/data/harnesses/code/skills/boundary/references/index.md +2 -4
  15. package/data/harnesses/code/skills/boundary/references/mechanisms.md +3 -10
  16. package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
  17. package/data/harnesses/code/skills/boundary/references/packs/frontend.md +17 -17
  18. package/data/harnesses/code/skills/boundary/references/packs/generic-tail.md +1 -1
  19. package/data/harnesses/code/skills/brainstorm/README.md +11 -13
  20. package/data/harnesses/code/skills/brainstorm/SKILL.md +150 -132
  21. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +48 -51
  22. package/data/harnesses/code/skills/brainstorm/references/harvest.md +51 -56
  23. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +48 -42
  24. package/data/harnesses/code/skills/design/SKILL.md +31 -35
  25. package/data/harnesses/code/skills/design/components/charts.md +121 -43
  26. package/data/harnesses/code/skills/design/components/collections.md +209 -41
  27. package/data/harnesses/code/skills/design/components/feedback.md +86 -25
  28. package/data/harnesses/code/skills/design/components/hooks.md +198 -12
  29. package/data/harnesses/code/skills/design/components/index.md +93 -71
  30. package/data/harnesses/code/skills/design/components/inputs.md +249 -157
  31. package/data/harnesses/code/skills/design/components/layout.md +98 -38
  32. package/data/harnesses/code/skills/design/components/media.md +46 -25
  33. package/data/harnesses/code/skills/design/components/motion.md +56 -46
  34. package/data/harnesses/code/skills/design/components/navigation.md +54 -15
  35. package/data/harnesses/code/skills/design/components/overlays.md +51 -41
  36. package/data/harnesses/code/skills/design/components/setup.md +84 -5
  37. package/data/harnesses/code/skills/design/components/typography.md +72 -22
  38. package/data/harnesses/code/skills/design/components/utils.md +47 -13
  39. package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
  40. package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
  41. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
  42. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
  43. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
  44. package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
  45. package/data/harnesses/code/skills/design/data/iconography.md +2 -2
  46. package/data/harnesses/code/skills/design/references/compose.md +14 -16
  47. package/data/harnesses/code/skills/design/references/emission.md +6 -6
  48. package/data/harnesses/code/skills/design/references/foundations.md +5 -5
  49. package/data/harnesses/code/skills/design/references/intake.md +6 -6
  50. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  51. package/data/harnesses/code/skills/design/references/ship-gate.md +5 -5
  52. package/data/harnesses/code/skills/design/references/ux-patterns/Readme.md +4 -4
  53. package/data/harnesses/code/skills/design/references/ux-patterns/ai-layer.md +1 -1
  54. package/data/harnesses/code/skills/design/references/ux-patterns/container-choice.md +1 -1
  55. package/data/harnesses/code/skills/design/references/ux-patterns/dashboards.md +1 -1
  56. package/data/harnesses/code/skills/design/references/ux-patterns/modes.md +1 -1
  57. package/data/harnesses/code/skills/design/references/ux-patterns/object-model.md +2 -2
  58. package/data/harnesses/code/skills/design/references/ux-patterns/promotion-demotion.md +1 -1
  59. package/data/harnesses/code/skills/design/references/ux-patterns/settings.md +1 -1
  60. package/data/harnesses/code/skills/design/references/ux-patterns/standard-pages.md +1 -1
  61. package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
  62. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
  63. package/data/harnesses/code/skills/documentation/SKILL.md +5 -5
  64. package/data/harnesses/code/skills/documentation/references/examples.md +22 -22
  65. package/data/harnesses/code/skills/documentation/references/frontmatter.md +3 -3
  66. package/data/harnesses/code/skills/documentation/references/instruction-style.md +3 -3
  67. package/data/harnesses/code/skills/documentation/references/source-comments.md +3 -3
  68. package/data/harnesses/code/skills/documentation/references/style-guide.md +5 -5
  69. package/data/harnesses/code/skills/documentation/references/untemplated.md +8 -8
  70. package/data/harnesses/code/skills/documentation/scripts/doc-lint.mjs +3 -2
  71. package/data/harnesses/code/skills/documentation/templates/Readme.md +1 -1
  72. package/data/harnesses/code/skills/documentation/templates/acceptance-criteria.md +1 -1
  73. package/data/harnesses/code/skills/documentation/templates/api-reference.md +1 -1
  74. package/data/harnesses/code/skills/documentation/templates/architecture-decision.md +3 -7
  75. package/data/harnesses/code/skills/documentation/templates/behavioral-checklist.md +1 -1
  76. package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +1 -1
  77. package/data/harnesses/code/skills/documentation/templates/changelog-index.md +1 -1
  78. package/data/harnesses/code/skills/documentation/templates/docs-readme.md +3 -3
  79. package/data/harnesses/code/skills/documentation/templates/doctrine.md +1 -1
  80. package/data/harnesses/code/skills/documentation/templates/domain-model.md +1 -1
  81. package/data/harnesses/code/skills/documentation/templates/environment-registry.md +1 -1
  82. package/data/harnesses/code/skills/documentation/templates/feature.md +3 -3
  83. package/data/harnesses/code/skills/documentation/templates/handover.md +2 -2
  84. package/data/harnesses/code/skills/documentation/templates/implementation-map.md +1 -1
  85. package/data/harnesses/code/skills/documentation/templates/migration-runbook.md +1 -1
  86. package/data/harnesses/code/skills/documentation/templates/non-goals.md +1 -1
  87. package/data/harnesses/code/skills/documentation/templates/operations-procedure.md +2 -2
  88. package/data/harnesses/code/skills/documentation/templates/package.md +1 -1
  89. package/data/harnesses/code/skills/documentation/templates/protected-files.md +1 -1
  90. package/data/harnesses/code/skills/documentation/templates/root-readme.md +1 -1
  91. package/data/harnesses/code/skills/documentation/templates/security-overview.md +1 -1
  92. package/data/harnesses/code/skills/documentation/templates/system-overview.md +1 -1
  93. package/data/harnesses/code/skills/documentation/templates/system.md +1 -1
  94. package/data/harnesses/code/skills/documentation/templates/testing-strategy.md +1 -1
  95. package/data/harnesses/code/skills/documentation/templates/ux-behavior.md +3 -5
  96. package/data/harnesses/code/skills/issue-bridge/SKILL.md +51 -16
  97. package/data/harnesses/code/skills/issue-bridge/references/trackers/github.md +5 -5
  98. package/data/harnesses/code/skills/issue-bridge/references/trackers/jira.md +11 -8
  99. package/data/harnesses/code/skills/issue-bridge/references/trackers/linear.md +16 -11
  100. package/data/harnesses/code/skills/nustack-graph/SKILL.md +38 -29
  101. package/data/harnesses/code/skills/polygraph/references/dispatch.md +31 -18
  102. package/data/harnesses/code/skills/polygraph/references/rows.md +11 -6
  103. package/data/harnesses/code/skills/schema-design/SKILL.md +39 -41
  104. package/data/harnesses/code/skills/test/SKILL.md +38 -42
  105. package/data/harnesses/code/skills/testing/SKILL.md +83 -73
  106. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +156 -193
  107. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +15 -15
  108. package/data/harnesses/delivery/harness.json +2 -2
  109. package/data/harnesses/delivery/skills/brainstorm/README.md +11 -13
  110. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +150 -132
  111. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +48 -51
  112. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +51 -56
  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 +5 -5
  116. package/data/harnesses/delivery/skills/documentation/references/examples.md +22 -22
  117. package/data/harnesses/delivery/skills/documentation/references/frontmatter.md +3 -3
  118. package/data/harnesses/delivery/skills/documentation/references/instruction-style.md +3 -3
  119. package/data/harnesses/delivery/skills/documentation/references/source-comments.md +3 -3
  120. package/data/harnesses/delivery/skills/documentation/references/style-guide.md +5 -5
  121. package/data/harnesses/delivery/skills/documentation/references/untemplated.md +8 -8
  122. package/data/harnesses/delivery/skills/documentation/scripts/doc-lint.mjs +3 -2
  123. package/data/harnesses/delivery/skills/documentation/templates/Readme.md +1 -1
  124. package/data/harnesses/delivery/skills/documentation/templates/acceptance-criteria.md +1 -1
  125. package/data/harnesses/delivery/skills/documentation/templates/api-reference.md +1 -1
  126. package/data/harnesses/delivery/skills/documentation/templates/architecture-decision.md +3 -7
  127. package/data/harnesses/delivery/skills/documentation/templates/behavioral-checklist.md +1 -1
  128. package/data/harnesses/delivery/skills/documentation/templates/changelog-entry.md +1 -1
  129. package/data/harnesses/delivery/skills/documentation/templates/changelog-index.md +1 -1
  130. package/data/harnesses/delivery/skills/documentation/templates/docs-readme.md +3 -3
  131. package/data/harnesses/delivery/skills/documentation/templates/doctrine.md +1 -1
  132. package/data/harnesses/delivery/skills/documentation/templates/domain-model.md +1 -1
  133. package/data/harnesses/delivery/skills/documentation/templates/environment-registry.md +1 -1
  134. package/data/harnesses/delivery/skills/documentation/templates/feature.md +3 -3
  135. package/data/harnesses/delivery/skills/documentation/templates/handover.md +2 -2
  136. package/data/harnesses/delivery/skills/documentation/templates/implementation-map.md +1 -1
  137. package/data/harnesses/delivery/skills/documentation/templates/migration-runbook.md +1 -1
  138. package/data/harnesses/delivery/skills/documentation/templates/non-goals.md +1 -1
  139. package/data/harnesses/delivery/skills/documentation/templates/operations-procedure.md +2 -2
  140. package/data/harnesses/delivery/skills/documentation/templates/package.md +1 -1
  141. package/data/harnesses/delivery/skills/documentation/templates/protected-files.md +1 -1
  142. package/data/harnesses/delivery/skills/documentation/templates/root-readme.md +1 -1
  143. package/data/harnesses/delivery/skills/documentation/templates/security-overview.md +1 -1
  144. package/data/harnesses/delivery/skills/documentation/templates/system-overview.md +1 -1
  145. package/data/harnesses/delivery/skills/documentation/templates/system.md +1 -1
  146. package/data/harnesses/delivery/skills/documentation/templates/testing-strategy.md +1 -1
  147. package/data/harnesses/delivery/skills/documentation/templates/ux-behavior.md +3 -5
  148. package/data/harnesses/delivery/skills/escalate/SKILL.md +11 -11
  149. package/data/harnesses/delivery/skills/prompt-eval/SKILL.md +8 -8
  150. package/data/harnesses/delivery/skills/prompt-library/SKILL.md +30 -9
  151. package/data/harnesses/delivery/skills/route/SKILL.md +8 -8
  152. package/data/harnesses/etna/harness.json +2 -2
  153. package/data/harnesses/etna/skills/boundary/SKILL.md +33 -22
  154. package/data/harnesses/etna/skills/boundary/references/index.md +2 -4
  155. package/data/harnesses/etna/skills/boundary/references/mechanisms.md +3 -10
  156. package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
  157. package/data/harnesses/etna/skills/boundary/references/packs/frontend.md +17 -17
  158. package/data/harnesses/etna/skills/boundary/references/packs/generic-tail.md +1 -1
  159. package/data/harnesses/etna/skills/brainstorm/README.md +11 -13
  160. package/data/harnesses/etna/skills/brainstorm/SKILL.md +150 -132
  161. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +48 -51
  162. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +51 -56
  163. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +48 -42
  164. package/data/harnesses/etna/skills/documentation/SKILL.md +5 -5
  165. package/data/harnesses/etna/skills/documentation/references/examples.md +22 -22
  166. package/data/harnesses/etna/skills/documentation/references/frontmatter.md +3 -3
  167. package/data/harnesses/etna/skills/documentation/references/instruction-style.md +3 -3
  168. package/data/harnesses/etna/skills/documentation/references/source-comments.md +3 -3
  169. package/data/harnesses/etna/skills/documentation/references/style-guide.md +5 -5
  170. package/data/harnesses/etna/skills/documentation/references/untemplated.md +8 -8
  171. package/data/harnesses/etna/skills/documentation/scripts/doc-lint.mjs +3 -2
  172. package/data/harnesses/etna/skills/documentation/templates/Readme.md +1 -1
  173. package/data/harnesses/etna/skills/documentation/templates/acceptance-criteria.md +1 -1
  174. package/data/harnesses/etna/skills/documentation/templates/api-reference.md +1 -1
  175. package/data/harnesses/etna/skills/documentation/templates/architecture-decision.md +3 -7
  176. package/data/harnesses/etna/skills/documentation/templates/behavioral-checklist.md +1 -1
  177. package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +1 -1
  178. package/data/harnesses/etna/skills/documentation/templates/changelog-index.md +1 -1
  179. package/data/harnesses/etna/skills/documentation/templates/docs-readme.md +3 -3
  180. package/data/harnesses/etna/skills/documentation/templates/doctrine.md +1 -1
  181. package/data/harnesses/etna/skills/documentation/templates/domain-model.md +1 -1
  182. package/data/harnesses/etna/skills/documentation/templates/environment-registry.md +1 -1
  183. package/data/harnesses/etna/skills/documentation/templates/feature.md +3 -3
  184. package/data/harnesses/etna/skills/documentation/templates/handover.md +2 -2
  185. package/data/harnesses/etna/skills/documentation/templates/implementation-map.md +1 -1
  186. package/data/harnesses/etna/skills/documentation/templates/migration-runbook.md +1 -1
  187. package/data/harnesses/etna/skills/documentation/templates/non-goals.md +1 -1
  188. package/data/harnesses/etna/skills/documentation/templates/operations-procedure.md +2 -2
  189. package/data/harnesses/etna/skills/documentation/templates/package.md +1 -1
  190. package/data/harnesses/etna/skills/documentation/templates/protected-files.md +1 -1
  191. package/data/harnesses/etna/skills/documentation/templates/root-readme.md +1 -1
  192. package/data/harnesses/etna/skills/documentation/templates/security-overview.md +1 -1
  193. package/data/harnesses/etna/skills/documentation/templates/system-overview.md +1 -1
  194. package/data/harnesses/etna/skills/documentation/templates/system.md +1 -1
  195. package/data/harnesses/etna/skills/documentation/templates/testing-strategy.md +1 -1
  196. package/data/harnesses/etna/skills/documentation/templates/ux-behavior.md +3 -5
  197. package/data/harnesses/etna/skills/workflow-mapper/SKILL.md +156 -193
  198. package/data/harnesses/etna/skills/workflow-mapper/references/patterns.md +15 -15
  199. package/data/harnesses/hr/harness.json +2 -2
  200. package/data/harnesses/hr/skills/evaluator/SKILL.md +71 -73
  201. package/data/harnesses/hr/skills/evaluator/criteria/code-quality.md +28 -47
  202. package/data/harnesses/hr/skills/evaluator/criteria/deployment-readiness.md +33 -43
  203. package/data/harnesses/hr/skills/evaluator/criteria/maintainability.md +34 -46
  204. package/data/harnesses/hr/skills/evaluator/criteria/mechanical-ambition.md +13 -13
  205. package/data/harnesses/hr/skills/evaluator/criteria/problem-substantiveness.md +7 -7
  206. package/data/harnesses/hr/skills/evaluator/criteria/testing.md +36 -41
  207. package/data/harnesses/hr/skills/evaluator/criteria/ux-mechanics.md +25 -11
  208. package/data/harnesses/hr/skills/evaluator/criteria/value-articulation.md +7 -7
  209. package/data/harnesses/hr/skills/evaluator/preflight.md +27 -46
  210. package/data/harnesses/hr/skills/interview-eval/SKILL.md +37 -42
  211. package/data/harnesses/hr/skills/interview-eval/rubric.md +21 -23
  212. package/package.json +2 -2
@@ -2,19 +2,19 @@
2
2
 
3
3
  Read the brief and choose from the menus: one identity package (the design.md system), any axis overrides the brief demands, layout blueprints per surface, and the product domain for content. Every choice is one recorded line.
4
4
 
5
- **Returning workspace first.** If the repo carries a `workspaceId` (or the NuStack context supplies one), open with `get_preferences`: the workspace's `design.md`, `taste.md`, and `product.md` rows are the session's context — then run the drift check (compare the repo's fork — `node scripts/validate-design-md.mjs --project .` resolves its one path from the repo shape and fails closed on a copy anywhere else — against the server row; on mismatch, tell the user which is newer and ask). A workspace with a recorded identity re-enters the steps with that identity already chosen; the rules below are for first intake.
5
+ **Returning workspace first.** If the repo carries a `workspaceId` (or the NuStack context supplies one), open with `get_preferences`: the workspace's `design.md`, `taste.md`, and `product.md` rows are the session's context. Then run the drift check — compare the repo's fork (the path `node scripts/validate-design-md.mjs --project .` resolves) against the server row; on mismatch, tell the user which is newer and ask. A workspace with a recorded identity re-enters the steps with that identity already chosen; the rules below are for first intake.
6
6
 
7
7
  ## Rules
8
8
 
9
9
  - **The brief's own words outrank any database default.** "Beautiful" means the ceiling, not the safe row.
10
10
  - **Adjectives become referents.** When the brief speaks in adjectives ("premium", "editorial"), name the 2–3 real products the brief is pointing at and pick the package whose recorded identity sits in that class — unnamed ambition becomes beige.
11
- - **Search is a retrieval aid, never a router.** `search_catalog` (family `design_md`) with the brief's segment/keyword resemblance; shortlist 2–3 results by their head metadata (feel, reads-as, keywords), then choose reading the brief. After the choice, `get_entry` **once**: the chosen package's full design.md enters context and **stays in view through step 4**; unchosen candidates are never fetched.
12
- - **The escape hatch fires mechanically.** No catalog hit, plus a recorded one-line reason why the closest package fails → author a one-off project design.md in the package schema, `tier: project`, at the path `--project .` resolves — the validator is the schema authority and checks it like any library entry. This path is expected to be common; flag the file as a curation candidate for the roster.
13
- - **Record the identity.** First intake ends with `record`: the identity choice as a decision line, and the resolved fork pushed as the workspace's `design.md` preference row. The `workspaceId` is committed to the repo if it is not ambient. Design taste is workspace-level — an app never gets its own.
11
+ - **Search is a retrieval aid, never a router.** `search_catalog` (family `design_md`) with the brief's segment/keyword resemblance; shortlist 2–3 results by their head metadata (feel, reads-as, keywords), then choose by reading the brief. After the choice, `get_entry` **once**: the chosen package's full design.md enters context and **stays in view through step 4**; unchosen candidates are never fetched.
12
+ - **The escape hatch fires mechanically.** No catalog hit, plus a recorded one-line reason why the closest package fails → author a one-off project design.md in the package schema, `tier: project`, at the path `--project .` resolves — the validator is the schema authority and checks it like any library entry. Expect this path to be common; flag the file as a curation candidate for the roster.
13
+ - **Record the identity.** First intake ends with `record`: the identity choice as a decision line, and the resolved fork pushed as the workspace's `design.md` preference row. Commit the `workspaceId` to the repo if it is not ambient. Design taste is workspace-level — an app **never** gets its own.
14
14
  - **Axis overrides fetch or read the single named entry** — color/font/gradient/chart-style overrides `get_entry` their dictionary entry; elevation/motion/iconography overrides read the named local entry under `data/`.
15
15
  - **Set the primitives switch** — write one `primitives: nurix | native` line into the project's `design.md` (the path `--project .` resolves; first intake creates the file there). Default by the probe: the project resolves `@nurix/components` (check package.json / lockfile / node_modules) → `nurix`; otherwise — existing apps, foreign stacks, no library access — → `native`. Set once here; nothing downstream re-asks. Also write `source-package: <slug>` (or `authored` for escape-hatch one-offs).
16
16
  - **Write or update `product.md`**: users and their jobs, roles/permissions, action frequency, risk level, accessibility commitments, brand anti-references. Package choice, UX decisions, motion intensity, and demo data all cite it. Push it as a preference row too — Studio shows it.
17
- - **The taste profile biases every choice** — `get_preferences` returns the workspace's `taste.md` (per-dimension feel/avoid lines); user reactions to shipped output update it via `record`. No profile yet = no bias, never a block.
17
+ - **The taste profile biases every choice** — `get_preferences` returns the workspace's `taste.md` (per-dimension feel/avoid lines); user reactions to shipped output update it via `record`. No profile = no bias, **never** a block.
18
18
  - **Stated-choice awareness:** if prior package picks are visible in the workspace, name them and say in one line why this pick repeats or differs — awareness, never forced rotation.
19
19
  - **Questions go to the user only when the answer changes the design** (theme, audience, density); everything else is inferred and marked inferred.
20
20
 
@@ -29,7 +29,7 @@ Step 1 ends with a preview block:
29
29
  - domain corpus
30
30
  - surface map with archetypes
31
31
  - planned deviations
32
- - the personality traits (under `nurix`): the six-trait reading of §4–§7 — density, pace, edge, depth, texture, tone — naming only what differs from neutral, written into the design-values block so the library compiles it
32
+ - the personality traits (under `nurix`): the six-trait reading of §4–§7 — density, pace, edge, depth, texture, accent — naming only what differs from neutral, written into the design-values block so the library compiles it
33
33
 
34
34
  When a user is present, pause here **once** for confirm-or-redirect — a wrong pick costs one message now instead of a full build. Autonomous runs proceed. Either way the block goes to workspace memory — `record` it as decision lines heading this run's choices, with the app as context.
35
35
 
@@ -12,7 +12,7 @@ Derive the object model and surface map using the UX-pattern decision layer (`re
12
12
  8. `container-choice` — container by workflow (duration, interruption, comparison need), never by size
13
13
  9. `creation-paths` — form, import, conversion, clone, recurrence
14
14
  10. `table-mechanics` — where tables project a surface
15
- 11. `state-matrix` — loading, the three empties (first-use, no-results, cleared), degraded, stale — per surface
15
+ 11. `state-matrix` — loading, the three empties (first-run, filtered-to-zero, failed-to-load), a queue's cleared-empty, degraded, stale — per surface
16
16
  12. `standard-pages` / `ai-layer` / `dashboards` / `settings` — when the brief has them
17
17
 
18
18
  Each pass file carries its rule as prose plus its machine-readable decision table; **follow the table's answer**. Disagreement is legitimate craft only when recorded — one `record` line naming the pass, the table's answer, yours, and why. An unrecorded divergence is the violation.
@@ -1,10 +1,10 @@
1
1
  # Step 5 — The ship gate
2
2
 
3
- The project ships with its project-local artifacts — `design.md` (the resolved fork, with provenance line, brief bindings, recorded deviations), its derived `design.tokens.css`, and `product.md` — and its memory server-side. The gate has two tiers, both objective: this is the only runtime check the skill performs, permitted precisely because it is automated and needs no judgment. Nothing here grades taste — anything that needs grading was the build-time harness's burden, not the run's.
3
+ The project ships with its project-local artifacts — `design.md` (the resolved fork, with provenance line, brief bindings, recorded deviations), its derived `design.tokens.css`, and `product.md` — and its memory server-side. The gate has two tiers, both objective — the only runtime check the skill performs, because it needs no judgment. Nothing here grades taste; grading is the build-time harness's burden, not the run's.
4
4
 
5
5
  ## Tier 1 — fails closed
6
6
 
7
- Every check a binary predicate. Run the validator (`node scripts/validate-design-md.mjs --project . --mode ship`) plus the build itself; all of these must hold:
7
+ Every check is a binary predicate. Run the validator (`node scripts/validate-design-md.mjs --project . --mode ship`) plus the build itself; all of these must hold:
8
8
 
9
9
  - **No placeholder text or scaffold stubs** anywhere (lorem, TODO, "Coming soon", empty `href="#"` walls).
10
10
  - **Data plausibility** against the corpus's declared invariants: aggregates reconcile with their visible rows; legal ranges hold; no degenerate repetition in visible rows (surname clusters, identical amounts).
@@ -18,10 +18,10 @@ Every check a binary predicate. Run the validator (`node scripts/validate-design
18
18
  - the emitted CSS actually compiles;
19
19
  - charts and status surfaces consume the package's tokens (a dark dashboard with hardcoded light charts fails here).
20
20
  - **The library reach checks** (`primitives: nurix`):
21
- - `personality.css` recompiles from the design.md's personality block to a byte-match (the validator's `dmv-12`); a design.md with no block fails nothing, and its `dmw-05` warn appears in the ship report;
21
+ - `personality.css` recompiles from the design.md's personality block to a byte-match (the validator's `dmv-12`); a design.md with no block fails nothing, and its `dmw-09` warn appears in the ship report;
22
22
  - no `data-theme` selector or attribute in app CSS or HTML — the theme is the `.dark` class;
23
23
  - no `duration-<n>` utility, no `transition-all`, and no literal `ms` inside a transition or animation declaration in app code — the seam carries timing;
24
- - no `<time` element outside `<Timestamp>`; no `truncate` or `line-clamp-` utility (the `clip` family replaces them);
24
+ - no `<time` element outside `<Timestamp>`; no `truncate` or `line-clamp-` utility (use the `clip` family);
25
25
  - every interactive element under 24px in either rendered dimension carries a `hit-area` utility.
26
26
 
27
27
  A Tier-1 failure blocks the ship; fix and re-run. Binary phrasing is the contract — anything that would need "use sparingly" grading does not belong in this tier.
@@ -32,4 +32,4 @@ Sweep `data/tells.csv` (the operator tell list), at this step only, plus the mot
32
32
 
33
33
  ## The ship report
34
34
 
35
- Close the run with a compact report: surfaces shipped, the recorded choices, Tier-1 results, every Tier-2 flag with its disposition, and the validator's warn list. No scores, no self-grades. Write it to memory — `record` with `report: { kind: "gate", summary }` — and, if the run's surviving edits changed the project's `design.md`, push the new text in the same `record` so the server canonical stays current.
35
+ Close the run with a compact report: surfaces shipped, the recorded choices, Tier-1 results, every Tier-2 flag with its disposition, and the validator's warn list. No scores, no self-grades. Write it to memory — `record` with `report: { kind: "gate", summary }` — and, if the run's surviving edits changed the project's `design.md`, push the new text in the same `record` so the server canonical matches.
@@ -5,15 +5,15 @@ sourced: 2026-07-12
5
5
  source: "b2b-ux-patterns playbook (16 chapters) — distilled"
6
6
  license: open
7
7
  ---
8
- # B2 — the B2B UX-pattern decision layer
8
+ # The B2B UX-pattern decision layer
9
9
 
10
- What-to-use-when for every structural UI decision, distilled from the ratified 16-chapter B2B UX playbook. **One decision file per pass**, each carrying its rule twice in one body: prose for the model, then an embedded machine-readable `json decision-table` that is the executable core — the contract runner ([`../../../../evals/design/run-decision-contracts.mjs`](../../../../evals/design/run-decision-contracts.mjs)) parses and evaluates these tables directly, so the tested rule and the followed rule are the same bytes.
10
+ What-to-use-when for every structural UI decision, distilled from the ratified 16-chapter B2B UX playbook. **One decision file per pass**, each carrying its rule twice in one body: prose for the model, then an embedded machine-readable `json decision-table` that is the executable core. The skill's contract tests evaluate these tables directly, so the table is the rule as tested — where prose and table seem to differ, follow the table.
11
11
 
12
12
  The pinned **seven-archetype roster** every pass conforms to: `browse`, `queue`, `grid`, `record-detail`, `dashboard`, `creation-flow`, `settings`. View-types (table, board, cards, calendar, timeline, map) are **projections** of an archetype, never archetypes themselves.
13
13
 
14
14
  ## The 15 passes
15
15
 
16
- Run each at the step of the method that needs it — the order below is the method's order.
16
+ Run each at the step of the method that needs it, in the order below.
17
17
 
18
18
  | # | Pass | Source | Owns |
19
19
  | --- | --- | --- | --- |
@@ -192,4 +192,4 @@ Every `when` key used across the 15 passes, with its legal values. **Any key may
192
192
 
193
193
  ## The load rule
194
194
 
195
- **One pass file per step, never all at once.** The load contract ([09 §Load contracts](../../../../docs/features/design-skill/09-database-structures.md)) is explicit: B2 enters context as *the one pass file the current step needs*; loading all passes at once is forbidden. Consult this Readme to route to the right file, then load only that file at the step that needs it. Clarification codes are surfaced, never guessed around — a `then.clarifications` firing means an input the pass needs is missing, and the step pauses to obtain it rather than proceeding on a default.
195
+ **One pass file per step, never all at once** (the `SKILL.md` load contract). Route through this Readme, then load only the pass file the current step needs. **Never** guess around a clarification code — a `then.clarifications` firing means an input the pass needs is missing; pause the step to obtain it (infer-and-mark when the answer does not change the design, ask when it does) rather than proceed on a default.
@@ -21,7 +21,7 @@ license: open
21
21
 
22
22
  **Guardrails are one orthogonal layer, factored once.** *Prevention*: confidence gating with a numeric threshold where the domain is mature (high-confidence posts through, sub-threshold queues for review); **statistical-significance gating** where the system corrects a human or third-party claim (never assert on a small sample — the reputation guardrail, and the home of the house-knowledge corrective); simulation/eval gating before an agent version deploys. *Recovery*: the undo/rollback backstop under every agent action; the **escalation floor** — no serious autonomous agent ships without a mandatory hand-to-human boundary, and the handoff carries what was already tried so the human resumes mid-stream. *Glass box*: citations, the source anchor stored beside every transduced value, and the **AI-action audit log as a surface distinct from record edit history** (actor = AI, what changed, and what data informed it).
23
23
 
24
- **The agent is a governed actor and the checkpoint is how the flow waits.** An agent principal gets its own identity in the directory, scoped least-privilege permissions, a human sponsor, and a lifecycle — never a borrowed human credential; its effective access is the intersection of its grants and its delegating subject's (see viewer-context). The **durable checkpoint** (axiom 21) — pause, persist, notify, resume — is the portable guardrail node: decision rights choose *when* the human enters; the checkpoint is *how* the flow waits, with state persisting across days and the notification carrying the evidence pack. Design against this primitive, not against inline blocking prompts. Chat is the **home surface** when its output is inspectable and reversible (conversational BI — expose the compiled query as the escape to determinism) and the **escape hatch** when output is externally committing (the human ratifies). Accumulated memory (system-auto-written, cross-session) is audited after and demands its own management surface and memory-provenance show-which. When an AI capability writes but its blast radius is undeclared, the decision-rights stance cannot be set: clarify.
24
+ **The agent is a governed actor and the checkpoint is how the flow waits.** An agent principal gets its own identity in the directory, scoped least-privilege permissions, a human sponsor, and a lifecycle — never a borrowed human credential; its effective access is the intersection of its grants and its delegating subject's (see viewer-context). The **durable checkpoint** — pause, persist, notify, resume — is the portable guardrail node: decision rights choose *when* the human enters; the checkpoint is *how* the flow waits, with state persisting across days and the notification carrying the evidence pack. Design against this primitive, not against inline blocking prompts. Chat is the **home surface** when its output is inspectable and reversible (conversational BI — expose the compiled query as the escape to determinism) and the **escape hatch** when output is externally committing (the human ratifies). Accumulated memory (system-auto-written, cross-session) is audited after and demands its own management surface and memory-provenance show-which. When an AI capability writes but its blast radius is undeclared, the decision-rights stance cannot be set: clarify.
25
25
 
26
26
  ```json decision-table
27
27
  {"pass": "ai-layer", "rows": [
@@ -17,7 +17,7 @@ license: open
17
17
 
18
18
  **Body organization forks two ways.** *Tabs* (lazy-loaded, per-section linkable) when sections are large, independently loaded, and rarely needed together — the record is "several pages sharing a header." *Single-scroll with a sticky anchor rail* when the job needs cross-section skimming in one pass and sections are modest. Objects worked in long sessions over a streaming main column (conversation, timeline) earn a persistent **360 / context rail** — the parent summary and key attributes stay put while the narrative moves; the rail is denormalization-for-display doing its job.
19
19
 
20
- **The container ladder — `hovercard → inline-popover → center-modal → side-peek → full-page`.** Information size does not pick the rung; five workflow axes do, size only breaks ties. (1) **Context retention** — if the originating list must stay live behind the opened record (open, close, open the next, compare), it is a **side peek**, however small the record; a modal dims and blocks the hub, a peek keeps it alive. (2) **Read-vs-edit depth** — a quick read wants a peek; deep, multi-field, interdependent editing wants center focus or a full page, because accidental dismissal becomes expensive. (3) **Shareability** — a record that needs a stable, shareable URL can now live in a URL-addressable peek or split pane; a record **sent outward** (an invoice) still defaults to a **full page** despite tiny size. (4) **Traversal** — processing or comparing many records in a row needs next/prev through the *exact filtered, sorted set*, which means a peek or split pane, never a modal and never a full-page round-trip per record. (5) **Interruption** — a center modal *blocks* (correct for confirmations and irreversible commits); a peek *continues* (work proceeds around it). Size is the tiebreaker only when the axes are indifferent: a leaf datum in a popover, a modest record in a peek.
20
+ **The container ladder — `hovercard → inline-popover → center-modal → side-peek → full-page`.** Information size does not pick the rung; five workflow axes do, size only breaks ties. (1) **Context retention** — if the originating list must stay live behind the opened record (open, close, open the next, compare), it is a **side peek**, however small the record; a modal dims and blocks the hub, a peek keeps it alive. (2) **Read-vs-edit depth** — a quick read wants a peek; deep, multi-field, interdependent editing wants center focus or a full page, because accidental dismissal becomes expensive. (3) **Shareability** — a record that needs a stable, shareable URL can live in a URL-addressable peek or split pane; a record **sent outward** (an invoice) defaults to a **full page** despite tiny size. (4) **Traversal** — processing or comparing many records in a row needs next/prev through the *exact filtered, sorted set*, which means a peek or split pane, never a modal and never a full-page round-trip per record. (5) **Interruption** — a center modal *blocks* (correct for confirmations and irreversible commits); a peek *continues* (work proceeds around it). Size is the tiebreaker only when the axes are indifferent: a leaf datum in a popover, a modest record in a peek.
21
21
 
22
22
  **Container requirements.** Every peek and modal carries an **"open as full page"** escape hatch — users promote up the ladder themselves, so picking the lighter rung costs one click. Closing a peek or modal honors the **return contract**: the originating surface restores *exactly as left* — same scroll, filters, selection. The same object opens at the same rung from the same kind of origin, product-wide — container choice is per-object-per-origin, not per-screen improvisation. When a record must open but no workflow axis is declared, the rung cannot be chosen from size alone: clarify.
23
23
 
@@ -21,7 +21,7 @@ license: open
21
21
 
22
22
  **Dashboards are where three lifecycle declarations become visible.** Trend tiles are the UI output of the **Sampled** history class — a field declared Overwrite has no trend to show, and an empty trend tile is a history-class declaration failure, not a chart bug. **Freshness is mandatory** — every tile group carries "updated N minutes ago" and degraded tiles fail individually, so one dead query never blanks the board. **Targets and thresholds are config objects** — owned, versioned, auditable — not constants buried in tile definitions. The whole surface renders f(data, viewer): a scope switcher (me / my team / org) rather than separate dashboards per rung, tiles gated by role and plan.
23
23
 
24
- **Promotion follows frequency × criticality, not habit** — dashboards go high for managers and low for operators, whose landing surface is the queue or index with the glance strip at most zoned above it; defaulting every sidebar item to a dashboard is the dashboard-first fallacy. The 2026 push inversion turns the monitoring dashboard from the ritually-visited wall into the drill-down destination behind a pushed digest — design the digest → dashboard → door → records chain unbroken, and ship auto-narration only behind the significance gate. A monitoring tile with no declared threshold cannot render a state: clarify. A trend tile over an Overwrite field has no trend to show: clarify.
24
+ **Promotion follows frequency × criticality, not habit** — dashboards go high for managers and low for operators, whose landing surface is the queue or index with the glance strip at most zoned above it; defaulting every sidebar item to a dashboard is the dashboard-first fallacy. Under the push inversion, the monitoring dashboard is the drill-down destination behind a pushed digest, not a ritually-visited wall — design the digest → dashboard → door → records chain unbroken, and ship auto-narration only behind the significance gate. A monitoring tile with no declared threshold cannot render a state: clarify. A trend tile over an Overwrite field has no trend to show: clarify.
25
25
 
26
26
  ```json decision-table
27
27
  {"pass": "dashboards", "rows": [
@@ -15,7 +15,7 @@ license: open
15
15
 
16
16
  A mode is a behaviorally distinct way of using the product; it earns a place only if it demands different UI — different layout, affordances, success metric. **Modes are not persona traits:** the same user on the same data switches modes hour to hour (monitoring at 9:00, triage at 9:15, procedural until lunch, an exception at 2:00, approvals at 4:00). Never map persona → mode and design one surface per persona; inventory which modes each role enters per dataset and let one dataset serve several modes — a leads list must support monitoring (stat glance), triage (route verbs, bulk bar), and batch mutation (grid selection) without becoming three pages.
17
17
 
18
- **Mode selects archetype — not the object.** When a screen feels wrong despite showing the right object, the usual cause is a mode mismatch: an index built for browsing handed to a team that triages, or a settings *page* given to what is actually a configuration *mode* needing preview and rollback. Distinctions the table encodes: investigation has a fixed question (timeline, trail, drill); exploration has none yet (pivot, segment — the question is the output). Triage routes without resolving; procedural resolves and takes the next. Approval judges someone else's finished output; supervision (the fastest-growing mode of 2025–26) steers an autonomous worker mid-flight — pause, redirect, resume — and is neither monitoring (no intervention), approval (finished artifact), nor exception handling (single-user improvisation after the playbook fails). Exception handling is exactly where UX quality matters most, because the designed flows have run out.
18
+ **Mode selects archetype — not the object.** When a screen feels wrong despite showing the right object, the usual cause is a mode mismatch: an index built for browsing handed to a team that triages, or a settings *page* given to what is actually a configuration *mode* needing preview and rollback. Distinctions the table encodes: investigation has a fixed question (timeline, trail, drill); exploration has none yet (pivot, segment — the question is the output). Triage routes without resolving; procedural resolves and takes the next. Approval judges someone else's finished output; supervision steers an autonomous worker mid-flight — pause, redirect, resume — and is neither monitoring (no intervention), approval (finished artifact), nor exception handling (single-user improvisation after the playbook fails). Exception handling is exactly where UX quality matters most, because the designed flows have run out.
19
19
 
20
20
  Richer surface forms noted in `page-archetype` (conversational inbox, split-pane console, canvas builder, report builder, wizard, log explorer, merge/diff views) are realizations of these roster mappings, not extra archetypes.
21
21
 
@@ -24,11 +24,11 @@ Cardinality deterministically dictates UI treatment — never information size.
24
24
 
25
25
  **Composite / line-item children** (invoice + line items, form + questions) are meaningless alone and edited atomically with the parent: master-detail *form* treatment — an editable grid inside the parent's create/edit surface, saved as one unit. Giving line items related-tab navigation produces absurd flows (navigate away from an unsaved invoice to create its second line).
26
26
 
27
- **Denormalization is an explicit pass:** for every relationship ask "which fields from the other side must appear here without a click?" — parent identity fields on child rows (lookups), child aggregates on parents (rollups). Skipping it is why v1 tables show bare foreign-key names.
27
+ **Denormalization is an explicit pass:** for every relationship ask "which fields from the other side must appear here without a click?" — parent identity fields on child rows (lookups), child aggregates on parents (rollups). Skipping it leaves tables showing bare foreign-key names.
28
28
 
29
29
  **Users are objects in the model.** There is no separate collaboration layer: ownership, assignment, watching, comments, @mentions, and read/unread are ordinary relationships between User and record. The test of a complete chart: three people touch every record — the model must say who owns it, who watches it, who said what, who has seen it. The User object carries `actor ∈ {human, agent}`; agents are Users, but the fork must be declared because assignment, delegation, audit origin, and access all branch on it.
30
30
 
31
- Consult this file once per relationship decision; if cardinality is not yet known, clarify before assigning any treatment.
31
+ Consult this file once per relationship decision; if cardinality is unknown, clarify before assigning any treatment.
32
32
 
33
33
  ```json decision-table
34
34
  {"pass": "object-model", "rows": [
@@ -15,7 +15,7 @@ license: open
15
15
 
16
16
  **Prominence = frequency × criticality, computed per role. Parenthood is not the driver.** Parent/child position in the schema is a data-integrity fact; it says nothing about how often a human opens the object. The canonical counterexample: in a CRM, Account is the parent of Leads, Contacts, and Opportunities — and it is demoted; reps live in Leads, Opportunities, and Tasks. If you find yourself promoting an object because "it's the parent," ask instead who opens it, how often, and what breaks if they can't — that answer sets the sidebar. Without a frequency reading per role, prominence cannot be computed: clarify.
17
17
 
18
- **Prominence is per persona × plan.** An object demoted for a rep is promoted for the ops admin who lives in it; the same schema yields different sidebars per role. Plan-gated items change what each tenant's sidebar contains (whether locked items render hidden or as upsell is `viewer-context`'s call). Agents and agent surfaces now compete for promoted slots like any object.
18
+ **Prominence is per persona × plan.** An object demoted for a rep is promoted for the ops admin who lives in it; the same schema yields different sidebars per role. Plan-gated items change what each tenant's sidebar contains (whether locked items render hidden or as upsell is `viewer-context`'s call). Agents and agent surfaces compete for promoted slots like any object.
19
19
 
20
20
  **The demotion contract** — demotion is only safe when two guarantees hold, or it punishes users:
21
21
  1. **Creatable in context** — every demoted object is creatable from inside the flows of promoted objects that reference it (nested create-in-context: "+ New Account" inside the Lead form). If a rep must abandon a half-filled form to create the parent first, the demotion has failed.
@@ -21,7 +21,7 @@ license: open
21
21
 
22
22
  **Risk class dictates the interaction tier.** *Preferences* (personal, reversible, instant): autosave silently, no confirm — friction here is pure tax. *Behavior config* (affects others, reversible): explicit save plus a changelog entry, and the setting's own Logged history answers "who changed this and when." *Structural & destructive* (schema changes, role edits, SSO, retention, deletion): the full ceremony — **draft → impact preview → publish**, where the impact preview is the load-bearing step ("this role change affects 34 users"; "changing this field type will truncate 1,204 values"); add maker-checker where policy demands, isolate the irreversible in a type-to-confirm **danger zone**, and log everything to the org audit trail. Tier-3 changes deserve the test-before-live discipline of the AI layer's agent CI (simulate the rule against yesterday's traffic before publishing).
23
23
 
24
- **The inheritance cascade — the most underserved settings pattern.** Any setting existing at more than one scope forms a cascade (org default → team override → user override), and the UI must solve the resolved-value problem: show the **effective value** the viewer gets, show **where it came from** ("inherited from Organization" vs "overridden here"), and offer **reset to inherit** as a first-class action distinct from "set to the same value." Once a cascade exists, impersonation/view-as is the only honest debugger. **Findability**: settings search is mandatory past ~30 nodes (admins remember words, not the tree), every setting has a stable deep link, and the in-context gear links bidirectionally between a governed surface and the setting that governs it. **The AI subjects (2026)**: build-time generation compiles NL to an inspectable artifact editable before commit — never a black box; the agent governance console (identities, model-routing, data masking, permission scoping, the AI-action audit view) is a new org-scope subject. Anti-patterns forbidden: the junk drawer, features hiding in settings (saved views, dashboards, templates are product surfaces, not settings), modal settings, and the invisible cascade. A settings page whose scope is undeclared cannot be placed or permissioned: clarify.
24
+ **The inheritance cascade — the most underserved settings pattern.** Any setting existing at more than one scope forms a cascade (org default → team override → user override), and the UI must solve the resolved-value problem: show the **effective value** the viewer gets, show **where it came from** ("inherited from Organization" vs "overridden here"), and offer **reset to inherit** as a first-class action distinct from "set to the same value." Once a cascade exists, impersonation/view-as is the only honest debugger. **Findability**: settings search is mandatory past ~30 nodes (admins remember words, not the tree), every setting has a stable deep link, and the in-context gear links bidirectionally between a governed surface and the setting that governs it. **The AI subjects**: build-time generation compiles NL to an inspectable artifact editable before commit — never a black box; the agent governance console (identities, model-routing, data masking, permission scoping, the AI-action audit view) is an org-scope subject. Anti-patterns forbidden: the junk drawer, features hiding in settings (saved views, dashboards, templates are product surfaces, not settings), modal settings, and the invisible cascade. A settings page whose scope is undeclared cannot be placed or permissioned: clarify.
25
25
 
26
26
  ```json decision-table
27
27
  {"pass": "settings", "rows": [
@@ -21,7 +21,7 @@ license: open
21
21
 
22
22
  **Audit has two surfaces, both outputs of the Logged history class at different scopes.** Per-object history is the record-scoped timeline on every detail page. The **global audit log** is an org-scope, append-only index of who-did-what-when across security-relevant actions — logins, permission changes, deletions, exports, setting changes, and every impersonation session (impersonation is always logged, no exceptions) — filterable by actor/action/object/time, searchable, exportable; for SOC2/enterprise buyers it is a purchase criterion, not an afterthought.
23
23
 
24
- **Admin pages are indexes and forms over the org's meta-objects.** User management (invite — noting SSO/SCIM may provision users externally, so the invite form is not the only entry point — role assignment, deactivation) must trigger an **ownership-transfer flow** on deactivation: reassign the departing user's records before the account closes, or orphaned records are guaranteed. Roles & permissions is the admin surface for the access layers, paired with **impersonation/view-as** — once record- and field-level access exist, "log in as this user" is the only practical way to debug what a person actually sees. Seats & licenses render "X of Y seats used," pending invites, and reclaim-on-deactivation. Billing is brief here; customer-facing usage/billing surfaces are deferred.
24
+ **Admin pages are indexes and forms over the org's meta-objects.** User management (invite — noting SSO/SCIM may provision users externally, so the invite form is not the only entry point — role assignment, deactivation) must trigger an **ownership-transfer flow** on deactivation: reassign the departing user's records before the account closes, or orphaned records are guaranteed. Roles & permissions is the admin surface for the access layers, paired with **impersonation/view-as** — once record- and field-level access exist, "log in as this user" is the only practical way to debug what a person actually sees. Seats & licenses render "X of Y seats used," pending invites, and reclaim-on-deactivation. Billing is brief here; customer-facing usage/billing surfaces are out of scope.
25
25
 
26
26
  **Integrations resolve to objects, never a free-floating layer.** External data always maps to objects and fields: a connect flow (OAuth or keys, workspace scope), a **field-mapping editor** (their "Company" ↔ your "Account," with sync direction and frequency per mapping), and **connection health** (status, last successful sync, error counts, per-connection sync logs as an index of sync events); synced fields carry their origin declaration wherever they render. When a standard-page request omits which meta-object it is over, its contract cannot be derived: clarify.
27
27
 
@@ -1,27 +1,39 @@
1
1
  # validate-design-md.mjs — the design.md system's validator + token emitter
2
2
 
3
- **CLI:** `node validate-design-md.mjs <file|folder> [--mode admission|build|ship] [--json] [--emit]`
3
+ **CLI:** `node validate-design-md.mjs (<file|folder> | --project [dir]) [--mode admission|build|ship] [--json] [--emit] [--emit-personality] [--write] [--lib <folder>]`
4
4
  File mode validates one design.md. Folder mode validates every `.md` in the tree (skipping `SCHEMA.md`) plus `index.csv` integrity.
5
- `admission` and `build` run the same checks; `ship` adds the dmv-11 drift check against a `design.tokens.css` beside the input file.
5
+ `--project [dir]` validates the project's own fork, located by the repo's shape: `packages/common/design.md` in a multi-package
6
+ workspace, `src/common/design.md` in a single-package repo (`dir` defaults to the cwd; an absent file fails closed, naming the path).
7
+ `admission` and `build` run the same checks; `ship` adds the dmv-11 drift check against a `design.tokens.css` beside the input file,
8
+ and dmv-12's drift check against `personality.css`.
6
9
  `--json` prints `{file, fails:[{id,detail}], warns:[{id,detail}]}` (array in folder mode). Exit 0 on pass (warns allowed), 1 on any FAIL.
7
10
 
8
11
  **Emit:** `--emit` (single file) compiles the token artifact from the `yaml design-values` block to stdout — deterministic, byte-stable;
9
- redirect to `design.tokens.css`. Shape: `:root, :root[data-theme="light"]` + `:root[data-theme="dark"]` blocks (specificity armor, both
10
- 0,2,0) carrying the 36 color roles as `--<role>`; the light block also carries `--font-display/sans/mono` (registered names quoted, with
11
- fallback stacks), `--text-<step>-size/-line/-weight` (+ `-family/-tracking/-features`), `--radius-*`, `--shadow-*`, `--duration-*`,
12
- `--ease-*`, and layout vars (`--space-base`, `--sidebar-width[-collapsed]`, `--topbar-height`, `--side-panel-width[-wide]`, `--content-max-width`).
12
+ redirect to `design.tokens.css`, or add `--write` to write it beside the design.md. Shape: three blocks. A bare `:root` carries every
13
+ theme-invariant token — `--font-display/sans/mono` (registered names quoted, with fallback stacks), the ramp as `--text-<step>` with
14
+ `--line-height`/`--font-weight`/`--letter-spacing` sub-keys, `--radius-*`, `--shadow-*`, `--duration-*`, `--ease-*`, and layout vars
15
+ (`--space-base`, `--sidebar-width[-collapsed]`, `--topbar-height`, `--side-panel-width[-wide]`, `--content-max-width`). Then
16
+ `:root:not(.dark)` and `:root.dark` (specificity armor, both 0,2,0) carry the color roles as `--<role>`.
17
+ `--emit-personality` (`primitives: nurix`) hands the design.md's `personality` traits to `@nurix/components`' own compiler
18
+ (`compileToCss` from `@nurix/components/lib/personality`) and prints `personality.css`, or writes it with `--write`; `--lib <folder>`
19
+ names where the library is installed when the resolver cannot tell. Any FAIL suppresses either artifact.
13
20
 
14
21
  **Fails (close the gate):** dmv-01 frontmatter strict, per-tier keys, id = filename · dmv-02 the 12 sections in order, non-empty,
15
22
  plus trailing design-values block · dmv-03 value block parses as YAML · dmv-04 coverage: 36 roles × both themes, ramp, register-scope,
16
23
  elevation, motion base, iconography, charts, layout · dmv-05 contrast on every declared pairing (body ≥ 4.5:1; primary/accent/
17
24
  destructive/sidebar-primary fills ≥ 3:1, warn under 4.5) · dmv-06 no image reference anywhere · dmv-07 index.csv ↔ files, both
18
25
  directions, no duplicates · dmv-08 registered font names + fallback stacks · dmv-09 no claude.md (any case) · dmv-10 project tier:
19
- `primitives: nurix|native` + `source-package` · dmv-11 (ship) emitted artifact byte-matches recompilation.
26
+ `primitives: nurix|native` + `source-package` · dmv-11 (ship) emitted artifact byte-matches recompilation · dmv-12 the
27
+ `personality` block (`primitives: nurix` only) uses the six traits `density|pace|edge|depth|texture|accent` with their closed values
28
+ (`pace` a number 0..1; a `tone` key fails naming `accent`, as the library's compiler rejects it), and under `--mode ship`
29
+ `personality.css` byte-matches the recompiled artifact.
20
30
 
21
31
  **Warns (recorded, never close):** dmw-01 background in the anti-cream band (L 0.84–0.97, C < 0.06, hue 40–100) · dmw-02 neutral
22
32
  surfaces pure gray (C < 0.005) or over-tinted (C > 0.015) · dmw-03 untinted black shadow above 0.15 alpha · dmw-04 ease-in entrance
23
33
  or duration over its element-class budget · dmw-05 display face granted a data register · dmw-06 dark ladder steps < ~0.04 L or hue
24
- drift · dmw-07 accent chroma delta between themes > 0.06.
34
+ drift · dmw-07 accent chroma delta between themes > 0.06 · dmw-08 the dense operator tier unadopted (`typography.ramp` omits the
35
+ optional steps) · dmw-09 (`primitives: nurix`) no personality block, so the library's neutral traits ship · dmw-10 (`primitives: nurix`)
36
+ the `info` role undeclared, so `--intent-info` falls back to the library's own hue.
25
37
 
26
38
  Stdlib-only: vendors its own YAML-subset parser and oklch → sRGB → WCAG-contrast math. The exact contrast pair table, thresholds,
27
39
  and emission order live in the script's header comment.
@@ -62,13 +62,14 @@
62
62
  // dmv-11 (--mode ship) drift: the token artifact recompiled from the design.md byte-matches the
63
63
  // design.tokens.css beside it.
64
64
  // dmv-12 the personality block (primitives: nurix): a mapping over the six closed-vocabulary traits
65
- // density|pace|edge|depth|texture|tone (pace a number 0..1); absent under native. In --mode
65
+ // density|pace|edge|depth|texture|accent (pace a number 0..1; a `tone` key fails naming
66
+ // `accent`, as the library's compiler rejects it); absent under native. In --mode
66
67
  // ship, personality.css beside the design.md byte-matches the recompiled artifact, and no
67
68
  // personality.css exists without a block (a hand-authored layer).
68
69
  //
69
70
  // WARN checks (never close): dmw-01 anti-cream backgrounds · dmw-02 neutral tint · dmw-03 untinted shadows ·
70
- // dmw-04 motion budgets · dmw-05 personality block absent on a nurix project (the library's neutral
71
- // traits ship) · dmw-06 `info` role undeclared on a nurix project (--tone-info falls back to the
71
+ // dmw-04 motion budgets · dmw-09 personality block absent on a nurix project (the library's neutral
72
+ // traits ship) · dmw-10 `info` role undeclared on a nurix project (--intent-info falls back to the
72
73
  // library's own hue).
73
74
  //
74
75
  // dmv-05 — the exact contrast pair table (both themes; WCAG 2.1 relative-luminance contrast; colors
@@ -106,6 +107,8 @@
106
107
  // dmw-07 accent chroma delta between themes > 0.06 (identity likely not held across themes).
107
108
  //
108
109
  // dmw-08 the dense operator tier is unadopted: typography.ramp omits optional steps (one warn per package).
110
+ // dmw-09 (primitives: nurix) no personality block — the library's neutral traits ship.
111
+ // dmw-10 (primitives: nurix) the `info` role undeclared — --intent-info falls back to the library's own hue.
109
112
  //
110
113
  // Emitted artifact shape (deterministic, byte-stable): THREE blocks. A bare `:root` carries every
111
114
  // theme-invariant group — --font-display/sans/mono (registered names quoted, fallback stacks appended),
@@ -148,18 +151,18 @@ const RAMP_STEPS_OPTIONAL = ["title", "h3", "prose", "control-lg", "dense", "con
148
151
  const RAMP_STEPS = [...RAMP_STEPS_REQUIRED, ...RAMP_STEPS_OPTIONAL];
149
152
  const FONT_SLOTS = ["display", "sans", "mono"];
150
153
  // Optional color roles: emitted only when declared (both themes or neither). `info` completes the
151
- // success/warning/info trio @nurix/components' status dots read through --tone-*.
154
+ // success/warning/info trio @nurix/components' status dots read through --intent-*.
152
155
  const OPTIONAL_COLOR_ROLES = ["info"];
153
156
  // The personality block — six closed-vocabulary traits @nurix/components compiles into the token
154
157
  // families its components read (lib/personality). The library owns the vocabulary; this mirrors it.
155
- const PERSONALITY_ORDER = ["density", "pace", "edge", "depth", "texture", "tone"];
158
+ const PERSONALITY_ORDER = ["density", "pace", "edge", "depth", "texture", "accent"];
156
159
  const PERSONALITY_TRAITS = {
157
160
  density: ["compact", "regular", "airy"],
158
161
  pace: null, // the one scalar: 0 still · 0.5 the library's neutral timing · 1 lively
159
162
  edge: ["sharp", "regular", "soft"],
160
163
  depth: ["flat", "layered", "elevated"],
161
164
  texture: ["clean", "grainy"],
162
- tone: ["neutral", "expressive"],
165
+ accent: ["neutral", "expressive"],
163
166
  };
164
167
  const THEMES = ["light", "dark"];
165
168
  const TIERS = ["default", "variant", "brand", "project"];
@@ -750,13 +753,13 @@ function checkCoverage(values, report) {
750
753
  else if (layout.base == null) missing("layout.base");
751
754
  }
752
755
 
753
- // dmv-12 — the personality block, and the two nurix-project warns (dmw-05 block absent, dmw-06 info absent).
756
+ // dmv-12 — the personality block, and the two nurix-project warns (dmw-09 block absent, dmw-10 info absent).
754
757
  function checkPersonality(front, values, report) {
755
758
  const isNurixProject = !!front && front.tier === "project" && front.primitives === "nurix";
756
759
  const p = values.personality;
757
760
  if (p === undefined) {
758
761
  if (isNurixProject) {
759
- warn(report, "dmw-05", "personality block absent — @nurix/components ships its neutral traits (regular · pace 0.5 · regular · layered · grainy · neutral); declare the traits §4–§7 imply so density, motion, radius and depth reach the components");
762
+ warn(report, "dmw-09", "personality block absent — @nurix/components ships its neutral traits (regular · pace 0.5 · regular · layered · grainy · neutral); declare the traits §4–§7 imply so density, motion, radius and depth reach the components");
760
763
  }
761
764
  } else if (!isObj(p)) {
762
765
  fail(report, "dmv-12", "personality must be a mapping of traits");
@@ -765,7 +768,9 @@ function checkPersonality(front, values, report) {
765
768
  fail(report, "dmv-12", "personality is compiled by @nurix/components — under primitives: native nothing reads it; drop the block or switch primitives");
766
769
  }
767
770
  for (const [k, v] of Object.entries(p)) {
768
- if (!(k in PERSONALITY_TRAITS)) {
771
+ if (k === "tone") {
772
+ fail(report, "dmv-12", `personality.tone is not a trait — the accent trait carries that axis (accent: ${PERSONALITY_TRAITS.accent.join("|")}); the library's compiler rejects tone`);
773
+ } else if (!(k in PERSONALITY_TRAITS)) {
769
774
  fail(report, "dmv-12", `personality.${k} is not a trait (${PERSONALITY_ORDER.join("|")})`);
770
775
  } else if (k === "pace") {
771
776
  const n = typeof v === "number" ? v : Number(v);
@@ -787,7 +792,7 @@ function checkPersonality(front, values, report) {
787
792
  const bad = THEMES.filter((t) => !parseColor(color[t][role]));
788
793
  if (bad.length) fail(report, "dmv-04", `color.${role} unparseable in ${bad.join(", ")}`);
789
794
  } else if (isNurixProject) {
790
- warn(report, "dmw-06", `color.${role} undeclared — @nurix/components' --tone-${role} falls back to the library's own hue beside your success/warning; declare it in both themes`);
795
+ warn(report, "dmw-10", `color.${role} undeclared — @nurix/components' --intent-${role} falls back to the library's own hue beside your success/warning; declare it in both themes`);
791
796
  }
792
797
  }
793
798
  }
@@ -3,7 +3,7 @@ name: documentation
3
3
  description: "Use when creating or substantively editing ANY markdown doc — invoke BEFORE writing. Genre registry, templates and style authority for technical docs: LLDs, ADs, plans, changelogs, READMEs, runbooks. Owns the tense rule: truth docs state the present; history only in dated records. Baselining is the maintenance agent."
4
4
  ---
5
5
 
6
- # Technical Documentation Skill
6
+ # Technical documentation skill
7
7
 
8
8
  This skill writes one document at a time: the genre registry says what kind of document it is, a template gives its shape, the style guide its prose, and `doc-lint` checks the mechanical half. It does not baseline, audit or reconcile a repo's doc tree; that is the `maintenance` agent, which calls this skill once per document it scaffolds.
9
9
 
@@ -67,7 +67,7 @@ The full strip-list and the record-side rules: `references/style-guide.md` § Th
67
67
  - **Intent and promises; facts are the graph's.** An owning document (feature, package, system) says why the product is shaped this way and what it promises, and names the objects it designs in `objects:`. Every computable fact (a table's columns, which function writes which column, which route sits behind which guard, which file holds what) is the code's, and a hand-typed copy is wrong the day the code moves. `doc-lint` blocks the retired mechanism sections (`mechanism-section`) and an owning document with no `objects:`.
68
68
  - **Read by people, pointed at by the footer.** Sharp bullets under noun-phrase headings, each a bold label, a colon, one or two plain sentences; code named only where a person types or sees it, or at a cross-cutting seam; every other pointer in the closing **For the agent** footer (style guide § Owning documents — the body and the footer).
69
69
  - **The stability test.** A sentence that would change when a function is renamed, a file moves, or a route, column or error code changes is the code's, not the document's. The code is the authority on *what*; the document on *why* (style guide § Shape).
70
- - **Unbuilt work has one home per kind.** Decided design the code does not yet do sits in the body, wrapped in an `UNBUILT` marker; a shortfall in what is built is one bullet under Gaps; the work that would close either is a backlog row, which the document never tracks (style guide § The stability test).
70
+ - **Unbuilt work has one home per kind.** Decided, unbuilt design sits in the body, wrapped in an `UNBUILT` marker; a shortfall in what is built is one bullet under Gaps; the work that would close either is a backlog row, which the document never tracks (style guide § The stability test).
71
71
  - **No empty stubs.** Omit a section with nothing real to say. Write "None" only where the absence is itself information, such as a plan's Cross-Module Contracts Affected.
72
72
  - **No redirect documents.** Moving a document deletes the old file and repoints every inbound link; a "Moved to X" stub rots and creates false search hits.
73
73
 
@@ -78,9 +78,9 @@ The full strip-list and the record-side rules: `references/style-guide.md` § Th
78
78
  - **The links an index may carry:** a sibling folder's `Readme.md`, the mandated scaffolds (`structure.md`, `operations/setup.md`, `history/CHANGELOG.md`, `history/backlog.md`, `history/journal.md`, `history/health-log.md`, `memory/main.md`), and the root `CLAUDE.md` and `AGENTS.md`. `doc-lint` blocks the rest under `docs/` as `index-lists-files`, a drawn tree as `index-file-tree`, a named file or record as `index-names-records`.
79
79
  - **Routing documents point at truth.** A "read first" row names the topic's truth document, never a plan or changelog entry. An index of the records themselves (a History section naming `plans/` and `changelog/`) is sanctioned.
80
80
 
81
- ### Ownership today
81
+ ### Ownership edges
82
82
 
83
- A document names the objects it designs in `objects:`, and a source file names the document that speaks for it in its path header. The harness's ownership scan reads one edge today: the transitional `owns:` region glob on each feature, package, system and surface-owning UX document, the narrower glob winning. Write the header pointer anyway, so the scan can switch to it and to the object closure without a second pass over the code. Where a repository has no `docs/architecture/systems/knowledge-layer.md`, this skill and `references/frontmatter.md` are the whole authority on document–code edges. `docs/structure.md` is harness-owned: the installer writes it, and the `maintenance` agent stamps only its `harness-version`.
83
+ A document names the objects it designs in `objects:`, and a source file names the document that speaks for it in its path header. The harness's ownership scan reads one edge: the transitional `owns:` region glob on each feature, package, system and surface-owning UX document, the narrower glob winning. **Always write the header pointer as well** — the scan switches to it and to the object closure, and pointers already in place spare that switch a second pass over the code. Where a repository has no `docs/architecture/systems/knowledge-layer.md`, this skill and `references/frontmatter.md` are the whole authority on document–code edges. `docs/structure.md` is harness-owned: the installer writes it, and the `maintenance` agent stamps only its `harness-version`.
84
84
 
85
85
  ---
86
86
 
@@ -113,7 +113,7 @@ A document names the objects it designs in `objects:`, and a source file names t
113
113
  | Scaffold a standard doc (docs index, changelog guide, backlog, memory) | The registry's § Baseline scaffolds |
114
114
  | Frontmatter keys (`objects:`, `verifies:`, the transitional `owns:`) | [`references/frontmatter.md`](references/frontmatter.md) |
115
115
  | Source-file comments: what stays, what moves to a doc, proving a sweep | [`references/source-comments.md`](references/source-comments.md) |
116
- | Instruction file (`CLAUDE.md`, a rule, an agent, skill prose) | [`references/instruction-style.md`](references/instruction-style.md): every-load prose stays lean; the present-tense rule still applies |
116
+ | Instruction file (`CLAUDE.md`, a rule, an agent, skill prose) | [`references/instruction-style.md`](references/instruction-style.md): every-load prose stays lean; the present-tense rule applies too |
117
117
  | Author or restructure a skill | The skill-authoring field guide in the etna repo (`nurixlabs/etna`), `docs/playbooks/skills/`. No etna checkout ⇒ ask the user for access, or proceed from first principles with `references/instruction-style.md` governing the prose |
118
118
  | No template matches | [`references/untemplated.md`](references/untemplated.md) |
119
119
 
@@ -1,12 +1,12 @@
1
- # Documentation Examples
1
+ # Documentation examples
2
2
 
3
- Good vs bad examples showing the key differences.
3
+ Good and bad documentation side by side; `style-guide.md` cites each example by number.
4
4
 
5
5
  ---
6
6
 
7
- ## Example 1: Function Documentation
7
+ ## Example 1: Function documentation
8
8
 
9
- ### Bad: Full Implementation
9
+ ### Bad: full implementation
10
10
 
11
11
  ```markdown
12
12
  ### mergeData
@@ -14,9 +14,9 @@ Good vs bad examples showing the key differences.
14
14
  function mergeData(server, local, changes) { const result = {}; const serverMap = new Map(server.map((i) => [i.id, i])); // ... 30 more lines return result; }
15
15
  ```
16
16
 
17
- **Problems:** Will become obsolete, focuses on HOW not WHAT.
17
+ **Problems:** goes stale with the first refactor; shows *how* instead of *what*.
18
18
 
19
- ### Good: Contract Only
19
+ ### Good: contract only
20
20
 
21
21
  ```markdown
22
22
  ### `mergeData(serverData, localData, changes)`
@@ -40,9 +40,9 @@ function mergeData(server, local, changes) { const result = {}; const serverMap
40
40
 
41
41
  ---
42
42
 
43
- ## Example 2: State Documentation
43
+ ## Example 2: State documentation
44
44
 
45
- ### Bad: State Everywhere
45
+ ### Bad: state everywhere
46
46
 
47
47
  ```markdown
48
48
  ## Component State
@@ -58,9 +58,9 @@ const [items, setItems] = useState([]);
58
58
  { items: [], loading: false, error: null }
59
59
  ```
60
60
 
61
- **Problems:** Documents transient state, repeats shapes.
61
+ **Problems:** documents transient state and repeats shapes.
62
62
 
63
- ### Good: Persistence Points Only, in the API reference
63
+ ### Good: persistence points only, in the API reference
64
64
 
65
65
  Persisted shapes live in the API reference (`docs/architecture/api.md`), never in a feature document, where `## State` is a retired mechanism section.
66
66
 
@@ -89,7 +89,7 @@ export const items = pgTable('items', {
89
89
 
90
90
  ## Example 3: Changelog
91
91
 
92
- ### Bad: Vague
92
+ ### Bad: vague
93
93
 
94
94
  ```markdown
95
95
  # 2025-01-05 - Updates
@@ -105,7 +105,7 @@ export const items = pgTable('items', {
105
105
  - Various files in src/
106
106
  ```
107
107
 
108
- ### Good: Behavior First, Refinement Context Kept
108
+ ### Good: behavior first, refinement context kept
109
109
 
110
110
  ```markdown
111
111
  # 2025-01-05 · data-sync — Local edits survive a sync only when versions match
@@ -123,7 +123,7 @@ export const items = pgTable('items', {
123
123
 
124
124
  ## Example 4: Flow
125
125
 
126
- ### Bad: Mechanism narrated in a paragraph
126
+ ### Bad: mechanism narrated in a paragraph
127
127
 
128
128
  ```markdown
129
129
  ## Data Flow
@@ -133,7 +133,7 @@ When the page loads, the useAppInit hook calls the syncData function. This funct
133
133
 
134
134
  **Problems:** names a hook, a function and a store that a rename would invalidate (the stability test); runs parallel cases together in one paragraph; gives a scanning reader no label to land on; "Data Flow" is a retired mechanism section.
135
135
 
136
- ### Good: Labelled bullets, a role-level diagram beside them
136
+ ### Good: labelled bullets, a role-level diagram beside them
137
137
 
138
138
  ````markdown
139
139
  ## Flows
@@ -161,7 +161,7 @@ sequenceDiagram
161
161
 
162
162
  ## Example 5: Architecture Decision revision
163
163
 
164
- ### Bad: Supersession chain
164
+ ### Bad: supersession chain
165
165
 
166
166
  ```
167
167
  docs/architecture/decisions/
@@ -170,9 +170,9 @@ docs/architecture/decisions/
170
170
  └── AD-011-auth-better-auth-v2.md (status: Accepted, "supersedes AD-006")
171
171
  ```
172
172
 
173
- **Problems:** Three files hold one subject; the reader must diff a chain to learn the current truth; two of the three are wrong-but-present (the same pathology as keeping `report_v1.sql` beside the live `report_v2.sql`); the reasoning that killed Keycloak is stranded in a dead file nobody opens.
173
+ **Problems:** three files hold one subject; the reader must diff a chain to learn the current truth; two of the three are wrong-but-present (the same pathology as keeping `report_v1.sql` beside the live `report_v2.sql`); the reasoning that killed Keycloak is stranded in a dead file nobody opens.
174
174
 
175
- ### Good: One subject, updated in place
175
+ ### Good: one subject, updated in place
176
176
 
177
177
  ```
178
178
  docs/architecture/decisions/
@@ -195,15 +195,15 @@ We use Better Auth with one-shot credential issuance… ← current truth, no
195
195
  - 2026-01-10 — Initial decision accepted. Implemented by [plan](…).
196
196
  ```
197
197
 
198
- **Why it works:** The body answers "how does auth work and why" without archaeology; the tail preserves every reversal with its trigger; the rejected alternatives stay findable in the one file a reader actually opens.
198
+ **Why it works:** the body answers "how does auth work and why" without archaeology; the tail preserves every reversal with its trigger; the rejected alternatives stay findable in the one file a reader actually opens.
199
199
 
200
200
  ---
201
201
 
202
202
  ## Example 6: Stripping history from a truth doc
203
203
 
204
- The move agents fumble: deleting narration is only half the job — the story must land in a record.
204
+ Deleting narration is only half the move; the story **must** land in a record.
205
205
 
206
- ### Bad: The journey narrated in place
206
+ ### Bad: the journey narrated in place
207
207
 
208
208
  ```markdown
209
209
  ## Export Pipeline
@@ -214,7 +214,7 @@ output is not yet implemented. Treat any reference to `reports/export.js` as
214
214
  stale — it was superseded by `src/export/run.js`.
215
215
  ```
216
216
 
217
- ### Good: Present-tense truth doc + a dated record carrying the story
217
+ ### Good: present-tense truth doc + a dated record carrying the story
218
218
 
219
219
  The feature doc states only what is:
220
220
 
@@ -243,7 +243,7 @@ And the change-story goes to `docs/history/changelog/2026-06-02-export-extractio
243
243
 
244
244
  ---
245
245
 
246
- ## Quick Comparison
246
+ ## Quick comparison
247
247
 
248
248
  | Aspect | Bad | Good |
249
249
  | ---------- | -------------------- | --------------------------- |
@@ -6,7 +6,7 @@ This reference states how a document joins the knowledge graph, and it is kept i
6
6
 
7
7
  ## The model
8
8
 
9
- A document names the product objects it designs. Every other edge between a document and the code is either authored on the code's side or computed, never typed into the document. The harness's ownership scan reads one edge today, the transitional `owns:` region glob (§ `owns:`); principles 2 and 3 are the edges it switches to, and the header pointer is written now so the switch needs no second pass over the code.
9
+ A document names the product objects it designs. Every other edge between a document and the code is either authored on the code's side or computed, never typed into the document. The harness's ownership scan reads one edge, the transitional `owns:` region glob (§ `owns:` — transitional); principles 2 and 3 are the edges it switches to, and the header pointer is written alongside it so the switch needs no second pass over the code.
10
10
 
11
11
  ### Principles
12
12
 
@@ -63,7 +63,7 @@ Tooling keys sit beside these on any genre: `rev:` (a generator's generation sta
63
63
 
64
64
  ### `owns:` — transitional
65
65
 
66
- - **Reason for the key:** the harness's ownership scan (`.claude/hooks/lib/ownership.mjs`) keys on `owns:` until it switches to the header pointers and the object closure, which is the knowledge layer's recorded gap. Until then the key keeps the session's ownership index and the doc-debt detectors working.
66
+ - **Reason for the key:** the harness's ownership scan (`.claude/hooks/lib/ownership.mjs`) keys on `owns:` until it switches to the header pointers and the object closure, which is the knowledge layer's recorded gap. The key is what keeps the session's ownership index and the doc-debt detectors working.
67
67
  - **Form:** region globs only, one per region the document speaks for: `packages/{name}/**` on a package document, the machine's subtrees on a system document, a feature's own directory on a feature document. Never a list of individual files, and never a shared file several features import.
68
68
  - **Growth:** none. A new document carries the region glob its genre needs and nothing more; an edit never adds file-level entries.
69
69
  - **Retirement:** removed from every document in the same change that switches the scan, and this section with it.
@@ -73,7 +73,7 @@ Tooling keys sit beside these on any genre: `rev:` (a generator's generation sta
73
73
  | Key | Retired because | What replaces it |
74
74
  | --- | --- | --- |
75
75
  | `applies:` | A list of governing documents is a hand-kept copy of a relationship the graph computes through the objects both documents name, and it drifts the way any copy does | The objects the doctrine and the surface share, computed; for people, the document's Scope section (a UX document's Purpose) names its governing doctrine and what each settles |
76
- | `keywords:` | An object's name and aliases are its discovery terms | `objects:`. The ownership scan still shows a document's `keywords:` in the index when it names no `objects:`, so removing the key without adding `objects:` empties that entry |
76
+ | `keywords:` | An object's name and aliases are its discovery terms | `objects:`. The ownership scan shows a document's `keywords:` in the index when it names no `objects:`, so removing the key without adding `objects:` empties that entry |
77
77
  | A file-level `owns:` list | The header pointers and the object closure compute it | Region globs only, until the scan switches (above) |
78
78
 
79
79
  An edit to a document that carries a retired key removes the key in the same edit.