@nurix/etna 0.19.51 → 0.19.53

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 (156) hide show
  1. package/data/harness-index.json +1 -1
  2. package/data/harnesses/apollo/.mcp.json +8 -0
  3. package/data/harnesses/apollo/harness.json +3 -2
  4. package/data/harnesses/apollo/skills/design/SKILL.md +45 -50
  5. package/data/harnesses/apollo/skills/design/data/blueprints/browse.md +38 -0
  6. package/data/harnesses/apollo/skills/design/data/blueprints/creation-flow.md +38 -0
  7. package/data/harnesses/apollo/skills/design/data/blueprints/dashboard.md +38 -0
  8. package/data/harnesses/apollo/skills/design/data/blueprints/grid.md +38 -0
  9. package/data/harnesses/apollo/skills/design/data/blueprints/queue.md +38 -0
  10. package/data/harnesses/apollo/skills/design/data/blueprints/record-detail.md +38 -0
  11. package/data/harnesses/apollo/skills/design/data/blueprints/settings.md +38 -0
  12. package/data/harnesses/apollo/skills/design/data/charts/census.csv +58 -0
  13. package/data/harnesses/apollo/skills/design/data/checklists/browse.md +21 -0
  14. package/data/harnesses/apollo/skills/design/data/checklists/creation-flow.md +20 -0
  15. package/data/harnesses/apollo/skills/design/data/checklists/dashboard.md +21 -0
  16. package/data/harnesses/apollo/skills/design/data/checklists/grid.md +21 -0
  17. package/data/harnesses/apollo/skills/design/data/checklists/queue.md +21 -0
  18. package/data/harnesses/apollo/skills/design/data/checklists/record-detail.md +21 -0
  19. package/data/harnesses/apollo/skills/design/data/checklists/settings.md +21 -0
  20. package/data/harnesses/apollo/skills/design/data/chrome/board-column.md +68 -0
  21. package/data/harnesses/apollo/skills/design/data/chrome/data-table.md +63 -0
  22. package/data/harnesses/apollo/skills/design/data/chrome/side-panel.md +60 -0
  23. package/data/harnesses/apollo/skills/design/data/chrome/sidebar.md +78 -0
  24. package/data/harnesses/apollo/skills/design/data/chrome/stat-cards.md +62 -0
  25. package/data/harnesses/apollo/skills/design/data/chrome/topbar.md +65 -0
  26. package/data/harnesses/apollo/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  27. package/data/harnesses/apollo/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  28. package/data/harnesses/apollo/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  29. package/data/harnesses/apollo/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  30. package/data/harnesses/apollo/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  31. package/data/harnesses/apollo/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  32. package/data/harnesses/apollo/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  33. package/data/harnesses/apollo/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  34. package/data/harnesses/apollo/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  35. package/data/harnesses/apollo/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  36. package/data/harnesses/apollo/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  37. package/data/harnesses/apollo/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  38. package/data/harnesses/apollo/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  39. package/data/harnesses/apollo/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  40. package/data/harnesses/apollo/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  41. package/data/harnesses/apollo/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  42. package/data/harnesses/apollo/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  43. package/data/harnesses/apollo/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  44. package/data/harnesses/apollo/skills/design/data/iconography.md +199 -0
  45. package/data/harnesses/apollo/skills/design/data/motion/accordion-expand.md +18 -0
  46. package/data/harnesses/apollo/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  47. package/data/harnesses/apollo/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  48. package/data/harnesses/apollo/skills/design/data/motion/empty-state-arrive.md +18 -0
  49. package/data/harnesses/apollo/skills/design/data/motion/hover-lift.md +18 -0
  50. package/data/harnesses/apollo/skills/design/data/motion/modal-center-arrive.md +18 -0
  51. package/data/harnesses/apollo/skills/design/data/motion/number-ticker-roll.md +18 -0
  52. package/data/harnesses/apollo/skills/design/data/motion/onboarding-bounce.md +18 -0
  53. package/data/harnesses/apollo/skills/design/data/motion/panel-slide.md +18 -0
  54. package/data/harnesses/apollo/skills/design/data/motion/press-feedback.md +18 -0
  55. package/data/harnesses/apollo/skills/design/data/motion/progress-linear-loop.md +18 -0
  56. package/data/harnesses/apollo/skills/design/data/motion/route-crossfade.md +18 -0
  57. package/data/harnesses/apollo/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  58. package/data/harnesses/apollo/skills/design/data/motion/skeleton-shimmer.md +18 -0
  59. package/data/harnesses/apollo/skills/design/data/motion/stagger-arrive.md +18 -0
  60. package/data/harnesses/apollo/skills/design/data/motion/toast-enter-stack.md +18 -0
  61. package/data/harnesses/apollo/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  62. package/data/harnesses/apollo/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  63. package/data/harnesses/apollo/skills/design/data/tells.csv +34 -0
  64. package/data/harnesses/apollo/skills/design/data/voices/bright-collaborator.md +29 -0
  65. package/data/harnesses/apollo/skills/design/data/voices/direct-operator.md +29 -0
  66. package/data/harnesses/apollo/skills/design/data/voices/earnest-helper.md +29 -0
  67. package/data/harnesses/apollo/skills/design/data/voices/editorial-composed.md +29 -0
  68. package/data/harnesses/apollo/skills/design/data/voices/quiet-concierge.md +29 -0
  69. package/data/harnesses/apollo/skills/design/data/voices/warm-guide.md +29 -0
  70. package/data/harnesses/apollo/skills/design/references/compose.md +3 -7
  71. package/data/harnesses/apollo/skills/design/references/content.md +4 -4
  72. package/data/harnesses/apollo/skills/design/references/existing-apps.md +1 -1
  73. package/data/harnesses/apollo/skills/design/references/foundations.md +57 -0
  74. package/data/harnesses/apollo/skills/design/references/intake.md +11 -11
  75. package/data/harnesses/apollo/skills/design/references/object-pass.md +1 -1
  76. package/data/harnesses/apollo/skills/design/references/ship-gate.md +1 -1
  77. package/data/harnesses/apollo/skills/design/scripts/select-chart.mjs +14 -8
  78. package/data/harnesses/apollo/skills/design/scripts/validate-design-md.mjs +1 -1
  79. package/data/harnesses/code/.mcp.json +8 -0
  80. package/data/harnesses/code/harness.json +4 -2
  81. package/data/harnesses/code/skills/design/SKILL.md +45 -50
  82. package/data/harnesses/code/skills/design/data/blueprints/browse.md +38 -0
  83. package/data/harnesses/code/skills/design/data/blueprints/creation-flow.md +38 -0
  84. package/data/harnesses/code/skills/design/data/blueprints/dashboard.md +38 -0
  85. package/data/harnesses/code/skills/design/data/blueprints/grid.md +38 -0
  86. package/data/harnesses/code/skills/design/data/blueprints/queue.md +38 -0
  87. package/data/harnesses/code/skills/design/data/blueprints/record-detail.md +38 -0
  88. package/data/harnesses/code/skills/design/data/blueprints/settings.md +38 -0
  89. package/data/harnesses/code/skills/design/data/charts/census.csv +58 -0
  90. package/data/harnesses/code/skills/design/data/checklists/browse.md +21 -0
  91. package/data/harnesses/code/skills/design/data/checklists/creation-flow.md +20 -0
  92. package/data/harnesses/code/skills/design/data/checklists/dashboard.md +21 -0
  93. package/data/harnesses/code/skills/design/data/checklists/grid.md +21 -0
  94. package/data/harnesses/code/skills/design/data/checklists/queue.md +21 -0
  95. package/data/harnesses/code/skills/design/data/checklists/record-detail.md +21 -0
  96. package/data/harnesses/code/skills/design/data/checklists/settings.md +21 -0
  97. package/data/harnesses/code/skills/design/data/chrome/board-column.md +68 -0
  98. package/data/harnesses/code/skills/design/data/chrome/data-table.md +63 -0
  99. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +60 -0
  100. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +78 -0
  101. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +62 -0
  102. package/data/harnesses/code/skills/design/data/chrome/topbar.md +65 -0
  103. package/data/harnesses/code/skills/design/data/elevation/ant-design-directional-shadow.md +19 -0
  104. package/data/harnesses/code/skills/design/data/elevation/apple-liquid-glass-material.md +18 -0
  105. package/data/harnesses/code/skills/design/data/elevation/atlassian-surface-shadow-pairing.md +20 -0
  106. package/data/harnesses/code/skills/design/data/elevation/fluent-2-key-ambient-ramp.md +20 -0
  107. package/data/harnesses/code/skills/design/data/elevation/github-primer-sparing-shadow.md +19 -0
  108. package/data/harnesses/code/skills/design/data/elevation/ibm-carbon-layer-and-border.md +19 -0
  109. package/data/harnesses/code/skills/design/data/elevation/linear-dark-surface-ladder.md +17 -0
  110. package/data/harnesses/code/skills/design/data/elevation/material-2-key-ambient-dp-ramp.md +19 -0
  111. package/data/harnesses/code/skills/design/data/elevation/material-3-tonal-elevation.md +21 -0
  112. package/data/harnesses/code/skills/design/data/elevation/neobrutalist-hard-offset.md +19 -0
  113. package/data/harnesses/code/skills/design/data/elevation/neumorphic-soft-dual-shadow.md +18 -0
  114. package/data/harnesses/code/skills/design/data/elevation/notion-warm-minimal-hairline.md +17 -0
  115. package/data/harnesses/code/skills/design/data/elevation/polaris-elevation-inset-bevel.md +21 -0
  116. package/data/harnesses/code/skills/design/data/elevation/radix-themes-alpha-ring-scale.md +19 -0
  117. package/data/harnesses/code/skills/design/data/elevation/shadcn-neutral-derived-radius.md +19 -0
  118. package/data/harnesses/code/skills/design/data/elevation/stripe-brand-tinted-dual-shadow.md +18 -0
  119. package/data/harnesses/code/skills/design/data/elevation/tailwind-default-utility-scale.md +19 -0
  120. package/data/harnesses/code/skills/design/data/elevation/vercel-geist-shadow-as-border.md +20 -0
  121. package/data/harnesses/code/skills/design/data/iconography.md +199 -0
  122. package/data/harnesses/code/skills/design/data/motion/accordion-expand.md +18 -0
  123. package/data/harnesses/code/skills/design/data/motion/destructive-hold-confirm.md +18 -0
  124. package/data/harnesses/code/skills/design/data/motion/drag-dismiss-momentum.md +18 -0
  125. package/data/harnesses/code/skills/design/data/motion/empty-state-arrive.md +18 -0
  126. package/data/harnesses/code/skills/design/data/motion/hover-lift.md +18 -0
  127. package/data/harnesses/code/skills/design/data/motion/modal-center-arrive.md +18 -0
  128. package/data/harnesses/code/skills/design/data/motion/number-ticker-roll.md +18 -0
  129. package/data/harnesses/code/skills/design/data/motion/onboarding-bounce.md +18 -0
  130. package/data/harnesses/code/skills/design/data/motion/panel-slide.md +18 -0
  131. package/data/harnesses/code/skills/design/data/motion/press-feedback.md +18 -0
  132. package/data/harnesses/code/skills/design/data/motion/progress-linear-loop.md +18 -0
  133. package/data/harnesses/code/skills/design/data/motion/route-crossfade.md +18 -0
  134. package/data/harnesses/code/skills/design/data/motion/rubber-band-overscroll.md +18 -0
  135. package/data/harnesses/code/skills/design/data/motion/skeleton-shimmer.md +18 -0
  136. package/data/harnesses/code/skills/design/data/motion/stagger-arrive.md +18 -0
  137. package/data/harnesses/code/skills/design/data/motion/toast-enter-stack.md +18 -0
  138. package/data/harnesses/code/skills/design/data/motion/tooltip-chain-instant.md +18 -0
  139. package/data/harnesses/code/skills/design/data/motion/trigger-anchored-reveal.md +18 -0
  140. package/data/harnesses/code/skills/design/data/tells.csv +34 -0
  141. package/data/harnesses/code/skills/design/data/voices/bright-collaborator.md +29 -0
  142. package/data/harnesses/code/skills/design/data/voices/direct-operator.md +29 -0
  143. package/data/harnesses/code/skills/design/data/voices/earnest-helper.md +29 -0
  144. package/data/harnesses/code/skills/design/data/voices/editorial-composed.md +29 -0
  145. package/data/harnesses/code/skills/design/data/voices/quiet-concierge.md +29 -0
  146. package/data/harnesses/code/skills/design/data/voices/warm-guide.md +29 -0
  147. package/data/harnesses/code/skills/design/references/compose.md +3 -7
  148. package/data/harnesses/code/skills/design/references/content.md +4 -4
  149. package/data/harnesses/code/skills/design/references/existing-apps.md +1 -1
  150. package/data/harnesses/code/skills/design/references/foundations.md +57 -0
  151. package/data/harnesses/code/skills/design/references/intake.md +11 -11
  152. package/data/harnesses/code/skills/design/references/object-pass.md +1 -1
  153. package/data/harnesses/code/skills/design/references/ship-gate.md +1 -1
  154. package/data/harnesses/code/skills/design/scripts/select-chart.mjs +14 -8
  155. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +1 -1
  156. package/package.json +2 -2
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: direct-operator
3
+ class: c2
4
+ sourced: 2026-07-12
5
+ source: "Distilled from Atlassian's 'bold, optimistic, practical' brevity mandate (atlassian.design/content/voice-and-tone-principles) and Material Design's clarity-to-anyone standard (m3.material.io/foundations/content-design)."
6
+ license: open
7
+ ---
8
+ # Voice: direct-operator
9
+
10
+ **Feel:** Brisk and task-first — reads like a command line, not a conversation.
11
+
12
+ Imperative mood by default; sentence fragments are acceptable where a full sentence adds nothing ("Upload failed. Retry."). No adjectives unless load-bearing. Numerals are always digits, units abbreviated once established. No exclamation points, no rhetorical questions, no throat-clearing openers ("Please note that…"). Density over politeness — every word has to justify its presence.
13
+
14
+ ## Tone map
15
+
16
+ Voice is constant; tone dials by situation.
17
+
18
+ - **routine action:** imperative, fragments allowed
19
+ - **error:** states failure plus count or reason, no softening
20
+ - **success:** single clipped phrase, no embellishment
21
+ - **destructive confirmation:** same flat register as everything else — no added urgency language, the plainness is the safeguard
22
+
23
+ ## Examples
24
+
25
+ - **button:** "Create workspace"
26
+ - **empty state (heading + motivation):** "No records" / "Import a file or add one manually to begin."
27
+ - **error:** "Save failed. 3 fields are invalid."
28
+ - **tooltip:** "Locks the row for editing by others."
29
+ - **confirmation:** "Workspace created."
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: earnest-helper
3
+ class: c2
4
+ sourced: 2026-07-12
5
+ source: "Distilled from Intercom's PREACH framework (intercom.com/blog/preach-framework-for-customer-support-tone) — Proud, Responsible, Empathetic, Articulate, Concise, Human."
6
+ license: open
7
+ ---
8
+ # Voice: earnest-helper
9
+
10
+ **Feel:** Owns the failure, states the fix, never grovels.
11
+
12
+ First-person-plural ownership when the product is at fault ("we couldn't…"), second person when guiding the user's next step. Sentences are short and declarative; empathy is shown through precision and a clear next step rather than apology words ("sorry," "oops" are avoided). No exclamation points, even on success — confidence doesn't need punctuation. Numbers are digits throughout.
13
+
14
+ ## Tone map
15
+
16
+ Voice is constant; tone dials by situation.
17
+
18
+ - **routine action:** second person, concise, no flourish
19
+ - **error:** first-person-plural ownership ("we couldn't…"), immediate next step
20
+ - **success:** short, no exclamation, confidence without decoration
21
+ - **destructive confirmation:** states irreversibility explicitly, still no apology language
22
+
23
+ ## Examples
24
+
25
+ - **button:** "Submit request"
26
+ - **empty state (heading + motivation):** "No requests yet" / "Submit one and track its progress here."
27
+ - **error:** "We couldn't submit that request. Reconnect and try again."
28
+ - **tooltip:** "Requests are visible to your whole team once submitted."
29
+ - **confirmation:** "Request submitted."
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: editorial-composed
3
+ class: c2
4
+ sourced: 2026-07-12
5
+ source: "Distilled from Material Design's AP-style clarity standard (m3.material.io/foundations/content-design/style-guide/ux-writing-best-practices) and Atlassian's 'practical, with a wink' brand register (atlassian.design/content/writing-style), slowed to an editorial cadence."
6
+ license: open
7
+ ---
8
+ # Voice: editorial-composed
9
+
10
+ **Feel:** Measured and literate — composed sentences, unhurried but exact.
11
+
12
+ Longer, fully-formed sentences that favor a subordinate clause over a fragment; still one idea per sentence, but the idea is given room. Verbs remain the engine of the sentence rather than being buried under nominalizations. Numbers under ten are spelled out even in most UI text; digits are reserved for data-dense contexts (tables, counters, timestamps). Restraint reads as taste, not coldness — warmth comes from word choice, never from exclamation.
13
+
14
+ ## Tone map
15
+
16
+ Voice is constant; tone dials by situation.
17
+
18
+ - **routine action:** a fuller sentence, still verb-led
19
+ - **error:** composed, no blame, the fix named in a complete sentence
20
+ - **success:** a complete, satisfying sentence rather than a clipped label
21
+ - **destructive confirmation:** the most fully-formed of the four — consequence and reversibility spelled out in full
22
+
23
+ ## Examples
24
+
25
+ - **button:** "Add collection"
26
+ - **empty state (heading + motivation):** "Nothing archived yet" / "Items you archive will be kept here, in order, for as long as you need them."
27
+ - **error:** "The collection couldn't be saved. Review the highlighted fields and try again."
28
+ - **tooltip:** "Determines the order collections appear in for every viewer."
29
+ - **confirmation:** "Collection added and ready to share."
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: quiet-concierge
3
+ class: c2
4
+ sourced: 2026-07-12
5
+ source: "Distilled from Shopify Polaris content fundamentals (polaris-react.shopify.com — verb-first directness, plain language, 'remove until it breaks') and Atlassian voice & tone (atlassian.design — say it once, then get out of the way)."
6
+ license: open
7
+ ---
8
+ # Voice: quiet-concierge
9
+
10
+ **Feel:** Understated and precise — says the necessary thing once, then steps back.
11
+
12
+ Short-to-medium declarative sentences, verb-first for any instruction ("Add," "Move," "Archive"). Warmth comes from precision, not adjectives — no exclamation points, no stacked modifiers, no filler words ("just," "simply," "easily"). Numbers render as digits even under ten, to keep the eye moving. Contractions are allowed ("it's," "can't") to keep the register human. If a sentence can be cut without losing meaning, cut it.
13
+
14
+ ## Tone map
15
+
16
+ Voice is constant; tone dials by situation.
17
+
18
+ - **routine action:** plain, verb-first, no ornament
19
+ - **error:** flat statement of what happened, then the fix — no apology
20
+ - **success:** states the fact and stops there
21
+ - **destructive confirmation:** names exactly what's lost, in the same even register — precision is the only warning
22
+
23
+ ## Examples
24
+
25
+ - **button:** "Add customer"
26
+ - **empty state (heading + motivation):** "No reports yet" / "Reports appear here once your first one is generated."
27
+ - **error:** "The file didn't upload. Check your connection and try again."
28
+ - **tooltip:** "Archives the record without deleting its history."
29
+ - **confirmation:** "Customer added."
@@ -0,0 +1,29 @@
1
+ ---
2
+ id: warm-guide
3
+ class: c2
4
+ sourced: 2026-07-12
5
+ source: "Distilled from the Mailchimp Content Style Guide (styleguide.mailchimp.com) — voice & tone, writing principles, web elements, and grammar & mechanics pages: plainspoken warmth, dry humor, active voice, treats users as capable partners. Mailchimp's style guide content is published under a Creative Commons Attribution-NonCommercial 4.0 International License (CC BY-NC 4.0); reworded and distilled throughout, no verbatim reuse."
6
+ license: licensed
7
+ ---
8
+ # Voice: warm-guide
9
+
10
+ **Feel:** Plainspoken and warm — talks to you like a colleague who respects your time.
11
+
12
+ Medium sentences in active voice, contractions throughout. One dry aside is permitted per surface, never forced. Numbers under ten are spelled out in body copy, digits in dense UI (tables, counters). Confidence over cheerleading — no "Great job!"; encouragement is implied by clarity, not stated outright. The register never talks down to the reader.
13
+
14
+ ## Tone map
15
+
16
+ Voice is constant; tone dials by situation.
17
+
18
+ - **routine action:** relaxed, active voice, one idea per sentence
19
+ - **error:** takes ownership ("we couldn't…"), calm next step, no exclamation
20
+ - **success:** quietly confident, still no exclamation
21
+ - **destructive confirmation:** slows down a beat, spells out what's being removed and that it can't be undone
22
+
23
+ ## Examples
24
+
25
+ - **button:** "Send invoice"
26
+ - **empty state (heading + motivation):** "Nothing here yet" / "Once you add a project, it'll show up in this list."
27
+ - **error:** "We couldn't send that invoice. Check the email address and try again."
28
+ - **tooltip:** "Sends a copy to your own inbox too."
29
+ - **confirmation:** "Invoice sent."
@@ -6,20 +6,16 @@ Build the app — all surfaces in one continuous context, the chosen package's d
6
6
 
7
7
  Per the primitives switch recorded in the project's `design.md`:
8
8
 
9
- - **`nurix`** — compose chrome from `@nurix/components`. The chrome recipes (`get_entry`, kind `chrome` — fetch only the recipes for surfaces in the structure doc) carry composition, states, and when-to-use; the component reference folder (`components/`) carries props, imports, and usage — consult the index for what exists, and open the touched category's API reference on need.
9
+ - **`nurix`** — compose chrome from `@nurix/components`. The chrome recipes (`data/chrome/` — read only the recipes for surfaces in the structure doc) carry composition, states, and when-to-use; the component dictionary (`components/`) carries props, imports, and usage across both provenances — consult the index for what exists, and open the touched category's API reference on need.
10
10
  - **`native`** — the recipes are *specifications*: anatomy, the eight states, keyboard behavior, token reach — implement them with the incumbent stack's own components. The index's shadcn/fallback columns carry the composition; category API references never load.
11
11
 
12
12
  Recipes are starting points, not jails: restyle or extend them in place when the package demands it.
13
13
 
14
- ## The consult, at your discretion
15
-
16
- The composition consult is available here — a whole-app paragraph in, candidate shapes + a component list + rulings out. It is advisory, never binding: you compose. The judgment rule for *when* lives in the router (SKILL.md § The coupled server); the short form: consult on a real knowledge gap or a rework signal, stay local when the canvas is the answer, and `record` every consult and every deviation from its advice. Unavailable is normal — compose locally, record it, continue.
17
-
18
14
  ## Composition rules
19
15
 
20
- - **Every surface starts from a chosen layout blueprint** — `get_entry` the chosen archetype's blueprint (kind `blueprint`); pick the shape reading the brief, record it in one line. Structural variety, not visual variety, is what reads as designed.
16
+ - **Every surface starts from a chosen layout blueprint** (`data/blueprints/<archetype>.md`) — pick the shape reading the brief, record it in one line. Structural variety, not visual variety, is what reads as designed.
21
17
  - **Values come from the token artifact** — components consume the emitted custom properties and never invent raw values ([emission.md](emission.md) has the pipe rules). Switching packages must re-skin the whole app.
22
- - **Positive obligations apply** — `get_entry` the surface's archetype checklist (kind `checklist`); the checklists are ceilings: a sidebar ships with brand block, icons, and user context; a dashboard tile ships with number + comparison + trend + state + door; every surface ships its state matrix.
18
+ - **Positive obligations apply** — load the surface's archetype checklist (`data/checklists/<archetype>.md`); the checklists are ceilings: a sidebar ships with brand block, icons, and user context; a dashboard tile ships with number + comparison + trend + state + door; every surface ships its state matrix.
23
19
  - **The register scope holds**: the display face never touches cells, buttons, labels, or form chrome; data numerals run the mono face with `tabular-nums`.
24
20
  - **Motion follows the package's §7** and the frequency law: actions performed 100+ times a day, and any keyboard-initiated action, get no animation, ever; panel/drawer motion is interruptible; entrances never `ease-in`.
25
21
  - **No ownership jails.** Any file may be edited at any time, including generated ones and library compositions.
@@ -4,7 +4,7 @@ Author the demo data **before composing surfaces**. Data credibility is the sing
4
4
 
5
5
  ## From the corpus
6
6
 
7
- Fetch the chosen domain's corpus — `search_catalog` (kind `corpus`) to find it, `get_entry` to load it: the body (vocabulary, number-shape recipes, the invariants block) arrives with its `people` and `companies` rosters in one payload.
7
+ Fetch the chosen domain's corpus — `search_catalog` (family `corpus`) to find it, `get_entry` to load it: the body (vocabulary, number-shape recipes, the invariants block) arrives with its `people` and `companies` rosters in one payload.
8
8
 
9
9
  - Names come from the corpus roster; emails derive from names; roles are domain-correct.
10
10
  - Activity strings use the corpus vocabulary — a CRM logs "Intro call with Elena — pricing discussion", never webhook noise.
@@ -14,13 +14,13 @@ Fetch the chosen domain's corpus — `search_catalog` (kind `corpus`) to find it
14
14
 
15
15
  ## Voice
16
16
 
17
- Fetch the package-bound voice pack — `get_entry` the voice the package's §9 names. All authored strings — buttons, empty states, errors, tooltips, confirmations — speak in that voice, with tone varying by situation per the pack's tone map.
17
+ Load the package-bound voice pack (`data/voices/<id>.md` — the package's §9 names it). All authored strings — buttons, empty states, errors, tooltips, confirmations — speak in that voice, with tone varying by situation per the pack's tone map.
18
18
 
19
19
  ## Chart choice
20
20
 
21
- Every data-bearing surface consults the chart-selection engine — **one graph question per consult**. The census rows the engine evaluates are fetched **once per session** via `get_entry("chart-census")`:
21
+ Every data-bearing surface consults the chart-selection engine — **one graph question per consult**. The census ships beside the engine; nothing is fetched:
22
22
 
23
- 1. Author the data signature (the judgment half): the question, measures, dimensions, semantic flags (temporal, parts-form-whole, target-exists, …), constraints — plus the session's `census` rows. Decompose multi-question asks first.
23
+ 1. Author the data signature (the judgment half): the question, measures, dimensions, semantic flags (temporal, parts-form-whole, target-exists, …), constraints. Decompose multi-question asks first.
24
24
  2. Run `node scripts/select-chart.mjs <signature.json>` and read the typed output: admissible set, eliminations with reason codes, ranking, recommendation, or a refusal code.
25
25
  3. **Honor refusals** — a refusal means the question isn't chartable as posed (often: it's a table). Never invent a measure to force a chart.
26
26
  4. `record` the pick in one line. Taking a non-recommended admissible option needs a reason on that line; taking an eliminated option is out of contract.
@@ -4,7 +4,7 @@ The same machinery runs on existing UIs, under a preservation contract.
4
4
 
5
5
  ## Judge — a user-invoked service
6
6
 
7
- A critique of an existing UI against the brief, the project's `design.md`, the archetype checklists, and the project's taste profile (`get_project`), producing a **severity-ranked (never scored) report**. Judge is a service the user asks for — never a self-check the skill runs on its own output. Read the actual rendered state (screenshots the user provides, or captures the user asks for); refuse to critique from source alone when the ask is "does it look right", and never imagine what unrendered code looks like. Each finding: severity, the on-screen element, what's wrong, the exact fix.
7
+ A critique of an existing UI against the brief, the project's `design.md`, the archetype checklists, and the workspace's taste profile (`get_preferences`), producing a **severity-ranked (never scored) report**. Judge is a service the user asks for — never a self-check the skill runs on its own output. Read the actual rendered state (screenshots the user provides, or captures the user asks for); refuse to critique from source alone when the ask is "does it look right", and never imagine what unrendered code looks like. Each finding: severity, the on-screen element, what's wrong, the exact fix.
8
8
 
9
9
  ## Improve — judge + the fix pass
10
10
 
@@ -0,0 +1,57 @@
1
+ # Foundations — the brief fixed doctrine
2
+
3
+ Cross-cutting decisions every build makes once, stated at the length they deserve and no longer (the obviousness rule: what competent intelligence already knows gets nothing). Load the touched entry at the step that decides it, never the file whole.
4
+
5
+ ## The five status palettes
6
+
7
+ Pick **one** per project at intake and hold it everywhere — status colors are semantics, not decoration, and deltas color by *meaning* (down is green when down is good):
8
+
9
+ | Palette | success | warning | danger | info | neutral | Feel |
10
+ | --- | --- | --- | --- | --- | --- | --- |
11
+ | `signal` | `oklch(0.64 0.15 150)` | `oklch(0.75 0.15 80)` | `oklch(0.58 0.20 25)` | `oklch(0.60 0.14 250)` | `oklch(0.65 0.02 260)` | the default — clear, saturated, unmistakable |
12
+ | `muted-pro` | `oklch(0.60 0.09 155)` | `oklch(0.68 0.10 75)` | `oklch(0.55 0.13 25)` | `oklch(0.58 0.08 250)` | `oklch(0.62 0.015 260)` | desaturated for dense dashboards — readable without shouting |
13
+ | `warm-ledger` | `oklch(0.62 0.11 140)` | `oklch(0.70 0.13 60)` | `oklch(0.56 0.17 30)` | `oklch(0.60 0.10 230)` | `oklch(0.64 0.02 80)` | warm-neutral products (finance, ops review) |
14
+ | `cool-console` | `oklch(0.66 0.12 165)` | `oklch(0.74 0.12 85)` | `oklch(0.60 0.18 15)` | `oklch(0.62 0.12 265)` | `oklch(0.66 0.02 250)` | cool/dark consoles — holds up on deep backgrounds |
15
+ | `high-contrast` | `oklch(0.55 0.17 150)` | `oklch(0.60 0.16 70)` | `oklch(0.50 0.21 27)` | `oklch(0.50 0.16 255)` | `oklch(0.50 0.02 260)` | accessibility-first; every value ≥4.5:1 on white |
16
+
17
+ Each value is the light-theme anchor; derive the dark-theme sibling by raising lightness ~0.08 and trimming chroma ~0.02. Severity ladders (P0–P3 and kin) map onto danger → warning → info → neutral, never onto new hues.
18
+
19
+ ## Data-viz palettes
20
+
21
+ No database — three constraints, values yours: **categorical** series need distinguishable hues that survive colorblind simulation (rotate hue ≥40° apart, vary lightness too, ≤8 series then facet); **sequential** ramps run light→dark in one hue for magnitude; **diverging** ramps put two hues around a *meaningful* zero, neutral at the middle. Validate every ramp in both themes; charts consume package tokens, never raw hex.
22
+
23
+ ## Number, date, unit formatting
24
+
25
+ Tabular figures in tables and KPIs; thousands separators; unit or currency attached to the number; consistent decimals per column; large values truncate meaningfully (`1.2M`, never `1,200,000` in a tile); timestamps show relative when recent and absolute on hover; timezones explicit anywhere ambiguity costs money.
26
+
27
+ ## Spacing & density
28
+
29
+ The 2/4/6/8 scale, period. Operator surfaces default **compact** (data rows 32–36px) with a comfortable mode only when `product.md` says reading, not scanning. Density is a per-project decision made once, not a per-surface mood.
30
+
31
+ ## Radius & stroke
32
+
33
+ Radius is identity — sharp (0–2px), soft (4–6px), or round (10px+) — chosen by the package and applied consistently; mixing radii on one surface reads as templated. One border weight per surface; elevation *or* borders separate layers, never both at full strength.
34
+
35
+ ## Loading, skeleton, progress
36
+
37
+ Skeletons for layout-known loads, spinners only for unknowable ones, optimistic updates for high-frequency mutations with undo. Skeletons mirror the real layout's bones (no generic gray blocks). Nothing pulses faster than 1.2s.
38
+
39
+ ## Empty states
40
+
41
+ The three empties (first-use, no-results, cleared-filter) each say what happened and what to do next, in the project voice. Art direction follows the package's restraint: an icon or nothing for dense tools; illustration only where the package's feel says warm. Never a bare "No data".
42
+
43
+ ## Keyboard
44
+
45
+ The operator vocabulary: `⌘K` command palette, `j/k` traversal where lists dominate, `esc` closes the topmost layer only, `enter` commits, focus visible always. Declare shortcuts in a discoverable surface (palette footer or `?` overlay).
46
+
47
+ ## Dark mode physics
48
+
49
+ Elevation becomes lightness (surfaces lighten as they rise — shadows barely read); desaturate fills ~15%; never pure black (`oklch(0.13–0.18 …)` floors); borders drop to low-alpha white; charts re-derive from dark-theme tokens, never inherit light values.
50
+
51
+ ## Code, log, terminal surfaces
52
+
53
+ Mono face with `tabular-nums`; a shiki theme paired to the package (dark identity → dark code surface even in light theme is legitimate); log levels use the status palette; wrap off by default with horizontal scroll.
54
+
55
+ ## Polish
56
+
57
+ Focus rings on-brand (2px, offset, the accent — never browser default blue on a styled app); selection color derived from the accent at low alpha; scrollbars styled thin on dense panes; cursor changes only where affordance is real.
@@ -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 project first.** If the repo carries a `projectId`, open with `get_project`: the personality, the taste profile, and the recent decision lines are the session's context — then run the drift check (compare the repo's `design.md` against the server canonical; on mismatch, tell the user which is newer and ask). A returning project re-enters the steps with its identity already chosen; the rules below are for first intake.
5
+ **Returning workspace first.** If the repo carries a `workspaceId` (or the Apollo 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 `design.md` 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` (kind `package`) 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.
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
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` — 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
- - **Register the project.** First intake ends with `register_project` — name, the consumer's container if it has one, and `fork: { slug, version }` pinning the chosen package as it was chosen (a copy, never a live read: later catalog edits cannot change a running project's identity). Commit the returned `projectId` to the repo. Escape-hatch one-offs register without a fork; the authored design.md is pushed via `record`.
14
- - **Axis overrides fetch the same way** — a recorded override names its axis entry; `get_entry` (kind `axis`) fetches exactly that entry.
15
- - **Set the primitives switch** — write one `primitives: nurix | native` line into the project's `design.md`. 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>@<version>` (or `authored` for escape-hatch one-offs).
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.
17
- - **The taste profile biases every choice** — `get_project` returns it (per-dimension feel/avoid lines); user reactions to shipped output update it via `record`. No profile yet = no bias, never a block.
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.
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
+ - **Set the primitives switch** — write one `primitives: nurix | native` line into the project's `design.md`. 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
+ - **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.
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
 
@@ -30,11 +30,11 @@ Step 1 ends with a preview block:
30
30
  - surface map with archetypes
31
31
  - planned deviations
32
32
 
33
- 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 project memory — `record` it as decision lines heading this run's choices.
33
+ 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.
34
34
 
35
35
  ## Outputs
36
36
 
37
- - `design.md` (project fork: chosen package + switch line + provenance + brief bindings; deviations accrue as they are recorded)
38
- - `product.md` written/updated
39
- - the project registered (or resumed) — `projectId` in the repo, the identity pin and the preview block recorded
37
+ - `design.md` (project fork: chosen package + switch line + provenance + brief bindings; deviations accrue as they are recorded) — pushed as the workspace preference row
38
+ - `product.md` written/updated and pushed
39
+ - the identity pin and the preview block recorded
40
40
  - the chosen package's full design.md held in context
@@ -15,7 +15,7 @@ Derive the object model and surface map using the UX-pattern decision layer (`re
15
15
  11. `state-matrix` — loading, the three empties (first-use, no-results, cleared), degraded, stale — per surface
16
16
  12. `standard-pages` / `ai-layer` / `dashboards` / `settings` — when the brief has them
17
17
 
18
- Each pass file carries its rule as prose; the current machine-readable decision table is the pass's catalog entry — `get_entry` the pass's ux-pass id when the step-2 decision needs it (curation edits the tables between skill releases; the served table is the authority) — and **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.
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.
19
19
 
20
20
  When a pass fires a clarification code (an input the table needs that the brief doesn't give), resolve it: infer-and-mark when the answer doesn't change the design, ask when it does.
21
21
 
@@ -22,7 +22,7 @@ A Tier-1 failure blocks the ship; fix and re-run. Binary phrasing is the contrac
22
22
 
23
23
  ## Tier 2 — flags, never gates
24
24
 
25
- Sweep the operator tell list — fetched via `get_entry("tells")`, at this step only — plus the motion tells (`transition: all`; `ease-in` on an entrance; animation attached to a keyboard-triggered action). Flags cannot fail the build and trigger no in-run judging: each is **fixed or dismissed with one recorded line** through `record`, and every flag appears in the ship report for the human's eyes — numbers point eyes; they do not replace them. The validator may run this sweep warn-only after compose-step edits; nothing new ever fails the build mid-composition.
25
+ Sweep `data/tells.csv` (the operator tell list), at this step only, plus the motion tells (`transition: all`; `ease-in` on an entrance; animation attached to a keyboard-triggered action). Flags cannot fail the build and trigger no in-run judging: each is **fixed or dismissed with one recorded line** through `record`, and every flag appears in the ship report for the human's eyes — numbers point eyes; they do not replace them. The validator may run this sweep warn-only after compose-step edits; nothing new ever fails the build mid-composition.
26
26
 
27
27
  ## The ship report
28
28
 
@@ -2,10 +2,11 @@
2
2
  //
3
3
  // One graph question per call. The model authors the data-signature JSON (the judgment
4
4
  // half); this script computes elimination, scoring, ranking, and refusal (the mechanical
5
- // half) over the chart-leaf census rows the caller supplies — fetched once per session
6
- // via the design-mcp entry "chart-census" and passed in the signature's `census` array
7
- // (engines local, knowledge served). Deterministic: same signature + census in, same
8
- // output out. No network, stdlib only.
5
+ // half) over the chart-leaf census at ../data/charts/census.csv — the census and this
6
+ // engine are one designed artifact and ship together (dimension-placement chapter 12).
7
+ // Callers may pass explicit census rows (module arg or the signature's `census` array);
8
+ // the local CSV is the default. Deterministic: same signature + census in, same output
9
+ // out. No network, stdlib only.
9
10
  //
10
11
  // OUTPUT CONTRACT (docs/features/design-skill/07-evaluation-integrity.md §B1 — exact):
11
12
  // {
@@ -279,11 +280,16 @@ export function parseCensusCsv(text) {
279
280
  });
280
281
  }
281
282
 
282
- // Accepts census rows as served by design-mcp's "chart-census" entry (slug/ord, flags as
283
- // pipe-joined strings) or already in the engine's leaf shape, and normalizes onto it.
283
+ export function loadDefaultCensus() {
284
+ const censusPath = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'data', 'charts', 'census.csv');
285
+ return parseCensusCsv(fs.readFileSync(censusPath, 'utf8'));
286
+ }
287
+
288
+ // Accepts census rows in the engine's leaf shape (or a row shape with snake_case columns
289
+ // and pipe-joined flag strings) and normalizes onto the leaf shape.
284
290
  export function normalizeCensusRows(rows) {
285
291
  if (!Array.isArray(rows) || rows.length === 0) {
286
- throw new Error('census rows are required — fetch them once per session via the design-mcp entry "chart-census" and pass them in the signature\'s `census` array');
292
+ throw new Error('census rows are required — the shipped census at data/charts/census.csv is the default');
287
293
  }
288
294
  const toFlagList = (value) =>
289
295
  Array.isArray(value) ? value : value == null || value === '' ? [] : String(value).split('|').map((f) => f.trim());
@@ -547,7 +553,7 @@ export function selectChart(input, censusRows) {
547
553
  if (input == null || typeof input !== 'object' || Array.isArray(input)) {
548
554
  throw new Error('selectChart: input must be a data-signature object');
549
555
  }
550
- const census = normalizeCensusRows(censusRows ?? input.census);
556
+ const census = normalizeCensusRows(censusRows ?? input.census ?? loadDefaultCensus());
551
557
  const { flags, structure } = deriveFlags(input);
552
558
 
553
559
  const refusal = deriveRefusal(input, structure);
@@ -188,7 +188,7 @@ class YamlError extends Error {}
188
188
 
189
189
  const isObj = (v) => v !== null && typeof v === "object" && !Array.isArray(v);
190
190
 
191
- function parseYaml(src, label) {
191
+ export function parseYaml(src, label) {
192
192
  const rawLines = src.split(/\r?\n/);
193
193
  const lines = [];
194
194
  for (let i = 0; i < rawLines.length; i++) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.19.51",
3
+ "version": "0.19.53",
4
4
  "description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,5 +42,5 @@
42
42
  "agent",
43
43
  "plugin"
44
44
  ],
45
- "etnaFingerprint": "add8db2442a5"
45
+ "etnaFingerprint": "b90b7910764f"
46
46
  }