@nurix/etna 0.20.37 → 0.20.39

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 (60) hide show
  1. package/data/catalog/rules/frontend.md +5 -5
  2. package/data/catalog/rules/pnpm.md +2 -2
  3. package/data/harness-index.json +1 -1
  4. package/data/harnesses/code/agents/brainstorm.md +5 -3
  5. package/data/harnesses/code/codex/agents/brainstorm.toml +5 -3
  6. package/data/harnesses/code/harness.json +2 -2
  7. package/data/harnesses/code/hooks/approved-packages.md +1 -2
  8. package/data/harnesses/code/rules/frontend.md +5 -5
  9. package/data/harnesses/code/rules/pnpm.md +2 -2
  10. package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
  11. package/data/harnesses/code/skills/brainstorm/README.md +18 -45
  12. package/data/harnesses/code/skills/brainstorm/SKILL.md +105 -173
  13. package/data/harnesses/code/skills/brainstorm/references/doctrine.md +70 -141
  14. package/data/harnesses/code/skills/brainstorm/references/entry.md +70 -0
  15. package/data/harnesses/code/skills/brainstorm/references/harvest.md +85 -137
  16. package/data/harnesses/code/skills/brainstorm/references/session-schema.md +98 -135
  17. package/data/harnesses/code/skills/design/components/charts.md +121 -43
  18. package/data/harnesses/code/skills/design/components/collections.md +209 -41
  19. package/data/harnesses/code/skills/design/components/feedback.md +86 -25
  20. package/data/harnesses/code/skills/design/components/hooks.md +198 -12
  21. package/data/harnesses/code/skills/design/components/index.md +93 -71
  22. package/data/harnesses/code/skills/design/components/inputs.md +249 -157
  23. package/data/harnesses/code/skills/design/components/layout.md +98 -38
  24. package/data/harnesses/code/skills/design/components/media.md +46 -25
  25. package/data/harnesses/code/skills/design/components/motion.md +56 -46
  26. package/data/harnesses/code/skills/design/components/navigation.md +54 -15
  27. package/data/harnesses/code/skills/design/components/overlays.md +51 -41
  28. package/data/harnesses/code/skills/design/components/setup.md +84 -5
  29. package/data/harnesses/code/skills/design/components/typography.md +72 -22
  30. package/data/harnesses/code/skills/design/components/utils.md +47 -13
  31. package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
  32. package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
  33. package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
  34. package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
  35. package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
  36. package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
  37. package/data/harnesses/code/skills/design/references/emission.md +6 -6
  38. package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
  39. package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
  40. package/data/harnesses/delivery/agents/brainstorm.md +5 -3
  41. package/data/harnesses/delivery/codex/agents/brainstorm.toml +5 -3
  42. package/data/harnesses/delivery/harness.json +2 -2
  43. package/data/harnesses/delivery/skills/brainstorm/README.md +18 -45
  44. package/data/harnesses/delivery/skills/brainstorm/SKILL.md +105 -173
  45. package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +70 -141
  46. package/data/harnesses/delivery/skills/brainstorm/references/entry.md +70 -0
  47. package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +85 -137
  48. package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +98 -135
  49. package/data/harnesses/etna/agents/brainstorm.md +5 -3
  50. package/data/harnesses/etna/codex/agents/brainstorm.toml +5 -3
  51. package/data/harnesses/etna/harness.json +2 -2
  52. package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
  53. package/data/harnesses/etna/skills/brainstorm/README.md +18 -45
  54. package/data/harnesses/etna/skills/brainstorm/SKILL.md +105 -173
  55. package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +70 -141
  56. package/data/harnesses/etna/skills/brainstorm/references/entry.md +70 -0
  57. package/data/harnesses/etna/skills/brainstorm/references/harvest.md +85 -137
  58. package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +98 -135
  59. package/data/harnesses/hr/harness.json +1 -1
  60. package/package.json +2 -2
@@ -14,18 +14,18 @@ Tailwind v4 + shadcn-based UI conventions for **web** apps — styling, the `@nu
14
14
 
15
15
  - **Build every UI through the `design` skill** — never hand-roll layouts; the page archetypes, the `design.md` identity system with its token artifact (`design.tokens.css`), and chrome wiring live in the skill.
16
16
  - **The brief's stated theme binds** — dark boots dark when the brief says so (recorded in the project's `design.md`); light is the default only when the brief is silent.
17
- - **`@nurix/components`** is the UI library — import by subpath (`@nurix/components/button`). **Never** `npx shadcn add`, no `components.json` scaffold — consume the prebuilt library (`.tsx`, not `.jsx`). *A recorded deviation from canonical shadcn, where primitives are vendored into `components/ui/` and edited in place: this workspace consumes a published library instead, and vendoring would fork it. Deliberate — the design skill does not "converge" it.*
17
+ - **`@nurix/components`** is the UI library — import by layer-prefixed subpath (`@nurix/components/element/button`). **Never** `npx shadcn add`, no `components.json` scaffold — consume the prebuilt library (`.tsx`, not `.jsx`). *A recorded deviation from canonical shadcn, where primitives are vendored into `components/ui/` and edited in place: this workspace consumes a published library instead, and vendoring would fork it. Deliberate — the design skill does not "converge" it.*
18
18
  - Vite: `@tailwindcss/vite` + `@vitejs/plugin-react-swc`. Pin `react` / `react-dom` / `react/jsx-runtime` / `react/jsx-dev-runtime` to the app's single copy via `resolve.alias` — `@nurix/*` ship nested react, and two copies means two hook dispatchers.
19
19
  - Tailwind v4 is CSS-only — no `tailwind.config.js`, no PostCSS.
20
20
  - **The CSS entry is whatever the manifest names**, not a fixed filename — `globals.css`, `index.css` and `styles.css` are each conventional in different framework guides, so resolve it rather than grep for one. Imports in order: `@import "./fonts.css"` (`@fontsource` registrations) → the project's `design.tokens.css` (derived by the design skill's validator from the `design.md` in the design folder — `packages/common/` at the base of a multi-package workspace, `src/common/` in a single-package repo — **never** hand-edited) → `@import "tailwindcss"` → the library's `styles.css` → the project's `personality.css` (the same validator's `--emit-personality`, compiling the `design.md` traits through `@nurix/components`' own compiler — **never** hand-edited) — then `@theme inline {…}` mapping vars to tokens.
21
21
  - **Dark mode is the `.dark` class on the root element**, bound as `@custom-variant dark (&:is(.dark *))` in the CSS entry — **never** a `data-theme` attribute. `@nurix/components` keys its `dark:` variants, its theme toggle, and its toaster on that class and a consumer cannot re-key them, so an app on the attribute renders mixed: its own tokens invert, the library's dark-only chrome stays light. The switcher is three parts — a pre-paint inline script in the HTML shell (a mounted provider runs too late and the page flashes), `color-scheme: light dark`, and the persisted-preference module.
22
- - Tokens: raw values in `:root:not(.dark)` and `:root.dark` — **both specificity (0,2,0), and that armor is load-bearing.** Tailwind compiles `@theme` into `@layer theme` and any unlayered declaration beats a layered one, so the library's unlayered `:root`/`.dark` defeats an app's `@theme` outright and *ties* a bare `:root`/`.dark`, leaving the winner to import order. Values are then consumed as semantic Tailwind tokens (`bg-card`, `text-foreground`) through an `@theme inline` mapping layer. The library bundles `class-variance-authority`, `clsx`, `tailwind-merge` — don't re-add them.
22
+ - Tokens: raw values in `:root:not(.dark)` and `:root.dark` — **both specificity (0,2,0), and that armor is load-bearing.** Tailwind compiles `@theme` into `@layer theme` and any unlayered declaration beats a layered one, so the library's unlayered `:root`/`.dark` defeats an app's `@theme` outright and *ties* a bare `:root`/`.dark`, leaving the winner to import order. Values are then consumed as semantic Tailwind tokens (`bg-card`, `text-foreground`) through an `@theme inline` mapping layer. The library ships `class-variance-authority` and `cn` (the class merger) as dependencies — don't re-add them.
23
23
  - **Never retune a Tailwind scale key `@nurix/components` consumes** — `--text-xs`, `--text-sm`, `--text-base`, `--text-lg`, `--text-xl`, `--text-2xl`. Its components carry raw scale utilities and its stylesheet declares no `font-size`, so those compile against *this app's* `@theme`: redefining `--text-sm` moves every button, menu item and table cell in the library at once, with nothing to report it. Change type by changing ramp tokens.
24
24
  - Spacing in 2/4/6/8; `object-cover`; `clip` / `clip-<n>` / `clip-fade` (the library's — they carry `min-width: 0` and `overflow-wrap: anywhere`; **never** `truncate` / `line-clamp-*`, which leave the flex-child overflow bug open); color through tokens — **never** hardcoded hex in components, and **never a literal font size**. The type ramp and the family rules are the design skill's [`references/type-system.md`](../skills/design/references/type-system.md); `text-sm` is a scale step and is fine, `text-[13px]` is a component overruling the system.
25
25
  - **Feel comes from the traits, never from literals on a control or collection surface.** `personality.css` compiles `density` / `pace` / `edge` / `depth` into `--density-*`, `--motion-duration-*`, `--radius-scale`, `--elevation-*`, and every library component reads those. App code stays inside the same reach: scanned surfaces pad and gap through the tokens (`p-(--density-pad-md)`, `gap-(--density-gap-md)`), a `transition-*` utility carries **no** `duration-*` class (the library's default transition duration retimes it from `pace`), a repeated-row container carries `data-mode="inline"`, and app animation reads `var(--motion-duration-base)`. A `p-3`, a `duration-200`, or a `rounded-lg` on such a surface silently opts out of the product's feel.
26
- - **Every rendered time is `<Timestamp>`** (`@nurix/components/element/timestamp`, `format="auto"`), and a live label ticks through `useNow` (`@nurix/components/lib/time`) — one shared interval, never a `setInterval` per row or a hand-rolled relative formatter.
27
- - **Status colour is the role.** `success`, `warning`, `info` are declared in `design.md` in both themes; the app's `@theme inline` maps its utilities onto the same roles (`--color-success: var(--success)`), and a status dot is `<Chip prefix="dot" color="var(--tone-success)">` — one hue per meaning on every surface.
28
- - **`cn()` keeps only one of a type role and a colour merged together** — its tailwind-merge tables class `text-h1` / `text-body` / `text-dense` as colours, so `cn("text-h1", "text-foreground")` and `cn("text-h1 text-foreground")` are both `text-foreground`. Keep a role and a colour in a `className` string that never goes through `cn`, or put the colour on the parent.
26
+ - **Every rendered time is `<Timestamp>`** (`@nurix/components/element/timestamp`, which picks relative or absolute per render), and a live label ticks through `useNow` (`@nurix/components/lib/time`) — one shared interval, never a `setInterval` per row or a hand-rolled relative formatter.
27
+ - **Status colour is the role.** `success`, `warning`, `info` are declared in `design.md` in both themes; the app's `@theme inline` maps its utilities onto the same roles (`--color-success: var(--success)`), and a status dot is `<Chip prefix="dot" intent="success">` (`intent` paints from the `--intent-*` tokens; `color` is for stored data colours, never status) — one hue per meaning on every surface.
28
+ - **`cn()` keeps only one of a type role and a colour merged together** — its merge tables class `text-h1` / `text-body` / `text-dense` as colours, so `cn("text-h1", "text-foreground")` and `cn("text-h1 text-foreground")` are both `text-foreground`. Keep a role and a colour in a `className` string that never goes through `cn`, or put the colour on the parent.
29
29
 
30
30
  ## Component Search Order
31
31
 
@@ -61,6 +61,6 @@ Every workspace package is scoped **`@nurix/`**; the dot vs. hyphen after the sc
61
61
  //registry.npmjs.org/:_authToken=${NPM_READ_TOKEN}
62
62
  ```
63
63
  The token needs only `Read` on the `nurix` scope. A `403` on install means auth failed — check `npm whoami` (local) or the `NPM_READ_TOKEN` secret (CI). Attempt the install directly — the token authenticates ambiently; don't pre-empt or second-guess it. If it fails, flag it to the user — **never** reach for alternatives, a substitute package, or `npm login` swaps.
64
- - **Import by subpath, never the barrel** — subpaths tree-shake reliably; the available subpaths are the package's `exports` keys. `import { Button } from "@nurix/components/button";`
65
- - **Styles** — import a CSS-shipping package's stylesheet **once** at the app entry: `import "@nurix/components/styles.css";`. Unstyled components are almost always a missing styles import. The shipped stylesheet is precompiled — no Tailwind `@source` directive unless consuming source via a workspace link.
64
+ - **Import by subpath, never the barrel** — subpaths tree-shake reliably; the available subpaths are the package's `exports` keys. `import { Button } from "@nurix/components/element/button";`
65
+ - **Styles** — `@import` a CSS-shipping package's stylesheet **once** in the app's CSS entry, after `@import "tailwindcss"`: `@import "@nurix/components/styles.css";` (the full import order is the `frontend` rule's). Unstyled components are almost always a missing styles import. The stylesheet is **not** precompiled — it omits `@import "tailwindcss"` and carries its own `@source` over the package's compiled JS, so the app's Tailwind build generates its utilities: add no `@source` for it, and never `import` it from JS, which compiles it standalone with no theme loaded and fails the build.
66
66
  - **CLIs** ship a `bin` — run directly: `npx @nurix/etna@latest` (or `npm install -g`).
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "899bed2c91e6",
2
+ "fingerprint": "dffbc8593fdd",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -28,8 +28,9 @@ as a failed gate and report it, never as a pass.
28
28
  ## The write protocol you enforce
29
29
 
30
30
  One writer per file. You write `state.md`, `thesis.md`, `forks.md`, `ledger.md`, `fragments/`,
31
- manifest, and your own sync-log **result** lines. You never write `ops/capture.md` (the
32
- facilitator's) or sync-log dispatch lines. The user may hand-edit anything: before rewriting any
31
+ manifest, and your own sync-log **result** lines. You never write the facilitator's files — the
32
+ folder, `ops/` and `ops/.gitignore` at bootstrap, `basis/` at intake, `ops/capture.md` — or
33
+ sync-log dispatch lines. The user may hand-edit anything: before rewriting any
33
34
  file, read its current state in full and treat content you did not write as **first-class user
34
35
  signal — fold it forward, never clobber it**. A hand-edit that contradicts the ledger is a design
35
36
  question: file a fork, don't "fix" the file.
@@ -116,7 +117,8 @@ Stop is facilitator-orchestrated because approval belongs to the user; you execu
116
117
  what applied and stop — the folder stays visibly unfinished and the user restarts; never
117
118
  resume silently from a half-applied state.
118
119
  3. **Uselessness test.** Spawn a **fresh, context-free cold reader** — an independent subagent
119
- that inherits none of this session's context — whose prompt contains only the allowed-path list
120
+ on the standard tier (`model: sonnet`, named on the dispatch so it never inherits yours) that
121
+ inherits none of this session's context — whose prompt contains only the allowed-path list
120
122
  (the manifest's destinations — never the session folder) and the instruction to reconstruct the
121
123
  design: thesis, commitments, reasoning, declined branches. Grade its reconstruction against the
122
124
  ledger and thesis. Gaps → record them in the manifest (`Result: fail`, named gaps), and the fixes
@@ -26,8 +26,9 @@ as a failed gate and report it, never as a pass.
26
26
  ## The write protocol you enforce
27
27
 
28
28
  One writer per file. You write `state.md`, `thesis.md`, `forks.md`, `ledger.md`, `fragments/`,
29
- manifest, and your own sync-log **result** lines. You never write `ops/capture.md` (the
30
- facilitator's) or sync-log dispatch lines. The user may hand-edit anything: before rewriting any
29
+ manifest, and your own sync-log **result** lines. You never write the facilitator's files — the
30
+ folder, `ops/` and `ops/.gitignore` at bootstrap, `basis/` at intake, `ops/capture.md` — or
31
+ sync-log dispatch lines. The user may hand-edit anything: before rewriting any
31
32
  file, read its current state in full and treat content you did not write as **first-class user
32
33
  signal — fold it forward, never clobber it**. A hand-edit that contradicts the ledger is a design
33
34
  question: file a fork, don't "fix" the file.
@@ -114,7 +115,8 @@ Stop is facilitator-orchestrated because approval belongs to the user; you execu
114
115
  what applied and stop — the folder stays visibly unfinished and the user restarts; never
115
116
  resume silently from a half-applied state.
116
117
  3. **Uselessness test.** Spawn a **fresh, context-free cold reader** — an independent subagent
117
- that inherits none of this session's context — whose prompt contains only the allowed-path list
118
+ on the standard tier (named on the dispatch so it never inherits yours) that
119
+ inherits none of this session's context — whose prompt contains only the allowed-path list
118
120
  (the manifest's destinations — never the session folder) and the instruction to reconstruct the
119
121
  design: thesis, commitments, reasoning, declined branches. Grade its reconstruction against the
120
122
  ledger and thesis. Gaps → record them in the manifest (`Result: fail`, named gaps), and the fixes
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.20.7",
4
+ "version": "3.20.9",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -29,5 +29,5 @@
29
29
  "origin": "https://cdn.nustack.io",
30
30
  "track": "latest"
31
31
  },
32
- "digest": "068ff439e1f9"
32
+ "digest": "0e411f901396"
33
33
  }
@@ -7,7 +7,7 @@ Read by the PreToolUse install gate (`compliance.mjs`) — an off-table install
7
7
  | `react` | ^19.2.3 | UI components | — |
8
8
  | `vite` | ^8.0.0 | Build tool, dev server | `webpack`, CRA |
9
9
  | `tailwindcss` | ^4.3.3 | Styling | `styled-components` |
10
- | `@nurix/components` | ^0.15.12 | The UI component library — import by subpath | `npx shadcn add`, a `components.json` scaffold |
10
+ | `@nurix/components` | ^2.0.0 | The UI component library — import by subpath; toasts come from its `compound/toast` subpath | `npx shadcn add`, a `components.json` scaffold, `sonner`, `react-toastify` |
11
11
  | `@tailwindcss/vite` | ^4.3.3 | Tailwind v4 Vite plugin — 4.3.x is the vite-8 peer line; 4.1.x tops out at vite 7 | `postcss`, `tailwind.config.js` |
12
12
  | `@vitejs/plugin-react-swc` | ^4.2.2 | JSX compilation | `@vitejs/plugin-react` |
13
13
  | `react-router-dom` | ^7.11.0 | Routing | — |
@@ -19,7 +19,6 @@ Read by the PreToolUse install gate (`compliance.mjs`) — an off-table install
19
19
  | `@dnd-kit/core` | ^6.3.1 | Drag and drop | `react-beautiful-dnd` |
20
20
  | `@xyflow/react` | ^12.11.0 | Node-based flow charts | `reactflow`, `react-flow-renderer` |
21
21
  | `motion` | ^12.23.26 | Animations | `react-spring` |
22
- | `sonner` | ^2.0.7 | Toast notifications | `react-toastify` |
23
22
  | `react-window` | ^2.2.3 | List virtualization | `react-virtualized` |
24
23
  | `nanoid` | ^6.0.0 | ID generation | `uuid` — exempt: UUIDv5/v7 database ids per `database.md` |
25
24
  | `express` | ^5.2.1 | HTTP server | `fastify`, `koa` |
@@ -14,18 +14,18 @@ Tailwind v4 + shadcn-based UI conventions for **web** apps — styling, the `@nu
14
14
 
15
15
  - **Build every UI through the `design` skill** — never hand-roll layouts; the page archetypes, the `design.md` identity system with its token artifact (`design.tokens.css`), and chrome wiring live in the skill.
16
16
  - **The brief's stated theme binds** — dark boots dark when the brief says so (recorded in the project's `design.md`); light is the default only when the brief is silent.
17
- - **`@nurix/components`** is the UI library — import by subpath (`@nurix/components/button`). **Never** `npx shadcn add`, no `components.json` scaffold — consume the prebuilt library (`.tsx`, not `.jsx`). *A recorded deviation from canonical shadcn, where primitives are vendored into `components/ui/` and edited in place: this workspace consumes a published library instead, and vendoring would fork it. Deliberate — the design skill does not "converge" it.*
17
+ - **`@nurix/components`** is the UI library — import by layer-prefixed subpath (`@nurix/components/element/button`). **Never** `npx shadcn add`, no `components.json` scaffold — consume the prebuilt library (`.tsx`, not `.jsx`). *A recorded deviation from canonical shadcn, where primitives are vendored into `components/ui/` and edited in place: this workspace consumes a published library instead, and vendoring would fork it. Deliberate — the design skill does not "converge" it.*
18
18
  - Vite: `@tailwindcss/vite` + `@vitejs/plugin-react-swc`. Pin `react` / `react-dom` / `react/jsx-runtime` / `react/jsx-dev-runtime` to the app's single copy via `resolve.alias` — `@nurix/*` ship nested react, and two copies means two hook dispatchers.
19
19
  - Tailwind v4 is CSS-only — no `tailwind.config.js`, no PostCSS.
20
20
  - **The CSS entry is whatever the manifest names**, not a fixed filename — `globals.css`, `index.css` and `styles.css` are each conventional in different framework guides, so resolve it rather than grep for one. Imports in order: `@import "./fonts.css"` (`@fontsource` registrations) → the project's `design.tokens.css` (derived by the design skill's validator from the `design.md` in the design folder — `packages/common/` at the base of a multi-package workspace, `src/common/` in a single-package repo — **never** hand-edited) → `@import "tailwindcss"` → the library's `styles.css` → the project's `personality.css` (the same validator's `--emit-personality`, compiling the `design.md` traits through `@nurix/components`' own compiler — **never** hand-edited) — then `@theme inline {…}` mapping vars to tokens.
21
21
  - **Dark mode is the `.dark` class on the root element**, bound as `@custom-variant dark (&:is(.dark *))` in the CSS entry — **never** a `data-theme` attribute. `@nurix/components` keys its `dark:` variants, its theme toggle, and its toaster on that class and a consumer cannot re-key them, so an app on the attribute renders mixed: its own tokens invert, the library's dark-only chrome stays light. The switcher is three parts — a pre-paint inline script in the HTML shell (a mounted provider runs too late and the page flashes), `color-scheme: light dark`, and the persisted-preference module.
22
- - Tokens: raw values in `:root:not(.dark)` and `:root.dark` — **both specificity (0,2,0), and that armor is load-bearing.** Tailwind compiles `@theme` into `@layer theme` and any unlayered declaration beats a layered one, so the library's unlayered `:root`/`.dark` defeats an app's `@theme` outright and *ties* a bare `:root`/`.dark`, leaving the winner to import order. Values are then consumed as semantic Tailwind tokens (`bg-card`, `text-foreground`) through an `@theme inline` mapping layer. The library bundles `class-variance-authority`, `clsx`, `tailwind-merge` — don't re-add them.
22
+ - Tokens: raw values in `:root:not(.dark)` and `:root.dark` — **both specificity (0,2,0), and that armor is load-bearing.** Tailwind compiles `@theme` into `@layer theme` and any unlayered declaration beats a layered one, so the library's unlayered `:root`/`.dark` defeats an app's `@theme` outright and *ties* a bare `:root`/`.dark`, leaving the winner to import order. Values are then consumed as semantic Tailwind tokens (`bg-card`, `text-foreground`) through an `@theme inline` mapping layer. The library ships `class-variance-authority` and `cn` (the class merger) as dependencies — don't re-add them.
23
23
  - **Never retune a Tailwind scale key `@nurix/components` consumes** — `--text-xs`, `--text-sm`, `--text-base`, `--text-lg`, `--text-xl`, `--text-2xl`. Its components carry raw scale utilities and its stylesheet declares no `font-size`, so those compile against *this app's* `@theme`: redefining `--text-sm` moves every button, menu item and table cell in the library at once, with nothing to report it. Change type by changing ramp tokens.
24
24
  - Spacing in 2/4/6/8; `object-cover`; `clip` / `clip-<n>` / `clip-fade` (the library's — they carry `min-width: 0` and `overflow-wrap: anywhere`; **never** `truncate` / `line-clamp-*`, which leave the flex-child overflow bug open); color through tokens — **never** hardcoded hex in components, and **never a literal font size**. The type ramp and the family rules are the design skill's [`references/type-system.md`](../skills/design/references/type-system.md); `text-sm` is a scale step and is fine, `text-[13px]` is a component overruling the system.
25
25
  - **Feel comes from the traits, never from literals on a control or collection surface.** `personality.css` compiles `density` / `pace` / `edge` / `depth` into `--density-*`, `--motion-duration-*`, `--radius-scale`, `--elevation-*`, and every library component reads those. App code stays inside the same reach: scanned surfaces pad and gap through the tokens (`p-(--density-pad-md)`, `gap-(--density-gap-md)`), a `transition-*` utility carries **no** `duration-*` class (the library's default transition duration retimes it from `pace`), a repeated-row container carries `data-mode="inline"`, and app animation reads `var(--motion-duration-base)`. A `p-3`, a `duration-200`, or a `rounded-lg` on such a surface silently opts out of the product's feel.
26
- - **Every rendered time is `<Timestamp>`** (`@nurix/components/element/timestamp`, `format="auto"`), and a live label ticks through `useNow` (`@nurix/components/lib/time`) — one shared interval, never a `setInterval` per row or a hand-rolled relative formatter.
27
- - **Status colour is the role.** `success`, `warning`, `info` are declared in `design.md` in both themes; the app's `@theme inline` maps its utilities onto the same roles (`--color-success: var(--success)`), and a status dot is `<Chip prefix="dot" color="var(--tone-success)">` — one hue per meaning on every surface.
28
- - **`cn()` keeps only one of a type role and a colour merged together** — its tailwind-merge tables class `text-h1` / `text-body` / `text-dense` as colours, so `cn("text-h1", "text-foreground")` and `cn("text-h1 text-foreground")` are both `text-foreground`. Keep a role and a colour in a `className` string that never goes through `cn`, or put the colour on the parent.
26
+ - **Every rendered time is `<Timestamp>`** (`@nurix/components/element/timestamp`, which picks relative or absolute per render), and a live label ticks through `useNow` (`@nurix/components/lib/time`) — one shared interval, never a `setInterval` per row or a hand-rolled relative formatter.
27
+ - **Status colour is the role.** `success`, `warning`, `info` are declared in `design.md` in both themes; the app's `@theme inline` maps its utilities onto the same roles (`--color-success: var(--success)`), and a status dot is `<Chip prefix="dot" intent="success">` (`intent` paints from the `--intent-*` tokens; `color` is for stored data colours, never status) — one hue per meaning on every surface.
28
+ - **`cn()` keeps only one of a type role and a colour merged together** — its merge tables class `text-h1` / `text-body` / `text-dense` as colours, so `cn("text-h1", "text-foreground")` and `cn("text-h1 text-foreground")` are both `text-foreground`. Keep a role and a colour in a `className` string that never goes through `cn`, or put the colour on the parent.
29
29
 
30
30
  ## Component Search Order
31
31
 
@@ -61,6 +61,6 @@ Every workspace package is scoped **`@nurix/`**; the dot vs. hyphen after the sc
61
61
  //registry.npmjs.org/:_authToken=${NPM_READ_TOKEN}
62
62
  ```
63
63
  The token needs only `Read` on the `nurix` scope. A `403` on install means auth failed — check `npm whoami` (local) or the `NPM_READ_TOKEN` secret (CI). Attempt the install directly — the token authenticates ambiently; don't pre-empt or second-guess it. If it fails, flag it to the user — **never** reach for alternatives, a substitute package, or `npm login` swaps.
64
- - **Import by subpath, never the barrel** — subpaths tree-shake reliably; the available subpaths are the package's `exports` keys. `import { Button } from "@nurix/components/button";`
65
- - **Styles** — import a CSS-shipping package's stylesheet **once** at the app entry: `import "@nurix/components/styles.css";`. Unstyled components are almost always a missing styles import. The shipped stylesheet is precompiled — no Tailwind `@source` directive unless consuming source via a workspace link.
64
+ - **Import by subpath, never the barrel** — subpaths tree-shake reliably; the available subpaths are the package's `exports` keys. `import { Button } from "@nurix/components/element/button";`
65
+ - **Styles** — `@import` a CSS-shipping package's stylesheet **once** in the app's CSS entry, after `@import "tailwindcss"`: `@import "@nurix/components/styles.css";` (the full import order is the `frontend` rule's). Unstyled components are almost always a missing styles import. The stylesheet is **not** precompiled — it omits `@import "tailwindcss"` and carries its own `@source` over the package's compiled JS, so the app's Tailwind build generates its utilities: add no `@source` for it, and never `import` it from JS, which compiles it standalone with no theme loaded and fails the build.
66
66
  - **CLIs** ship a `bin` — run directly: `npx @nurix/etna@latest` (or `npm install -g`).
@@ -27,7 +27,7 @@ Load when: the touch list exhibits `package.json` (deps, `exports`, scripts, `pa
27
27
  **Safe change:** Declare every imported package in the importer's own `package.json` (workspace siblings as `"@nurix/x": "workspace:*"`); never widen `public-hoist-pattern` to fix a missing-module error — add the dep; verify with a fresh `pnpm install` on a clean clone.
28
28
 
29
29
  ## package-exports-subpath-map — HIGH · rendezvous-string
30
- **Contract:** Consumers' import specifiers (`@nurix/components/button`) must match literal keys in the package's `exports` map; the `files` allowlist and `types` conditions must cover the same paths.
30
+ **Contract:** Consumers' import specifiers (`@nurix/components/element/button`) must match literal keys in the package's `exports` map; the `files` allowlist and `types` conditions must cover the same paths.
31
31
  **Detect:** `"exports"` and `"files"` in `package.json`, `from ['"]@nurix/[^'"]+/`, `"moduleResolution"` in `tsconfig.json`
32
32
  **Ships green, breaks:** Any subpath not mapped in `exports` throws `ERR_PACKAGE_PATH_NOT_EXPORTED` at runtime — and tsc under `moduleResolution: "node10"` ignores `exports` entirely, so types resolve while Node throws (use `"bundler"`/`"nodenext"` to make tsc see the real contract); adding a new component file without an `exports` entry publishes fine and breaks every consumer import; a built `dist/` path referenced by `exports` but missing from the `files` allowlist installs cleanly and fails only on first import of the published tarball.
33
33
  **Safe change:** Add the `exports` subpath (with `types` condition first in each condition block) in the same change as the new file; confirm `files` includes everything `exports` references; check the shipped surface with `npm pack --dry-run`; treat removing/renaming an exports key as a breaking change for all consumers.
@@ -1,54 +1,27 @@
1
- # Brainstorm — process, not archive
1
+ # Brainstorm
2
2
 
3
- A Claude Code skill that is a **thinking partner for designing large-scale software changes**.
4
- The session's product is the repo's living documentation: the conversation helps the user think
5
- correctly, the record stays readable at any pause, and the session ends with a harvest so
6
- complete that the session folder is useless — it moves to history and the user deletes or
7
- commits it.
3
+ A thinking partner for a large-scale software change. The session's product is the repository's living documentation: the conversation helps the user think correctly, the working surface reads well at any pause, and the stop pipeline harvests the session so completely that its folder is redundant. The folder then moves to history, and the user deletes or commits it.
8
4
 
9
- > Spec (single source of truth): `docs/skills/brainstorm/` in the etna repo. The etna
10
- > copy of this skill (`skills/brainstorm/`) is canonical; the user-level path
11
- > `~/.claude/skills/brainstorm/` is a symlink to it.
5
+ The design, its reasons and its evidence live in `docs/skills/brainstorm/` in the etna repo.
12
6
 
13
- ## The architecture — one capability, two seats
14
-
15
- Prose obligations decay in the conversing seat: an audit of real sessions finds the same rules
16
- dying in every one, the successful ones included. So the capability is split:
7
+ ## One capability, two seats
17
8
 
18
9
  | Seat | Component | Owns |
19
10
  | --- | --- | --- |
20
- | Conversation (main loop) | `SKILL.md` — the facilitator | The dialogue, the basis gate, the moves, one write: appending everything to `ops/capture.md` |
21
- | Paper (dispatched agent) | `agents/brainstorm.md` — the twin, pinned strong tier | Every working-surface file: distilling ops into pillars, recomposing the thesis whole, the semantic audits, the harvest |
22
- | Integrity (script) | `scripts/detector.mjs` | Mechanical checks with stable rule IDs; blocks the manifest and the move while gates fail |
23
- | Quality (authoring-time) | `evals/` (never ships) | Session-replay scenarios, the two-agent audit, contrastive facilitation |
24
-
25
- Every twin dispatch is paired-logged in `ops/sync-log.md` — the facilitator writes the dispatch
26
- line, the twin writes the result — so reconciliation is observable, never asserted.
27
-
28
- ## The session lifecycle
29
-
30
- - **`/brainstorm start`**
31
- 1. Basis gate — a document, a prior session folder in any format, or a brain dump.
32
- 2. Bootstrap `docs/research/{topic}-brainstorm/` — `ops/` untracked; the twin writes the surface.
33
- 3. Converse — dump, interview, probe, blindspot, converge — steerable in plain language.
34
- 4. "Let me read" anytime — compose on demand, read the thesis, come back.
35
- - **`/brainstorm stop`**
36
- 1. Converge → manifest → **one** user approval → apply → uselessness test.
37
- 2. The folder moves to `docs/history/brainstorms/{topic}/` — the completion marker.
38
- 3. The user decides: delete or commit.
39
-
40
- The working surface: `thesis.md` (claim → argument → what changed, recomposed whole, stamped),
41
- `forks.md` (open questions with close conditions — the only convergence currency), `ledger.md`
42
- (commitments: Decision / Why / How to apply / Resolves, declined options inline with re-evaluate
43
- conditions), `state.md` (anchor + the aspect map), `basis/`, `fragments/` (harvest-native,
44
- drafted in destination format), and untracked `ops/` (raw capture + sync log; deleted at stop).
11
+ | Conversation (main loop) | `SKILL.md`, the facilitator | the dialogue, the basis gate, the moves, the per-turn capture into `ops/capture.md`, the sync-log dispatch lines |
12
+ | Paper (dispatched agent) | the `brainstorm` agent, the twin, pinned to a strong tier | every working-surface file: distillation, the whole-thesis recompose, the semantic audits, the harvest |
13
+ | Integrity (script) | `scripts/detector.mjs` | mechanical checks with stable rule ids, blocking the manifest and the move while they fail |
14
+ | Quality (authoring time) | `evals/`, never shipped | activation and behaviour cases, session-replay scenarios, the two-agent audit |
45
15
 
46
16
  ## Files
47
17
 
48
- - `SKILL.md` — the facilitator hub
49
- - `references/doctrine.md` — thesis / forces / forks / commitments / consequences epistemics
50
- - `references/session-schema.md` — the single format authority (what the detector enforces)
51
- - `references/harvest.md` — the stop pipeline and routing map
52
- - `scripts/detector.mjs` — the rule registry (`node detector.mjs <folder> [--gate=…] [--json]`)
53
- - `scripts/fixtures/` — contrastive fixtures + runner (authoring-time; never ships)
54
- - `evals/` — session-replay + audit harness (authoring-time; never ships)
18
+ | Path | Holds |
19
+ | --- | --- |
20
+ | `SKILL.md` | the facilitator hub: re-anchor, commands, write ownership, capture, moves, dispatch, questions, promises |
21
+ | `references/entry.md` | `/brainstorm start`: lookup, basis gate, bootstrap, intake, aspect map, orientation |
22
+ | `references/doctrine.md` | the epistemics of the surface, shared by both seats, with the capture-and-converge field lessons |
23
+ | `references/session-schema.md` | the on-disk contract the detector parses, and its rule table |
24
+ | `references/harvest.md` | `/brainstorm stop`: the pipeline, the routing map, the apply field lessons |
25
+ | `scripts/detector.mjs` | the rule registry: `node detector.mjs <folder> [--gate=session\|manifest\|move] [--json]` |
26
+ | `scripts/fixtures/` | contrastive fixtures and their runner, `node scripts/fixtures/run-fixtures.mjs` |
27
+ | `evals/` | `activation.json`, `evals.json`, the replay driver and its scenarios |
@@ -1,192 +1,124 @@
1
1
  ---
2
2
  name: brainstorm
3
- description: "Use when starting or stopping a large-scale design brainstorm via `/brainstorm start | stop` — never on phrases like 'let's plan' or 'let's design'. Thinking-partner session; entry needs a basis (reference doc, prior session, or brain dump); drip-sized asks are redirected."
3
+ description: "Use when the user types `/brainstorm start` or `/brainstorm stop` to run a thinking-partner session on a large-scale change, from a basis (a reference doc, a prior session folder, a brain dump) to a harvest into the living docs. Never on 'let's plan' or 'let's design'; small asks are redirected."
4
4
  ---
5
5
 
6
6
  # Brainstorm
7
7
 
8
- Help the user think correctly about a large-scale change, in a record that reads well at any
9
- pause, and end with a harvest so complete the session folder is useless. You are the
10
- **facilitator** — the conversation seat of a capability split across two seats:
8
+ A thinking partner for a large-scale change. You are the **facilitator**: you hold the conversation, and your job is to help the user think correctly. The `brainstorm` agent, the **twin**, owns the paper: it writes the working surface, recomposes the thesis, audits it and drives the harvest. `scripts/detector.mjs` owns mechanical integrity. The session's product is the repository's living documentation; the session folder under `docs/research/{topic}-brainstorm/` is scaffolding, and the design assumes it is deleted once the harvest passes.
11
9
 
12
- | Seat | Owns | Writes |
13
- | --- | --- | --- |
14
- | **You** (this skill, main loop) | the conversation; dispatching the twin at gates and relaying its reports | `ops/capture.md` every turn, the sync-log dispatch lines, the basis at intake — **nothing else** |
15
- | **The twin** (the `brainstorm` agent, pinned strong tier) | the paper: distilling ops into the working surface, recomposing the thesis whole, audits, the harvest | every other file in the folder |
16
- | **The detector** (`scripts/detector.mjs`, run by the twin) | mechanical integrity | — |
10
+ ## Re-anchor whenever you lack the conversation
17
11
 
18
- **Never write the working surface yourself** — prose obligations decay in the conversing seat, and
19
- the split exists to keep them out of it.
12
+ Resuming a parked session, a new sitting, and a context that was compacted mid-session are one procedure. The folder plus its capture is the session's whole memory, so re-entry is a read, never a reconstruction:
20
13
 
21
- Load each reference at its moment and read it in full — **never skim to save context**; this skill
22
- is sized by completeness:
14
+ 1. Find the active folder: `docs/research/*-brainstorm/` whose `state.md` reads `Status: open` (or `stopping`).
15
+ 2. Read `state.md` in full (posture line, aspect map) and the last ten entries of `ops/capture.md`.
16
+ 3. Dispatch the twin (§ Dispatching the twin): gate `start` for a resume or a new sitting, gate `on-demand` after compaction; scope `re-brief + freshness audit`.
17
+ 4. Relay its report, tell the user in two lines where the session stands, and continue in the posture `state.md` names.
23
18
 
24
- | Reference | Load when |
19
+ ## Commands
20
+
21
+ Only these two commands enter or leave a session. The user decides when to converge and when to stop; you never close a session on your own reading of it.
22
+
23
+ | Input | Do |
24
+ | --- | --- |
25
+ | `/brainstorm start`, a matching folder is open under `docs/research/` | Re-anchor (above) |
26
+ | `/brainstorm start`, anything else | Read `references/entry.md` in full and run it |
27
+ | `/brainstorm stop` | Read `references/harvest.md` in full and run it |
28
+ | Any other turn while a session is open | The conduct below |
29
+
30
+ ## Who writes what
31
+
32
+ | Writer | Writes |
33
+ | --- | --- |
34
+ | You | the folder, `ops/` and `ops/.gitignore` at bootstrap; `basis/` at intake; `ops/capture.md` every turn; the **dispatch** line of every `ops/sync-log.md` pair |
35
+ | The twin | every other file: `state.md`, `thesis.md`, `forks.md`, `ledger.md`, `fragments/`, `ops/manifest.md`, the **result** line of every sync-log pair |
36
+ | The user | anything; the twin folds a hand-edit forward as first-class signal |
37
+
38
+ **Never write a surface file yourself, not even to fix a typo.** Filing, recomposition and hygiene are exactly the duties that decayed when the conversing seat held them, and a second writer on a file breaks the twin's diff against its own last compose. A correction you want goes into the capture; the twin applies it at the next dispatch.
39
+
40
+ ## Every turn: capture
41
+
42
+ Append one entry to `ops/capture.md` per turn that carries anything session-relevant: `### T<n> · <UTC datetime>` (stamp from `date -u +%Y-%m-%dT%H:%MZ`), then the substance, both sides, labelled by speaker. The bar is the lowest one; anything that matters to the session goes in, distilled by the twin later:
43
+
44
+ - what the user said that matters, with their own phrasing where the phrasing is the point;
45
+ - your causal diagnoses ("the leak is X because Y");
46
+ - informed rejections: the option, who rejected it, and why;
47
+ - definitions of every term the session starts leaning on;
48
+ - the reasoning chain behind any recommendation you make;
49
+ - residue: asides, ideas mentioned in passing, things not pursued.
50
+
51
+ **Your own substance is the class that leaks.** Conclusions survive in every record; the diagnoses, rejections, definitions and reasoning chains you produce are what an audited session lost, so capture them in the turn they arise. Never distil or reorganise the capture; distillation is the twin's.
52
+
53
+ ## Moves
54
+
55
+ Five moves set who drives and how much gets asked. There is no mode field and no trigger word: any phrasing that implies a move triggers it ("I want to converge" converges), and the first time each fires, name it in one line. A session opens in dump or interview; the other three are mid-session moves.
56
+
57
+ | Move | You do |
25
58
  | --- | --- |
26
- | `references/doctrine.md` | judging what a turn's substance *is* (force, fork, commitment), or how to word what you capture |
27
- | `references/session-schema.md` | bootstrapping a session, or interpreting detector or twin output |
28
- | `references/harvest.md` | at `stop`, before orchestrating the pipeline |
59
+ | **Dump** | The user drives. Ask nothing mid-stream; reflect the shape, contradictions and implications back as they land, never sit silent |
60
+ | **Interview** | You drive, in batches of two or three questions on one aspect, derived from the basis and the surface, never from a template or to fill an empty file |
61
+ | **Probe** | Challenge flaws, edge cases and conflicts with the tech or domain fragment; capture each finding without demanding its resolution |
62
+ | **Blindspot** | Dispatched, never conversed: the twin cold-reads the surface and returns at most five gated findings as forks; relay them in prose |
63
+ | **Converge** | Burn forks down to decisions or explicit parks; each resolution carries its why and how it applies, each park a destination |
64
+
65
+ Self-initiate a blindspot pass when the frame settles: an aspect closes, a converge burst lands, or a recompose materially changes the thesis. Widen the next reconcile dispatch's scope to `reconcile + blindspot`; it takes no conversational control, and its findings arrive as forks the user may ignore.
66
+
67
+ If you cannot say in one line whether something is a fork, a decision or residue, or how a decision records what it declined, read `references/doctrine.md`.
68
+
69
+ ## Dispatching the twin
70
+
71
+ | Gate | When |
72
+ | --- | --- |
73
+ | `start` | after the intake at entry; on resume or a new sitting |
74
+ | `on-demand` | the user asks to read or sync ("let me read", "sync up", "what's open?"); after compaction; or the capture has outrun the surface: by default eight entries since the last reconciled sync, sooner when a converge burst lands |
75
+ | `pause` | the user parks the session |
76
+ | `stop` | each leg of the stop pipeline (`references/harvest.md`) |
77
+
78
+ 1. Append the dispatch line to `ops/sync-log.md` **before** dispatching: `S<n> | gate: <gate> | dispatched: <UTC datetime> | scope: <scope>`. Never write the result line; the pair is only evidence when two authors wrote it.
79
+ 2. Dispatch the `brainstorm` agent on the **strong tier** its definition pins (Opus on Anthropic; the flagship model at high reasoning effort on OpenAI), and name that model on the dispatch itself, so a runtime that ignores the pin cannot hand the twin the session's model. Distillation, recomposition and harvest are the capability-sensitive work; the pin keeps their quality independent of your tier.
80
+ 3. Brief it self-contained: the absolute session-folder path, the gate, the scope, the sync id, and the skill's own path so it finds `scripts/detector.mjs` and these references.
81
+ 4. Keep one dispatch in flight. Keep conversing while it runs, except at `start`, `pause`, the stop legs, and "let me read", which wait for the result.
82
+ 5. At the next turn break, relay its one-line report (edits · new forks · open · untouched aspects), what the recompose changed in the thesis, and any fork it raised, in prose. That line is the only convergence pressure the skill applies. Tell a `failed` result plainly and re-run it at the next gate.
29
83
 
30
- ## The one habit that is yours: capture
84
+ **"Let me read"** is a designed pause: dispatch a compose, say it takes a couple of minutes, point the user at `thesis.md`, and resume when they come back.
31
85
 
32
- Append to `ops/capture.md` **every turn**, both sides, at the lowest bar — raw notes, not prose:
86
+ ## Questions
33
87
 
34
- - what the user said that matters;
35
- - your own substance — causal diagnoses, informed rejections of options you presented,
36
- definitions, reasoning chains behind recommendations;
37
- - residue you judge not worth filing.
88
+ Structured questions (the `AskUserQuestion` tool, or a numbered pick list) appear at four sites only: the intake batch, interview batches, converge picks, and the stop approvals. Everywhere else, prose.
38
89
 
39
- Stamp each turn per the schema (`### T# · <ISO datetime>`). **Never distill here** — distillation is
40
- the twin's. Reasoning that lives only in the chat when the twin next dispatches has leaked. The
41
- folder plus ops is the session's whole memory, which is what makes every re-entry cheap.
90
+ - **One pick per question, recommendation first**, related questions batched in one message.
91
+ - **After about five structured batches, converge with defaults.** Draft the simplest answer for every remaining fork, show the list once, and let the user name exceptions; past that point new lines of inquiry are overthinking on the user's time. Override: the user asks for the forks one by one, and then each comes as one pick, recommendation first.
92
+ - **Standing approval:** "don't seek any more approvals, I'll look at the final diffs" holds for the rest of the session, gap rounds included. Proceed on your recommendations, commit nothing, delete nothing, and leave every file for review.
93
+
94
+ You stop for three things, and everything else proceeds on a default you state: what only the user knows (the idea itself, its scope, the sitting), the harvest manifest approval (it writes into canonical documents), and the delete-or-commit choice at the end (it destroys or publishes the record).
95
+
96
+ ## Promises
97
+
98
+ - **No production code while a session is open.** Illustrative snippets live in the session folder; the session designs, it does not implement. Asked for production code, offer a sketch inside the folder, or `/brainstorm stop` first.
99
+ - **No silent rewrite.** Every recompose of the user's thesis is reported at the next turn break with what moved.
100
+ - **No canonical write unapproved.** Every harvest write, gap rounds included, follows an approved manifest.
101
+ - **Capture stays out of git.** `ops/` is gitignored from bootstrap and deleted at the move.
102
+ - **Plain English.** Name items by what they are; an id (`F3`, `D2`) rides in parentheses only where traceability needs it.
103
+
104
+ ## What this skill is NOT
105
+
106
+ | Request | Goes to |
107
+ | --- | --- |
108
+ | "Let's plan", "let's design", "how should we build X" with no `/brainstorm start` | Not a session. The root policy file may *offer* one when work is large or contradicts a recorded pillar; never enter on your own |
109
+ | A drip-sized ask: a one-line fix, a rename, one component's tweak | Redirect: too small for a session; do the work directly. Open a session only if the user insists |
110
+ | Refining or stress-testing an existing plan file ("interview me", "poke holes in my plan") | the `interview` skill |
111
+ | Writing for an audience: a memo, deck, exec update | the `writing` skill |
112
+ | Authoring or editing a doc, LLD or plan outside a harvest | the `documentation` skill |
113
+ | Migrating or resuming a session folder in an older format | Not supported; such a folder enters only as the basis of a fresh session |
42
114
 
43
- ## `start`
115
+ ## Load triggers
44
116
 
45
- Find sessions by their folders — **no index keeps a row per session**. Active sessions are
46
- `docs/research/*-brainstorm/`, harvested ones `docs/history/brainstorms/*/`; the folder name is the
47
- topic and each `thesis.md` heading its subject.
117
+ Read every triggered reference in full. This skill is sized by completeness: nothing in a reference is optional, skimmable or summarised elsewhere.
48
118
 
49
- | Topic matches | Do |
119
+ | Reference | Read when |
50
120
  | --- | --- |
51
- | an active session | resume it (Re-entry, below) |
52
- | a harvested session, or a session folder in another format | offer it **as a basis** for a fresh session |
53
- | nothing | open a new session |
54
-
55
- **1 · The entry gate.** A session needs substance. Ask for a **basis**, now:
56
-
57
- - a reference document (path or URL);
58
- - a prior session folder, in any format — ingested exactly like a PRD: copied into `basis/`,
59
- frozen, distilled; **never** operated on in place, **never** migrated;
60
- - a one-shot brain dump in prose.
61
-
62
- Drip-sized input (a bug fix, one button): say this skill is the wrong tool, and do not open the
63
- session unless the user explicitly overrides. No basis, no session.
64
-
65
- **2 · Bootstrap.**
66
-
67
- 1. Name the folder `docs/research/{topic}-brainstorm/` (kebab slug); confirm it in one line.
68
- 2. Create `ops/` holding a `.gitignore` containing `*`, `ops/capture.md`, and `ops/sync-log.md`.
69
- 3. Copy the basis into `basis/`. Add no index row — the folder is the session's entry.
70
- 4. Write the sync-log dispatch line and dispatch the twin (gate: start) to write the initial
71
- surface. **Never scaffold** `state.md`, `thesis.md`, `forks.md`, or `ledger.md` yourself.
72
-
73
- **3 · Calibrate and frame.**
74
-
75
- 1. Distill the basis first — it seeds everything.
76
- 2. Calibrate from the living docs (the ownership index, recent decision records, any
77
- open-questions doc), so your questions match this repo, not a template.
78
- 3. Ask one `AskUserQuestion` batch:
79
- - **sitting** — single sprint (the default, and the shape that succeeds) or explicitly multi;
80
- - **execution reality** — greenfield, brownfield, or hybrid; a migration gotcha found at plan
81
- time is found too late;
82
- - **where the idea is now** — fully in their head → dump; half-formed → interview.
83
- 4. Propose the **aspect map** — the thinking dimensions for *this* idea, derived from the basis,
84
- from no fixed list. The user edits it; it lives in `state.md`.
85
-
86
- **4 · Orient.** In 3–4 lines, written for a first-time user: how the session works (you talk, the
87
- folder keeps everything), the steering verbs in plain words, "let me read" (pause and read the
88
- thesis anytime), and what `stop` does (converge → your approval → harvest → the folder moves and
89
- you choose delete or commit). Then begin — **always in dump or interview**; probe and converge are
90
- mid-session moves, never starting postures.
91
-
92
- ## The moves
93
-
94
- Five user-steerable moves set who drives and how much gets asked. There is no `MODE:` field, no
95
- switch ceremony, and no sanctioned trigger word: **any phrasing that implies a move triggers it**
96
- ("I want to poke holes" → probe; "what am I missing?" → blindspot; "let's decide" → converge). The
97
- first time each move fires, name what you are doing in one line. When the signals call for a
98
- switch (the user monologues mid-interview; every probe answer is "haven't thought about it"), offer
99
- it once — never seize it.
100
-
101
- - **dump** — the user drives. Ask no questions mid-stream. Reflect back the shape, contradictions,
102
- and implications as they land — that reflection is the active listening; **never sit silent**.
103
- - **interview** — you drive. `AskUserQuestion` batches of 2–3, one aspect at a time. Derive the
104
- questions from the basis and the current surface — **never** from a template inventory, and
105
- **never** interview to fill empty files.
106
- - **probe** — you challenge: flaws, edge cases, conflicts with the tech or domain fragment. Note
107
- each finding in ops and move on; **never** demand resolution mid-probe.
108
- - **blindspot** — the hunt for unknown unknowns, **dispatched, never conversed**: you co-built the
109
- frame, so the outside view belongs to the twin.
110
- 1. Dispatch the twin (gate: on demand, scope: blindspot) to cold-read the whole surface against
111
- the thesis's stated goal. Its quality gate kills any candidate not grounded in this folder,
112
- material to the design, new, and answerable; at most five survivors return, each already
113
- filed as a fork.
114
- 2. Relay survivors in prose — finding → why it is material here → what answering it would
115
- change — **never** as a question barrage: the user engages what matters, and converge burns
116
- the rest down later. Zero survivors is one relay line; **never** manufacture findings.
117
- 3. Self-initiate a pass, without offering, whenever the frame settles — an aspect closes, a
118
- converge burst lands, the thesis materially recomposes — by widening a reconcile dispatch's
119
- scope. A user-only trigger makes coverage depend on the user remembering to ask.
120
- - **converge** — burn forks down to commitments or explicit parks, with `AskUserQuestion` for
121
- picks. Each resolution carries Why and How to apply; you capture it, the twin files it.
122
-
123
- ## Twin dispatches — the gates
124
-
125
- Dispatch at **start** (bootstrap), **on demand** (below), **pause**, and **stop** — **one dispatch in
126
- flight at a time**.
127
-
128
- 1. Before each dispatch, write its line to `ops/sync-log.md`
129
- (`S# | gate: <g> | dispatched: <ts> | scope: <s>`). The twin appends the result; the pairing
130
- keeps reconciliation observable instead of asserted.
131
- 2. At the next turn break, relay the twin's one-line report ("4 edits · 2 new forks · 6 open ·
132
- untouched: risks") plus what the recompose changed — a rewrite of the user's thinking is
133
- **never** silent. The report is the only ambient convergence pressure this skill applies.
134
- 3. On a `failed` result, tell the user plainly and re-dispatch at the next gate.
135
-
136
- **On demand** means the user asks ("let me read", "sync up", "what's open?"), or you judge the
137
- capture has outrun the surface meaningfully. **"Let me read"** is a designed-for pause, not an
138
- interruption: dispatch a compose (say honestly it takes a couple of minutes), point the user at
139
- `thesis.md` — claim → argument → what changed, stamped — and resume when they return.
140
-
141
- ## Re-entry — resume, or context loss
142
-
143
- Re-entry is a read, not a reconstruction. It covers three triggers identically: resuming a parked
144
- session, a new sitting, and **losing conversational context mid-session (compaction)** — finding
145
- yourself mid-session without memory of it means running this procedure; nothing you "remembered"
146
- matters.
147
-
148
- 1. Re-read this hub, `state.md` (posture line first), and the tail of `ops/capture.md`.
149
- 2. Dispatch the twin (gate: on demand) for a re-brief and freshness audit.
150
-
151
- While a session folder exists, read `state.md` at the start of every turn.
152
-
153
- ## `stop` — the fixed pipeline
154
-
155
- Read `references/harvest.md` first. The pipeline **always** runs — a stop *is* convergence plus
156
- harvest. You orchestrate; the twin executes each leg.
157
-
158
- 1. **Converge** — resolve every open fork now, or park it explicitly with a destination
159
- (mini-converge in conversation; the scope-guard trio in `harvest.md` disambiguates parks). If no
160
- blindspot round has run this session, offer one first, once — an unknown unknown found after
161
- commitments freeze is the expensive kind.
162
- 2. **Final sync and manifest** — dispatch the twin (gate: stop). It builds the manifest only when
163
- the detector's manifest gate is clean; relay anything blocking.
164
- 3. **One approval** — present the manifest via `AskUserQuestion`. Gap rounds re-enter here: every
165
- write to canonical docs is user-approved, **no exceptions**.
166
- 4. **Apply → uselessness test → move** — the twin's legs; relay the results. Harvest fails loud: a
167
- partial apply leaves the folder visibly unfinished in `docs/research/` and the user restarts the
168
- stop — **never** resume silently.
169
- 5. **The offer** — after the move to `docs/history/brainstorms/{topic}/`, ask via
170
- `AskUserQuestion`: **delete the folder, or commit it**. The user decides; the design assumes
171
- deletion.
172
-
173
- ## Conduct — holds for the whole session
174
-
175
- 1. **Speak plain English; codes live in files.** Name every item by what it is, with the code in
176
- parentheses only where traceability needs it ("…the timeout question (F2)"). **Never** lead with
177
- a bare `F3`/`D7`.
178
- 2. **No production code outside the session folder while it is open.** Illustrative snippets live
179
- in the folder. Asked for production code, offer a sketch inside the folder, or `/brainstorm stop`
180
- first.
181
- 3. **`AskUserQuestion` at exactly four sites:** the intake frame batch, interview batches, converge
182
- picks, and the stop approvals (manifest; delete-or-commit). Everywhere else, prose.
183
- 4. **Suggested, never seized.** Moves, abstractions, probes — one offer each; accept refusal
184
- without re-litigating. The one exemption is a self-initiated blindspot dispatch: it takes no
185
- conversational control, and its findings arrive as forks the user may ignore.
186
- 5. **Nothing lives only in the transcript.** What is not in the folder or in ops does not exist.
187
- Flaws, gaps, and contradictions reach the twin as capture; the twin turns them into forks, the
188
- only convergence currency.
189
- 6. **The user decides when to converge and when to stop.** Distance-to-coherent is visible in every
190
- relayed twin report; **never** say "let's decide now."
191
- 7. **Only `/brainstorm start` and `/brainstorm stop` enter or leave a session.** No
192
- auto-invocation, ever.
121
+ | `references/entry.md` | `/brainstorm start` with no open matching folder |
122
+ | `references/doctrine.md` | the first capture of a session; whenever you cannot say in one line how a fork, decision, decline or thesis is shaped |
123
+ | `references/session-schema.md` | bootstrap; writing a capture entry or dispatch line you are unsure of; relaying a detector finding |
124
+ | `references/harvest.md` | `/brainstorm stop`; any question about where session content lands |