@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.
- package/data/catalog/rules/frontend.md +5 -5
- package/data/catalog/rules/pnpm.md +2 -2
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/agents/brainstorm.md +5 -3
- package/data/harnesses/code/codex/agents/brainstorm.toml +5 -3
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/approved-packages.md +1 -2
- package/data/harnesses/code/rules/frontend.md +5 -5
- package/data/harnesses/code/rules/pnpm.md +2 -2
- package/data/harnesses/code/skills/boundary/references/packs/build-config-runtime.md +1 -1
- package/data/harnesses/code/skills/brainstorm/README.md +18 -45
- package/data/harnesses/code/skills/brainstorm/SKILL.md +105 -173
- package/data/harnesses/code/skills/brainstorm/references/doctrine.md +70 -141
- package/data/harnesses/code/skills/brainstorm/references/entry.md +70 -0
- package/data/harnesses/code/skills/brainstorm/references/harvest.md +85 -137
- package/data/harnesses/code/skills/brainstorm/references/session-schema.md +98 -135
- package/data/harnesses/code/skills/design/components/charts.md +121 -43
- package/data/harnesses/code/skills/design/components/collections.md +209 -41
- package/data/harnesses/code/skills/design/components/feedback.md +86 -25
- package/data/harnesses/code/skills/design/components/hooks.md +198 -12
- package/data/harnesses/code/skills/design/components/index.md +93 -71
- package/data/harnesses/code/skills/design/components/inputs.md +249 -157
- package/data/harnesses/code/skills/design/components/layout.md +98 -38
- package/data/harnesses/code/skills/design/components/media.md +46 -25
- package/data/harnesses/code/skills/design/components/motion.md +56 -46
- package/data/harnesses/code/skills/design/components/navigation.md +54 -15
- package/data/harnesses/code/skills/design/components/overlays.md +51 -41
- package/data/harnesses/code/skills/design/components/setup.md +84 -5
- package/data/harnesses/code/skills/design/components/typography.md +72 -22
- package/data/harnesses/code/skills/design/components/utils.md +47 -13
- package/data/harnesses/code/skills/design/data/chrome/board-column.md +12 -12
- package/data/harnesses/code/skills/design/data/chrome/data-table.md +6 -6
- package/data/harnesses/code/skills/design/data/chrome/side-panel.md +15 -15
- package/data/harnesses/code/skills/design/data/chrome/sidebar.md +25 -25
- package/data/harnesses/code/skills/design/data/chrome/stat-cards.md +22 -22
- package/data/harnesses/code/skills/design/data/chrome/topbar.md +12 -12
- package/data/harnesses/code/skills/design/references/emission.md +6 -6
- package/data/harnesses/code/skills/design/scripts/README-validator.md +20 -8
- package/data/harnesses/code/skills/design/scripts/validate-design-md.mjs +15 -10
- package/data/harnesses/delivery/agents/brainstorm.md +5 -3
- package/data/harnesses/delivery/codex/agents/brainstorm.toml +5 -3
- package/data/harnesses/delivery/harness.json +2 -2
- package/data/harnesses/delivery/skills/brainstorm/README.md +18 -45
- package/data/harnesses/delivery/skills/brainstorm/SKILL.md +105 -173
- package/data/harnesses/delivery/skills/brainstorm/references/doctrine.md +70 -141
- package/data/harnesses/delivery/skills/brainstorm/references/entry.md +70 -0
- package/data/harnesses/delivery/skills/brainstorm/references/harvest.md +85 -137
- package/data/harnesses/delivery/skills/brainstorm/references/session-schema.md +98 -135
- package/data/harnesses/etna/agents/brainstorm.md +5 -3
- package/data/harnesses/etna/codex/agents/brainstorm.toml +5 -3
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/skills/boundary/references/packs/build-config-runtime.md +1 -1
- package/data/harnesses/etna/skills/brainstorm/README.md +18 -45
- package/data/harnesses/etna/skills/brainstorm/SKILL.md +105 -173
- package/data/harnesses/etna/skills/brainstorm/references/doctrine.md +70 -141
- package/data/harnesses/etna/skills/brainstorm/references/entry.md +70 -0
- package/data/harnesses/etna/skills/brainstorm/references/harvest.md +85 -137
- package/data/harnesses/etna/skills/brainstorm/references/session-schema.md +98 -135
- package/data/harnesses/hr/harness.json +1 -1
- 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
|
|
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`,
|
|
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"
|
|
28
|
-
- **`cn()` keeps only one of a type role and a colour merged together** — its
|
|
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**
|
|
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`).
|
package/data/harness-index.json
CHANGED
|
@@ -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
|
|
32
|
-
|
|
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
|
-
|
|
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
|
|
30
|
-
|
|
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
|
-
|
|
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.
|
|
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": "
|
|
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.
|
|
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
|
|
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`,
|
|
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"
|
|
28
|
-
- **`cn()` keeps only one of a type role and a colour merged together** — its
|
|
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**
|
|
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
|
|
1
|
+
# Brainstorm
|
|
2
2
|
|
|
3
|
-
A
|
|
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
|
-
|
|
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
|
-
##
|
|
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
|
|
21
|
-
| Paper (dispatched agent) | `
|
|
22
|
-
| Integrity (script) | `scripts/detector.mjs` |
|
|
23
|
-
| Quality (authoring
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
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
|
-
|
|
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
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
86
|
+
## Questions
|
|
33
87
|
|
|
34
|
-
|
|
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
|
-
|
|
40
|
-
the
|
|
41
|
-
|
|
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
|
-
##
|
|
115
|
+
## Load triggers
|
|
44
116
|
|
|
45
|
-
|
|
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
|
-
|
|
|
119
|
+
| Reference | Read when |
|
|
50
120
|
| --- | --- |
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
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 |
|