@nurix/etna 0.19.28 → 0.19.30

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "56f4d401af64",
2
+ "fingerprint": "e9e399985980",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -102,6 +102,8 @@ A commit marks the user's behavioral verification of the work, and the working s
102
102
  - **A commit is the smallest unit an entry may describe**; above that the mapping is judgment. Work exceeding a draft's scope gets a *second* entry rather than stretching the first.
103
103
  - **Distillation is the `retro` agent** — run on demand (before a brainstorm or LLD, before a new project, after a refinement arc), it converts accumulated entries into a typed punch list (doc content, doc structure, skill evolution, pins, harness rules), appends actionable items to the backlog, and proposes only — application runs through the normal documentation loop.
104
104
 
105
+ **One-shot migrations are a different genre.** Work that runs **once** against a live system — a data backfill, a schema cutover, a dependency or harness upgrade rolled across repos — is a **migration runbook** at `docs/history/migrations/YYYY-MM-DD-{slug}.md` (template: the `documentation` skill's `templates/migration-runbook.md`), authored **before** execution and outcome-stamped after. A changelog entry says what changed in the repo; a runbook says what was executed against the world and how to verify or undo it. A repeatable procedure is neither — that is `docs/operations/`. When a runbook defers targets, it records **why** and the **trigger to re-evaluate them**, so the next run re-checks rather than inheriting the skip.
106
+
105
107
  ---
106
108
 
107
109
  ## Out-of-Scope Discovery
@@ -23,12 +23,14 @@ Out of scope (handled by the `boundary` skill, which derives contracts dynamical
23
23
 
24
24
  Decide the mode once, up front, from the version marker — then run.
25
25
 
26
- 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry. The resolved version's **major** is the structural-shape signal — a major bump means the mandated `docs/` shape changed.
26
+ 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry.
27
27
  2. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter (a semver).
28
28
  - **Absent** ⇒ the repo is unharnessed ⇒ **baseline mode** (reconcile from nothing), then audit.
29
- - **Behind on major** ⇒ the mandated shape changed ⇒ **baseline mode** (reconcile across the gap), then audit.
30
- - **Behind on only minor/patch** ⇒ the shape is unchanged ⇒ re-stamp the version (no reshape), then audit.
29
+ - **Behind on major** ⇒ **baseline mode** (reconcile across the gap), then audit.
30
+ - **Behind on minor/patch** ⇒ **probe before deciding.** Run the Step B2 detection pass read-only: if any old-shape artifact in the fold table is present, **or** the target tree is missing a folder the current shape mandates, the shape *did* change ⇒ **baseline mode**. Only when the probe finds nothing ⇒ re-stamp the version (no reshape), then audit.
31
31
  - **Equal to installed** ⇒ **audit only** (the default spine).
32
+
33
+ > **The version digit is a hint; the fold table is the authority.** A shape change ships in a minor whenever the capability behind it is additive — `docs/history/ledger/` dissolving into `docs/history/changelog/` arrived in a minor, as did `docs/history/migrations/`. Never conclude "minor ⇒ nothing to reshape" without running the probe: that reading silently strands dissolved-shape artifacts in the repo forever.
32
34
  3. **Precondition for baseline mode:** a root `CLAUDE.md` must exist. If absent, **refuse the reshape** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconciling against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a hard gate on the audit.
33
35
 
34
36
  You write only under `docs/` and `docs/memory/maintenance.md`. You never edit `CLAUDE.md` (the CLI ships it) or production code.
@@ -139,6 +141,7 @@ docs/
139
141
  │ ├── CHANGELOG.md # Master changelog index
140
142
  │ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
141
143
  │ ├── plans/ # Implementation plans (Status field required)
144
+ │ ├── migrations/ # One-shot migration/upgrade runbooks (YYYY-MM-DD-{slug}.md; outcome-stamped then frozen; NOT scaffolded empty)
142
145
  │ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
143
146
  │ └── backlog.md # Tracked work items by priority (P0-P3)
144
147
  ├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
@@ -170,6 +173,7 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
170
173
  | `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
171
174
  | `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
172
175
  | `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
176
+ | `docs/architecture/adr/` (legacy folder name) | **rename** to `docs/architecture/decisions/` — the same genre under the mandated name. Move every file across unchanged; an AD's body and its Decision Changelog tail are never rewritten by the move, and files keep their existing names (`AD-NNN-*.md`, legacy `ADR-*.md`). Repoint live references; leave frozen records' links as point-in-time |
173
177
  | a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
174
178
  | no `harness-version` in `structure.md` | stamp it (Step B4) |
175
179
 
@@ -201,7 +205,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
201
205
  ## Rules
202
206
 
203
207
  - **Never delete feature docs** — only update or flag for review.
204
- - **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
208
+ - **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
205
209
  - **Preserve existing doc structure and formatting** when updating.
206
210
  - **When in doubt, create a backlog item** rather than making a wrong update.
207
211
  - **Be specific:** include file paths, line numbers, and what changed.
@@ -21,12 +21,14 @@ Out of scope (handled by the `boundary` skill, which derives contracts dynamical
21
21
 
22
22
  Decide the mode once, up front, from the version marker — then run.
23
23
 
24
- 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry. The resolved version's **major** is the structural-shape signal — a major bump means the mandated `docs/` shape changed.
24
+ 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry.
25
25
  2. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter (a semver).
26
26
  - **Absent** ⇒ the repo is unharnessed ⇒ **baseline mode** (reconcile from nothing), then audit.
27
- - **Behind on major** ⇒ the mandated shape changed ⇒ **baseline mode** (reconcile across the gap), then audit.
28
- - **Behind on only minor/patch** ⇒ the shape is unchanged ⇒ re-stamp the version (no reshape), then audit.
27
+ - **Behind on major** ⇒ **baseline mode** (reconcile across the gap), then audit.
28
+ - **Behind on minor/patch** ⇒ **probe before deciding.** Run the Step B2 detection pass read-only: if any old-shape artifact in the fold table is present, **or** the target tree is missing a folder the current shape mandates, the shape *did* change ⇒ **baseline mode**. Only when the probe finds nothing ⇒ re-stamp the version (no reshape), then audit.
29
29
  - **Equal to installed** ⇒ **audit only** (the default spine).
30
+
31
+ > **The version digit is a hint; the fold table is the authority.** A shape change ships in a minor whenever the capability behind it is additive — `docs/history/ledger/` dissolving into `docs/history/changelog/` arrived in a minor, as did `docs/history/migrations/`. Never conclude "minor ⇒ nothing to reshape" without running the probe: that reading silently strands dissolved-shape artifacts in the repo forever.
30
32
  3. **Precondition for baseline mode:** a root `CLAUDE.md` must exist. If absent, **refuse the reshape** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconciling against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a hard gate on the audit.
31
33
 
32
34
  You write only under `docs/` and `docs/memory/maintenance.md`. You never edit `CLAUDE.md` (the CLI ships it) or production code.
@@ -137,6 +139,7 @@ docs/
137
139
  │ ├── CHANGELOG.md # Master changelog index
138
140
  │ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
139
141
  │ ├── plans/ # Implementation plans (Status field required)
142
+ │ ├── migrations/ # One-shot migration/upgrade runbooks (YYYY-MM-DD-{slug}.md; outcome-stamped then frozen; NOT scaffolded empty)
140
143
  │ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
141
144
  │ └── backlog.md # Tracked work items by priority (P0-P3)
142
145
  ├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
@@ -165,8 +168,10 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
165
168
  | repo-wide `docs/pillars/` | cross-module doctrine → `docs/architecture/`; delete the folder |
166
169
  | `docs/boundaries/` (legacy persisted boundaries) | delete — boundary analysis is a plan-time diagnostic (the `boundary` skill reads contracts fresh from source); fold any human-authored knowledge (external consumers, intent, accepted exceptions) into `docs/architecture/` |
167
170
  | `docs/OWNERSHIP_INDEX.md` (legacy derived ownership index) | delete — ownership is the union of feature `owns:` frontmatter, surfaced by the generated index |
171
+ | `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
168
172
  | `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
169
173
  | `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
174
+ | `docs/architecture/adr/` (legacy folder name) | **rename** to `docs/architecture/decisions/` — the same genre under the mandated name. Move every file across unchanged; an AD's body and its Decision Changelog tail are never rewritten by the move, and files keep their existing names (`AD-NNN-*.md`, legacy `ADR-*.md`). Repoint live references; leave frozen records' links as point-in-time |
170
175
  | a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
171
176
  | no `harness-version` in `structure.md` | stamp it (Step B4) |
172
177
 
@@ -198,7 +203,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
198
203
  ## Rules
199
204
 
200
205
  - **Never delete feature docs** — only update or flag for review.
201
- - **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
206
+ - **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
202
207
  - **Preserve existing doc structure and formatting** when updating.
203
208
  - **When in doubt, create a backlog item** rather than making a wrong update.
204
209
  - **Be specific:** include file paths, line numbers, and what changed.
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.4.1",
4
+ "version": "3.4.2",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
8
8
  ".vscode/settings.json"
9
9
  ],
10
- "digest": "3af16853b429"
10
+ "digest": "245930959725"
11
11
  }
@@ -28,7 +28,7 @@ No alternatives. Just use these.
28
28
  | motion | ^12.23.26 | Animations | react-spring |
29
29
  | sonner | ^2.0.7 | Toast notifications | react-toastify |
30
30
  | react-window | ^2.2.3 | List virtualization | react-virtualized |
31
- | nanoid | ^5.1.6 | ID generation | uuid |
31
+ | nanoid | ^6.0.0 | ID generation | uuid |
32
32
  | express | ^5.2.1 | HTTP server | fastify, koa |
33
33
  | drizzle-orm | ^0.45.2 | Database ORM | prisma, sequelize, typeorm |
34
34
  | drizzle-kit | ^0.31.10 | Schema tooling | - |
@@ -37,9 +37,9 @@ No alternatives. Just use these.
37
37
  | microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
38
38
  | react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
39
39
  | @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
40
- | shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
41
- | lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
42
- | @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
40
+ | shiki | ^4.3.1 | Syntax highlighting | prism, highlight.js |
41
+ | lucide-react | ^1.26.0 | Icons | react-icons, heroicons |
42
+ | @pdfme/generator | ^6.1.12 | PDF generation | jspdf, pdfkit |
43
43
  | cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
44
44
  | @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
45
45
  | localforage | ^1.10.0 | Client-side storage | idb, dexie |
@@ -120,6 +120,8 @@ A commit marks the user's behavioral verification of the work, and the working s
120
120
  - **A commit is the smallest unit an entry may describe**; above that the mapping is judgment. Work exceeding a draft's scope gets a *second* entry rather than stretching the first.
121
121
  - **Distillation is the `retro` agent** — run on demand (before a brainstorm or LLD, before a new project, after a refinement arc), it converts accumulated entries into a typed punch list (doc content, doc structure, skill evolution, pins, harness rules), appends actionable items to the backlog, and proposes only — application runs through the normal documentation loop.
122
122
 
123
+ **One-shot migrations are a different genre.** Work that runs **once** against a live system — a harness rollout across consumer repos, a catalog-wide cutover, a data backfill — is a **migration runbook** at `docs/history/migrations/YYYY-MM-DD-{slug}.md` (template: the `documentation` skill's `templates/migration-runbook.md`), authored **before** execution and outcome-stamped after. A changelog entry says what changed in this repo; a runbook says what was executed against the world and how to verify or undo it. A repeatable procedure is neither — that is `docs/operations/`. When a runbook defers targets, it records **why** and the **trigger to re-evaluate them**, so the next run re-checks rather than inheriting the skip.
124
+
123
125
  ---
124
126
 
125
127
  ## Project Memory
@@ -23,12 +23,14 @@ Out of scope (handled by the `boundary` skill, which derives contracts dynamical
23
23
 
24
24
  Decide the mode once, up front, from the version marker — then run.
25
25
 
26
- 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry. The resolved version's **major** is the structural-shape signal — a major bump means the mandated `docs/` shape changed.
26
+ 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry.
27
27
  2. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter (a semver).
28
28
  - **Absent** ⇒ the repo is unharnessed ⇒ **baseline mode** (reconcile from nothing), then audit.
29
- - **Behind on major** ⇒ the mandated shape changed ⇒ **baseline mode** (reconcile across the gap), then audit.
30
- - **Behind on only minor/patch** ⇒ the shape is unchanged ⇒ re-stamp the version (no reshape), then audit.
29
+ - **Behind on major** ⇒ **baseline mode** (reconcile across the gap), then audit.
30
+ - **Behind on minor/patch** ⇒ **probe before deciding.** Run the Step B2 detection pass read-only: if any old-shape artifact in the fold table is present, **or** the target tree is missing a folder the current shape mandates, the shape *did* change ⇒ **baseline mode**. Only when the probe finds nothing ⇒ re-stamp the version (no reshape), then audit.
31
31
  - **Equal to installed** ⇒ **audit only** (the default spine).
32
+
33
+ > **The version digit is a hint; the fold table is the authority.** A shape change ships in a minor whenever the capability behind it is additive — `docs/history/ledger/` dissolving into `docs/history/changelog/` arrived in a minor, as did `docs/history/migrations/`. Never conclude "minor ⇒ nothing to reshape" without running the probe: that reading silently strands dissolved-shape artifacts in the repo forever.
32
34
  3. **Precondition for baseline mode:** a root `CLAUDE.md` must exist. If absent, **refuse the reshape** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconciling against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a hard gate on the audit.
33
35
 
34
36
  You write only under `docs/` and `docs/memory/maintenance.md`. You never edit `CLAUDE.md` (the CLI ships it) or production code.
@@ -139,6 +141,7 @@ docs/
139
141
  │ ├── CHANGELOG.md # Master changelog index
140
142
  │ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
141
143
  │ ├── plans/ # Implementation plans (Status field required)
144
+ │ ├── migrations/ # One-shot migration/upgrade runbooks (YYYY-MM-DD-{slug}.md; outcome-stamped then frozen; NOT scaffolded empty)
142
145
  │ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
143
146
  │ └── backlog.md # Tracked work items by priority (P0-P3)
144
147
  ├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
@@ -170,6 +173,7 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
170
173
  | `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
171
174
  | `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
172
175
  | `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
176
+ | `docs/architecture/adr/` (legacy folder name) | **rename** to `docs/architecture/decisions/` — the same genre under the mandated name. Move every file across unchanged; an AD's body and its Decision Changelog tail are never rewritten by the move, and files keep their existing names (`AD-NNN-*.md`, legacy `ADR-*.md`). Repoint live references; leave frozen records' links as point-in-time |
173
177
  | a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
174
178
  | no `harness-version` in `structure.md` | stamp it (Step B4) |
175
179
 
@@ -201,7 +205,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
201
205
  ## Rules
202
206
 
203
207
  - **Never delete feature docs** — only update or flag for review.
204
- - **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
208
+ - **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
205
209
  - **Preserve existing doc structure and formatting** when updating.
206
210
  - **When in doubt, create a backlog item** rather than making a wrong update.
207
211
  - **Be specific:** include file paths, line numbers, and what changed.
@@ -21,12 +21,14 @@ Out of scope (handled by the `boundary` skill, which derives contracts dynamical
21
21
 
22
22
  Decide the mode once, up front, from the version marker — then run.
23
23
 
24
- 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry. The resolved version's **major** is the structural-shape signal — a major bump means the mandated `docs/` shape changed.
24
+ 1. Resolve the **installed harness version** (semver): read `version` from `.claude/harness.json`, shipped by the CLI at install. Never a number baked into this file. If `.claude/harness.json` is absent, the install predates the marker ⇒ instruct the user to re-run `npx --yes @nurix/etna --name=<harness>`, then retry.
25
25
  2. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter (a semver).
26
26
  - **Absent** ⇒ the repo is unharnessed ⇒ **baseline mode** (reconcile from nothing), then audit.
27
- - **Behind on major** ⇒ the mandated shape changed ⇒ **baseline mode** (reconcile across the gap), then audit.
28
- - **Behind on only minor/patch** ⇒ the shape is unchanged ⇒ re-stamp the version (no reshape), then audit.
27
+ - **Behind on major** ⇒ **baseline mode** (reconcile across the gap), then audit.
28
+ - **Behind on minor/patch** ⇒ **probe before deciding.** Run the Step B2 detection pass read-only: if any old-shape artifact in the fold table is present, **or** the target tree is missing a folder the current shape mandates, the shape *did* change ⇒ **baseline mode**. Only when the probe finds nothing ⇒ re-stamp the version (no reshape), then audit.
29
29
  - **Equal to installed** ⇒ **audit only** (the default spine).
30
+
31
+ > **The version digit is a hint; the fold table is the authority.** A shape change ships in a minor whenever the capability behind it is additive — `docs/history/ledger/` dissolving into `docs/history/changelog/` arrived in a minor, as did `docs/history/migrations/`. Never conclude "minor ⇒ nothing to reshape" without running the probe: that reading silently strands dissolved-shape artifacts in the repo forever.
30
32
  3. **Precondition for baseline mode:** a root `CLAUDE.md` must exist. If absent, **refuse the reshape** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconciling against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a hard gate on the audit.
31
33
 
32
34
  You write only under `docs/` and `docs/memory/maintenance.md`. You never edit `CLAUDE.md` (the CLI ships it) or production code.
@@ -137,6 +139,7 @@ docs/
137
139
  │ ├── CHANGELOG.md # Master changelog index
138
140
  │ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
139
141
  │ ├── plans/ # Implementation plans (Status field required)
142
+ │ ├── migrations/ # One-shot migration/upgrade runbooks (YYYY-MM-DD-{slug}.md; outcome-stamped then frozen; NOT scaffolded empty)
140
143
  │ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
141
144
  │ └── backlog.md # Tracked work items by priority (P0-P3)
142
145
  ├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
@@ -165,8 +168,10 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
165
168
  | repo-wide `docs/pillars/` | cross-module doctrine → `docs/architecture/`; delete the folder |
166
169
  | `docs/boundaries/` (legacy persisted boundaries) | delete — boundary analysis is a plan-time diagnostic (the `boundary` skill reads contracts fresh from source); fold any human-authored knowledge (external consumers, intent, accepted exceptions) into `docs/architecture/` |
167
170
  | `docs/OWNERSHIP_INDEX.md` (legacy derived ownership index) | delete — ownership is the union of feature `owns:` frontmatter, surfaced by the generated index |
171
+ | `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
168
172
  | `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
169
173
  | `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
174
+ | `docs/architecture/adr/` (legacy folder name) | **rename** to `docs/architecture/decisions/` — the same genre under the mandated name. Move every file across unchanged; an AD's body and its Decision Changelog tail are never rewritten by the move, and files keep their existing names (`AD-NNN-*.md`, legacy `ADR-*.md`). Repoint live references; leave frozen records' links as point-in-time |
170
175
  | a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
171
176
  | no `harness-version` in `structure.md` | stamp it (Step B4) |
172
177
 
@@ -198,7 +203,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
198
203
  ## Rules
199
204
 
200
205
  - **Never delete feature docs** — only update or flag for review.
201
- - **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
206
+ - **Never modify `docs/history/plans/`, `docs/history/changelog/`, or `docs/history/migrations/`** (frozen records — changelog entries are written only at commit time and distilled only by the `retro` agent; a migration runbook freezes at its Outcome stamp).
202
207
  - **Preserve existing doc structure and formatting** when updating.
203
208
  - **When in doubt, create a backlog item** rather than making a wrong update.
204
209
  - **Be specific:** include file paths, line numbers, and what changed.
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "harness": "etna",
3
3
  "name": "etna",
4
- "version": "1.2.1",
4
+ "version": "1.2.2",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
8
8
  ".vscode/settings.json"
9
9
  ],
10
- "digest": "ee6c9bba81e8"
10
+ "digest": "aa2dafdf309d"
11
11
  }
@@ -28,7 +28,7 @@ No alternatives. Just use these.
28
28
  | motion | ^12.23.26 | Animations | react-spring |
29
29
  | sonner | ^2.0.7 | Toast notifications | react-toastify |
30
30
  | react-window | ^2.2.3 | List virtualization | react-virtualized |
31
- | nanoid | ^5.1.6 | ID generation | uuid |
31
+ | nanoid | ^6.0.0 | ID generation | uuid |
32
32
  | express | ^5.2.1 | HTTP server | fastify, koa |
33
33
  | drizzle-orm | ^0.45.2 | Database ORM | prisma, sequelize, typeorm |
34
34
  | drizzle-kit | ^0.31.10 | Schema tooling | - |
@@ -37,9 +37,9 @@ No alternatives. Just use these.
37
37
  | microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
38
38
  | react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
39
39
  | @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
40
- | shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
41
- | lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
42
- | @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
40
+ | shiki | ^4.3.1 | Syntax highlighting | prism, highlight.js |
41
+ | lucide-react | ^1.26.0 | Icons | react-icons, heroicons |
42
+ | @pdfme/generator | ^6.1.12 | PDF generation | jspdf, pdfkit |
43
43
  | cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
44
44
  | @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
45
45
  | localforage | ^1.10.0 | Client-side storage | idb, dexie |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.19.28",
3
+ "version": "0.19.30",
4
4
  "description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
5
5
  "type": "module",
6
6
  "bin": {