@nurix/etna 0.18.0 → 0.18.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +6 -5
  2. package/data/harness-index.json +1 -1
  3. package/data/harnesses/code/CLAUDE.md +7 -18
  4. package/data/harnesses/code/agents/brainstorm.md +3 -3
  5. package/data/harnesses/code/agents/change-review.md +13 -10
  6. package/data/harnesses/code/agents/harness-manager.md +15 -15
  7. package/data/harnesses/code/agents/maintenance.md +10 -3
  8. package/data/harnesses/code/agents/performance-review.md +5 -0
  9. package/data/harnesses/code/harness.json +1 -1
  10. package/data/harnesses/code/rules/general.md +40 -36
  11. package/data/harnesses/code/skills/boundary/SKILL.md +15 -42
  12. package/data/harnesses/code/skills/boundary/references/boundary-taxonomy.md +366 -304
  13. package/data/harnesses/code/skills/brainstorm/README.md +9 -9
  14. package/data/harnesses/code/skills/brainstorm/SKILL.md +15 -15
  15. package/data/harnesses/code/skills/brainstorm/harvest.md +2 -2
  16. package/data/harnesses/code/skills/brainstorm/templates/backlog.md +2 -2
  17. package/data/harnesses/code/skills/brainstorm/templates/build.md +6 -6
  18. package/data/harnesses/code/skills/brainstorm/templates/decisions.md +3 -3
  19. package/data/harnesses/code/skills/brainstorm/templates/doctrine.md +2 -2
  20. package/data/harnesses/code/skills/brainstorm/templates/domain-model.md +2 -2
  21. package/data/harnesses/code/skills/brainstorm/templates/glossary.md +2 -1
  22. package/data/harnesses/code/skills/brainstorm/templates/non-goals.md +3 -7
  23. package/data/harnesses/code/skills/brainstorm/templates/questions.md +6 -5
  24. package/data/harnesses/code/skills/brainstorm/templates/state.md +1 -8
  25. package/data/harnesses/code/skills/brainstorm/templates/tech.md +6 -6
  26. package/data/harnesses/code/skills/brainstorm/templates/thesis.md +2 -2
  27. package/data/harnesses/code/skills/distiller/SKILL.md +48 -177
  28. package/data/harnesses/code/skills/distiller/references/docs-mode.md +116 -343
  29. package/data/harnesses/code/skills/distiller/references/method.md +37 -109
  30. package/data/harnesses/code/skills/documentation/SKILL.md +9 -6
  31. package/data/harnesses/code/skills/documentation/references/examples.md +30 -61
  32. package/data/harnesses/code/skills/documentation/references/style-guide.md +59 -62
  33. package/data/harnesses/code/skills/documentation/references/templates.md +25 -33
  34. package/data/harnesses/code/skills/workflow-mapper/SKILL.md +32 -11
  35. package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +1 -1
  36. package/data/harnesses/code-fable/CLAUDE.md +12 -23
  37. package/data/harnesses/code-fable/agents/brainstorm.md +3 -3
  38. package/data/harnesses/code-fable/agents/change-review.md +13 -10
  39. package/data/harnesses/code-fable/agents/harness-manager.md +15 -15
  40. package/data/harnesses/code-fable/agents/maintenance.md +10 -3
  41. package/data/harnesses/code-fable/agents/performance-review.md +5 -0
  42. package/data/harnesses/code-fable/harness.json +1 -1
  43. package/data/harnesses/code-fable/rules/general.md +40 -36
  44. package/data/harnesses/code-fable/skills/boundary/SKILL.md +15 -42
  45. package/data/harnesses/code-fable/skills/boundary/references/boundary-taxonomy.md +366 -304
  46. package/data/harnesses/code-fable/skills/brainstorm/README.md +9 -9
  47. package/data/harnesses/code-fable/skills/brainstorm/SKILL.md +15 -15
  48. package/data/harnesses/code-fable/skills/brainstorm/harvest.md +2 -2
  49. package/data/harnesses/code-fable/skills/brainstorm/templates/backlog.md +2 -2
  50. package/data/harnesses/code-fable/skills/brainstorm/templates/build.md +6 -6
  51. package/data/harnesses/code-fable/skills/brainstorm/templates/decisions.md +3 -3
  52. package/data/harnesses/code-fable/skills/brainstorm/templates/doctrine.md +2 -2
  53. package/data/harnesses/code-fable/skills/brainstorm/templates/domain-model.md +2 -2
  54. package/data/harnesses/code-fable/skills/brainstorm/templates/glossary.md +2 -1
  55. package/data/harnesses/code-fable/skills/brainstorm/templates/non-goals.md +3 -7
  56. package/data/harnesses/code-fable/skills/brainstorm/templates/questions.md +6 -5
  57. package/data/harnesses/code-fable/skills/brainstorm/templates/state.md +1 -8
  58. package/data/harnesses/code-fable/skills/brainstorm/templates/tech.md +6 -6
  59. package/data/harnesses/code-fable/skills/brainstorm/templates/thesis.md +2 -2
  60. package/data/harnesses/code-fable/skills/distiller/SKILL.md +48 -177
  61. package/data/harnesses/code-fable/skills/distiller/references/docs-mode.md +116 -343
  62. package/data/harnesses/code-fable/skills/distiller/references/method.md +37 -109
  63. package/data/harnesses/code-fable/skills/documentation/SKILL.md +9 -6
  64. package/data/harnesses/code-fable/skills/documentation/references/examples.md +30 -61
  65. package/data/harnesses/code-fable/skills/documentation/references/style-guide.md +59 -62
  66. package/data/harnesses/code-fable/skills/documentation/references/templates.md +25 -33
  67. package/data/harnesses/code-fable/skills/workflow-mapper/SKILL.md +32 -11
  68. package/data/harnesses/code-fable/skills/workflow-mapper/references/patterns.md +1 -1
  69. package/data/harnesses/discover/CLAUDE.md +41 -109
  70. package/data/harnesses/discover/agents/api.md +11 -28
  71. package/data/harnesses/discover/agents/codebase.md +12 -30
  72. package/data/harnesses/discover/agents/community.md +9 -21
  73. package/data/harnesses/discover/agents/deployed-client-bundle.md +16 -67
  74. package/data/harnesses/discover/agents/distribution-artifacts.md +21 -59
  75. package/data/harnesses/discover/agents/docs.md +11 -20
  76. package/data/harnesses/discover/agents/infra-backend-fingerprint.md +28 -68
  77. package/data/harnesses/discover/agents/packages.md +12 -28
  78. package/data/harnesses/discover/agents/session.md +18 -50
  79. package/data/harnesses/discover/agents/website.md +9 -19
  80. package/data/harnesses/discover/agents/wire-capture.md +22 -72
  81. package/data/harnesses/discover/harness.json +1 -1
  82. package/data/harnesses/discover/rules/discovery.md +73 -182
  83. package/data/harnesses/discover/rules/evaluation.md +90 -98
  84. package/data/harnesses/discover/rules/ingestion.md +123 -322
  85. package/data/harnesses/discover/rules/self-correction.md +67 -92
  86. package/data/harnesses/discover/rules/tradecraft.md +201 -172
  87. package/data/harnesses/hr/CLAUDE.md +21 -51
  88. package/data/harnesses/hr/harness.json +1 -1
  89. package/data/harnesses/hr/skills/interview-eval/SKILL.md +23 -11
  90. package/data/harnesses/hr/skills/interview-eval/TEMPLATE.md +49 -29
  91. package/data/harnesses/hr/skills/interview-eval/rubric.md +30 -30
  92. package/data/harnesses/kb-agi/CLAUDE.md +8 -8
  93. package/data/harnesses/kb-agi/agents/kb-agi-init.md +31 -22
  94. package/data/harnesses/kb-agi/agents/kb-catch-stale.md +1 -1
  95. package/data/harnesses/kb-agi/agents/kb-find-gaps.md +1 -1
  96. package/data/harnesses/kb-agi/agents/kb-fix-links.md +1 -1
  97. package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +2 -2
  98. package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +2 -2
  99. package/data/harnesses/kb-agi/harness.json +1 -1
  100. package/package.json +1 -1
package/README.md CHANGED
@@ -41,18 +41,18 @@ Re-run `npx @nurix/etna --name=code` anytime to refresh the harness content with
41
41
 
42
42
  ## After install: bootstrap the harness
43
43
 
44
- Installing only *drops the files* — the harness isn't active for your repo until you **baseline** it. Open Claude Code in the project and drive the reconcile chain once (the installed `CLAUDE.md` carries the same steps under its `## Bootstrap` heading, for the agent):
44
+ Installing only _drops the files_ — the harness isn't active for your repo until you **baseline** it. Open Claude Code in the project and drive the reconcile chain once (the installed `CLAUDE.md` carries the same steps under its `## Bootstrap` heading, for the agent):
45
45
 
46
46
  1. **"baseline this repo"** (or "reconcile the harness") — runs the **`harness-manager`** agent. It builds the `docs/` tree to the harness shape, stamps `docs/structure.md` with the installed `harness-version`, then hands back.
47
47
  2. If it asks for boundaries (a real codebase whose `docs/boundaries/` is still empty) — run **`/boundary generate`**. It detects your stack + information architecture and writes the typed boundary files.
48
48
  3. **"reconcile the harness"** again — `harness-manager` now proposes **modules** from those boundaries.
49
49
 
50
- Then work normally. This brownfield path reads your *actual* code, not a blank slate, so it's safe to run on an existing project with real history.
50
+ Then work normally. This brownfield path reads your _actual_ code, not a blank slate, so it's safe to run on an existing project with real history.
51
51
 
52
52
  Two things worth knowing on an existing repo:
53
53
 
54
54
  - **Your root `CLAUDE.md` is replaced** with the harness policy file (the old one is saved to `CLAUDE.md.bak.<ISO>`). If it held project-specific instructions, fold them back in after install — the harness file is the policy skeleton; your domain specifics sit alongside it.
55
- - **The ledger starts on your next commit.** The `post-commit` hook appends to `docs/memory/ledger/`; once enough entries accrue, the `maintenance` agent *proposes* a `distiller` run that distills them into provenance-linked fact-cards and, eventually, proposed `docs/` updates. Nothing runs on its own — it proposes, you approve.
55
+ - **The ledger starts on your next commit.** The `post-commit` hook appends to `docs/memory/ledger/`; once enough entries accrue, the `maintenance` agent _proposes_ a `distiller` run that distills them into provenance-linked fact-cards and, eventually, proposed `docs/` updates. Nothing runs on its own — it proposes, you approve.
56
56
 
57
57
  ### Optional: semantic retrieval (qmd)
58
58
 
@@ -69,13 +69,14 @@ The `nurixlabs` marketplace entry in `~/.claude/settings.json` is harmless to le
69
69
  Listed by `npx @nurix/etna` (no args) using the bundled `data/harness-index.json`.
70
70
 
71
71
  | Plugin name | Source in etna | What it ships |
72
- |---|---|---|
72
+ | --- | --- | --- |
73
73
  | `code` | [`plugins/code/`](../../plugins/code/) | Governance + session agents, baseline workflow skills, knowledge-ledger hooks |
74
74
  | `kb-agi` | [`plugins/kb-agi/`](../../plugins/kb-agi/) | Knowledge-vault scaffolding |
75
75
 
76
76
  ## How it works
77
77
 
78
78
  Each harness has two halves in the etna repo:
79
+
79
80
  - `plugins/<name>/` — the **plugin** (what a Claude Code plugin natively bundles): `definition.md` (manifest — identity + `skills:`/`rules:` lists), `agents/`, `hooks/`.
80
81
  - `harness/<name>/` — the **policy**: `CLAUDE.md` (pure policy, no frontmatter — installed as a verbatim copy) plus `index.md`, whose `plugin:` key names the plugin this harness pairs with. All harness-folder frontmatter lives in `index.md` alone.
81
82
 
@@ -88,7 +89,7 @@ Two kinds of membership:
88
89
  ---
89
90
  name: code
90
91
  skills: [boundary, brainstorm, distiller, documentation, workflow-mapper]
91
- rules: [general, nomenclature]
92
+ rules: [general, nomenclature]
92
93
  ---
93
94
  ```
94
95
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "2a8b6a3ea74d",
2
+ "fingerprint": "5749d4f02de6",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code-fable",
@@ -31,7 +31,7 @@ This is the only step that runs **before** the harness exists; everything below
31
31
  Three peer modes plus a Completion step — enter wherever the user's thinking already is. Each mode is implemented by an agent + skill; the behavioural detail lives in those files, not here.
32
32
 
33
33
  | Mode | Enter when | Implemented by | Exits to |
34
- |------|-----------|----------------|----------|
34
+ | --- | --- | --- | --- |
35
35
  | **Brainstorming** | explicit ask; or a user utterance challenges a loaded pillar headline → name the brushed principle and offer `/brainstorm start` (no auto-entry) | `brainstorm` agent + skill | Spec, Plan, or close + harvest |
36
36
  | **Spec** | new feature work | `spec-mode` agent + `documentation` skill | Plan |
37
37
  | **Plan** | a spec is approved | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md` | Completion |
@@ -51,7 +51,7 @@ Before modifying code in an unfamiliar area:
51
51
  5. If a `docs/memory/` file exists for the domain you're working in, read it for domain knowledge and failure modes
52
52
  6. When you author a declared module's docs, its `docs/modules/{m}/CLAUDE.md` auto-loads (the pillar bootstrap) — follow it. For code work it's surfaced via step 2.
53
53
 
54
- For the protocol on *writing* to memory (which file, what belongs there, what doesn't), see **Project Memory** below.
54
+ For the protocol on _writing_ to memory (which file, what belongs there, what doesn't), see **Project Memory** below.
55
55
 
56
56
  ---
57
57
 
@@ -60,12 +60,12 @@ For the protocol on *writing* to memory (which file, what belongs there, what do
60
60
  Project-specific learnings live in `docs/memory/` (git-tracked). Cross-project user preferences live in `~/.claude/` (untracked).
61
61
 
62
62
  | File | Owner | Contents |
63
- |------|-------|----------|
63
+ | --- | --- | --- |
64
64
  | `docs/memory/main.md` | Main agent | Project-wide patterns, conventions confirmed in this codebase, recurring failure modes, decisions whose rationale isn't obvious from the code |
65
65
  | `docs/memory/{agent-name}.md` | The named sub-agent | Strategy memory for that agent — how to be more effective on this project (research patterns, taxonomy, ownership conflict zones). Never user-centric. |
66
66
  | `~/.claude/projects/...` | Auto-memory system | User preferences, role, communication style, cross-project habits |
67
67
 
68
- **Override the default auto-memory location for project-relevant facts.** When recording a learning, ask: *is this true of this project, or true of this user?* Project facts → `docs/memory/`. User facts → `~/.claude/`.
68
+ **Override the default auto-memory location for project-relevant facts.** When recording a learning, ask: _is this true of this project, or true of this user?_ Project facts → `docs/memory/`. User facts → `~/.claude/`.
69
69
 
70
70
  `docs/memory/main.md` is created on first write. Append entries dated `## YYYY-MM-DD — {topic}`; oldest at bottom is fine.
71
71
 
@@ -103,25 +103,14 @@ A boundary is a horizontal cross-cutting contract — entity model, db schema, w
103
103
 
104
104
  Unless explicitly requested:
105
105
 
106
- ❌ **Tests** – Never generate, update, or modify test files.
107
- ❌ **Dependencies** – Never upgrade frameworks, libraries, or dependencies.
108
- ❌ **Compatibility** – Never maintain backward compatibility unless specified.
109
- ❌ **Branches & Worktrees** – Never self-create git branches or worktrees. Commit straight to the checked-out branch; branch or create a worktree only when the user asks.
110
- ❌ **Protected Files** – Before editing, if `docs/operations/protected-files.md` exists, read it and never modify any path it lists; also never modify `AGENTS.md` or the `protected-files.md` file itself.
111
- ✅ **Browser Automation** – Use Chrome CDP / "Claude in Chrome" tools whenever they help (verifying UI, reproducing a flow, seeding or inspecting local data) — no need to ask first. **Main session only:** never drive the browser from a sub-agent or workflow executor — the session-bound Chrome connection destabilizes the sub-agent. A sub-agent that needs browser verification instead returns an explicit CDP checklist (exact URLs, actions, expected outcomes) for the orchestrator to execute in the main session.
112
- ✅ **Orchestrate via Sub-agents** – Run the main session as an orchestrator: delegate substantive work (research, implementation, audits) to sub-agents spawned via the Agent/Task tool with `model: opus` (Claude Opus), keeping the main context for dispatch, coordination, and synthesis. Give each sub-agent a self-contained prompt; parallelize independent dispatches.
113
- ✅ **Documentation** – Keep `docs/` updated when code changes affect documented behavior.
114
- ⚠️ **Plans** – Plans are created directly in `docs/history/plans/` (see Workflow → Plan Mode). Once `Status: Complete` or `Status: Abandoned`, the file is frozen — never edited. If scope changes after completion, write a new dated plan that links back to the old one.
115
- ⚠️ **Tool Issues** – If any CLI tool, shell alias, or MCP tool behaves unexpectedly (syntax errors, silent failures, wrong defaults), report the exact tool name, command, and error to the user so they can fix or remove the underlying library.
106
+ ❌ **Tests** – Never generate, update, or modify test files. ❌ **Dependencies** – Never upgrade frameworks, libraries, or dependencies. ❌ **Compatibility** – Never maintain backward compatibility unless specified. ❌ **Branches & Worktrees** – Never self-create git branches or worktrees. Commit straight to the checked-out branch; branch or create a worktree only when the user asks. ❌ **Protected Files** – Before editing, if `docs/operations/protected-files.md` exists, read it and never modify any path it lists; also never modify `AGENTS.md` or the `protected-files.md` file itself. ✅ **Browser Automation** – Use Chrome CDP / "Claude in Chrome" tools whenever they help (verifying UI, reproducing a flow, seeding or inspecting local data) — no need to ask first. **Main session only:** never drive the browser from a sub-agent or workflow executor — the session-bound Chrome connection destabilizes the sub-agent. A sub-agent that needs browser verification instead returns an explicit CDP checklist (exact URLs, actions, expected outcomes) for the orchestrator to execute in the main session. ✅ **Orchestrate via Sub-agents** – Run the main session as an orchestrator: delegate substantive work (research, implementation, audits) to sub-agents spawned via the Agent/Task tool with `model: opus` (Claude Opus), keeping the main context for dispatch, coordination, and synthesis. Give each sub-agent a self-contained prompt; parallelize independent dispatches. ✅ **Documentation** – Keep `docs/` updated when code changes affect documented behavior. ⚠️ **Plans** – Plans are created directly in `docs/history/plans/` (see Workflow → Plan Mode). Once `Status: Complete` or `Status: Abandoned`, the file is frozen — never edited. If scope changes after completion, write a new dated plan that links back to the old one. ⚠️ **Tool Issues** – If any CLI tool, shell alias, or MCP tool behaves unexpectedly (syntax errors, silent failures, wrong defaults), report the exact tool name, command, and error to the user so they can fix or remove the underlying library.
116
107
 
117
108
  ---
118
109
 
119
110
  ## File Structure
120
111
 
121
- - Add file path at top of each file:
122
- `// src/modules/example.js - Module for handling user authentication`
123
- - Add a 1-line function description as a comment above each function:
124
- `// Extract JWT token from request based on endpoint type`
112
+ - Add file path at top of each file: `// src/modules/example.js - Module for handling user authentication`
113
+ - Add a 1-line function description as a comment above each function: `// Extract JWT token from request based on endpoint type`
125
114
 
126
115
  ---
127
116
 
@@ -20,15 +20,15 @@ If none of those steering files exist yet (a freshly-baselined repo), a session
20
20
 
21
21
  ## Modes and the close gate
22
22
 
23
- Four modes exist — **dump / interview / probe / converge** — and they change *who drives* and *how much gets asked*, not the loop, which never stops. The mode lives in the session's `state.md` and switches only on an explicit user word. The close gate is **open questions**, not decision state: questions are the single convergence currency, and the idea is coherent only when zero remain after a fresh sync. See the skill's **Modes** and **Coherence** sections — don't re-derive them here.
23
+ Four modes exist — **dump / interview / probe / converge** — and they change _who drives_ and _how much gets asked_, not the loop, which never stops. The mode lives in the session's `state.md` and switches only on an explicit user word. The close gate is **open questions**, not decision state: questions are the single convergence currency, and the idea is coherent only when zero remain after a fresh sync. See the skill's **Modes** and **Coherence** sections — don't re-derive them here.
24
24
 
25
25
  ## How you facilitate
26
26
 
27
- - **Speak plain English; codes live in the files.** Name a pillar item by what it *is*, never by a bare code (`Q3`, `D7`); append the code in parentheses only if traceability needs it.
27
+ - **Speak plain English; codes live in the files.** Name a pillar item by what it _is_, never by a bare code (`Q3`, `D7`); append the code in parentheses only if traceability needs it.
28
28
  - **Suggest, never seize.** Mode shifts, abstractions, and probes are one offer each; accept refusal without re-litigating.
29
29
  - **Never write production code** while a session is open — load-bearing snippets are illustration only, inside the session folder.
30
30
 
31
- You don't perform the harvest yourself, and you don't presume a destination. On close the session folder *is* the product by default; if the repo is v9-harnessed the skill **offers** the adapter routing into the doc tree. The skill's `## stop` section is the canonical harvest map — don't duplicate it.
31
+ You don't perform the harvest yourself, and you don't presume a destination. On close the session folder _is_ the product by default; if the repo is v9-harnessed the skill **offers** the adapter routing into the doc tree. The skill's `## stop` section is the canonical harvest map — don't duplicate it.
32
32
 
33
33
  ## What you may write
34
34
 
@@ -18,14 +18,14 @@ You work in two phases:
18
18
 
19
19
  Parse these from the user's prompt. Use defaults if not specified.
20
20
 
21
- | Parameter | Default | Examples |
22
- | ------------- | ---------------------------------------------- | ------------------------------------------------- |
23
- | `since` | `3 months ago` | "last 2 weeks", "since Feb 1", "since 2025-01-01" |
24
- | `until` | `now` | "until Feb 10" |
25
- | `batch_size` | `8` | "batches of 10" |
26
- | `output` | `change-review-YYYY-MM-DD.csv` (today's date) | "write to review.csv" |
27
- | `skip_merges` | `true` | "include merges" |
28
- | `branch` | current branch | "on main", "on ai-staging" |
21
+ | Parameter | Default | Examples |
22
+ | --- | --- | --- |
23
+ | `since` | `3 months ago` | "last 2 weeks", "since Feb 1", "since 2025-01-01" |
24
+ | `until` | `now` | "until Feb 10" |
25
+ | `batch_size` | `8` | "batches of 10" |
26
+ | `output` | `change-review-YYYY-MM-DD.csv` (today's date) | "write to review.csv" |
27
+ | `skip_merges` | `true` | "include merges" |
28
+ | `branch` | current branch | "on main", "on ai-staging" |
29
29
 
30
30
  The heatmap needs rolling 1w / 1m / 3m windows, so default `since` to 3 months even though the classifier processes every commit in range.
31
31
 
@@ -66,6 +66,7 @@ git diff-tree --no-commit-id --numstat -r {hash}
66
66
  ```
67
67
 
68
68
  Run these in a single bash call using a loop for efficiency. From the numstat output, compute per-commit totals:
69
+
69
70
  - `files_changed`: number of files in the commit
70
71
  - `insertions`: sum of added lines across all files
71
72
  - `deletions`: sum of removed lines across all files
@@ -86,11 +87,13 @@ Spawn **haiku** sub-agents via the Task tool with `subagent_type: "general-purpo
86
87
  Before building the prompt template, check if `docs/memory/change-review.md` contains **Module Taxonomy** and **Feature Taxonomy** sections. If yes, inject their content into the `{MODULE_TAXONOMY}` and `{FEATURE_TAXONOMY}` placeholders below. If no memory file exists, use these generic fallbacks:
87
88
 
88
89
  **Generic Module Taxonomy fallback:**
90
+
89
91
  ```
90
92
  Classify by the PRIMARY directory of changed files. Use the top-level directory as the module category (e.g., `src/components/` → `frontend/components`, `app/api/` → `backend/api`). For files spanning 3+ categories, use `multi`.
91
93
  ```
92
94
 
93
95
  **Generic Feature Taxonomy fallback:**
96
+
94
97
  ```
95
98
  Infer the product area from the commit message and file paths. Use descriptive labels like `auth`, `editor`, `deploy`, `ui`, `infra`, `docs`, `dx`, `other`.
96
99
  ```
@@ -182,7 +185,7 @@ When a commit cannot be classified by a sub-agent, use these defaults:
182
185
 
183
186
  # Phase 2 — Velocity analysis
184
187
 
185
- Where Phase 1 classifies *what* changed, Phase 2 asks *where is change accelerating or decelerating* — and whether review attention matches the risk. Read the CSV from Phase 1 (or the recent one found in Before Starting).
188
+ Where Phase 1 classifies _what_ changed, Phase 2 asks _where is change accelerating or decelerating_ — and whether review attention matches the risk. Read the CSV from Phase 1 (or the recent one found in Before Starting).
186
189
 
187
190
  ## Step 6: Velocity Heatmap
188
191
 
@@ -195,7 +198,7 @@ Compute commits-per-directory over rolling windows:
195
198
  Aggregate by the top-level directories the CSV's `directories` field already carries (computed generically in Phase 1, Step 2). Report:
196
199
 
197
200
  | Directory | Commits 1w | Commits 1m | Commits 3m | Trend |
198
- |-----------|-----------:|-----------:|-----------:|-------|
201
+ | --------- | ---------: | ---------: | ---------: | ----- |
199
202
 
200
203
  Trend column: ↑ rising, ↓ falling, → steady, ↑↑ sharply rising, ↓↓ sharply falling.
201
204
 
@@ -9,14 +9,14 @@ model: inherit
9
9
 
10
10
  You bring a repo's `docs/` governance tree into conformance with the **installed** harness version, and you audit that conformance on demand. You are the harness's migrator — the single owner of an operation it performs forever.
11
11
 
12
- The keystone: **baseline and upgrade are the same operation.** A repo's docs are always at *some* harness shape (none, pre-v8, v9, …); the installed plugin is at some shape; your job is to **reconcile the repo to the installed shape**. Baseline is the degenerate case (reconcile from nothing). Upgrade is reconcile across a version gap. Same agent, same convergence.
12
+ The keystone: **baseline and upgrade are the same operation.** A repo's docs are always at _some_ harness shape (none, pre-v8, v9, …); the installed plugin is at some shape; your job is to **reconcile the repo to the installed shape**. Baseline is the degenerate case (reconcile from nothing). Upgrade is reconcile across a version gap. Same agent, same convergence.
13
13
 
14
- Reconcile is **declarative, not a migration ladder.** You converge to the *current* shape — "match the installed shape" — idempotent, detecting old-shape artifacts to know what to *move* versus *create*. You do **not** maintain or replay an ordered `v8→v9→…` chain, and you never reconstruct a past version. (Same philosophy the stack already applies to the database: drop & push to a declared schema, not stacked migration files.)
14
+ Reconcile is **declarative, not a migration ladder.** You converge to the _current_ shape — "match the installed shape" — idempotent, detecting old-shape artifacts to know what to _move_ versus _create_. You do **not** maintain or replay an ordered `v8→v9→…` chain, and you never reconstruct a past version. (Same philosophy the stack already applies to the database: drop & push to a declared schema, not stacked migration files.)
15
15
 
16
16
  ## The two version layers (don't confuse them)
17
17
 
18
- - The **CLI** (`npx @nurix/etna --name=code`) refreshes the *engine* — `CLAUDE.md` + `.claude/{agents,skills,rules,scripts}/`. That is not your job; the install does it.
19
- - **You** reconcile the *repo's authored data* — the `docs/` tree — to match that engine.
18
+ - The **CLI** (`npx @nurix/etna --name=code`) refreshes the _engine_ — `CLAUDE.md` + `.claude/{agents,skills,rules,scripts}/`. That is not your job; the install does it.
19
+ - **You** reconcile the _repo's authored data_ — the `docs/` tree — to match that engine.
20
20
 
21
21
  The upgrade story is the two run back-to-back: install refreshes the engine → you reconcile the docs to it.
22
22
 
@@ -29,10 +29,10 @@ The upgrade story is the two run back-to-back: install refreshes the engine →
29
29
 
30
30
  These are different axes — keep them clean:
31
31
 
32
- - **`maintenance` audits docs-vs-code *fidelity*** — is the documented behavior *true* of the code? (stale docs, broken `owns` globs, routing drift). It edits docs for content accuracy.
33
- - **You audit repo-vs-spec *conformance*** — is the governance *structure* shaped to the installed harness version? (version marker present and current, mandated scaffolds present, no lingering dissolved-version artifacts, modules declared where the code's bounded contexts imply them).
32
+ - **`maintenance` audits docs-vs-code _fidelity_** — is the documented behavior _true_ of the code? (stale docs, broken `owns` globs, routing drift). It edits docs for content accuracy.
33
+ - **You audit repo-vs-spec _conformance_** — is the governance _structure_ shaped to the installed harness version? (version marker present and current, mandated scaffolds present, no lingering dissolved-version artifacts, modules declared where the code's bounded contexts imply them).
34
34
 
35
- You never edit a doc for content fidelity (that is `maintenance`); `maintenance` never reshapes the structure to a new version (that is you). Surfacing a statically-unresolved doc claim as a *question* in your hand-back (Step 1/Step 6) does **not** cross this seam — detection may cross, mutation never does. You observe and ask; you never assert falsity or fix the doc.
35
+ You never edit a doc for content fidelity (that is `maintenance`); `maintenance` never reshapes the structure to a new version (that is you). Surfacing a statically-unresolved doc claim as a _question_ in your hand-back (Step 1/Step 6) does **not** cross this seam — detection may cross, mutation never does. You observe and ask; you never assert falsity or fix the doc.
36
36
 
37
37
  ## Before starting
38
38
 
@@ -82,7 +82,7 @@ While reading each markdown doc to classify it, if the doc names a code symbol i
82
82
  This is what makes reconcile more than a fresh scaffold. Detect old-shape artifacts and fold them forward:
83
83
 
84
84
  | If you find (old shape) | Fold to (current shape) |
85
- |---|---|
85
+ | --- | --- |
86
86
  | `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
87
87
  | `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/` |
88
88
  | repo-wide `docs/pillars/` | module-local `docs/modules/{m}/pillars/`; cross-module doctrine → `docs/architecture/` |
@@ -110,7 +110,7 @@ Write `harness-version: <installed epoch>` into `docs/structure.md` frontmatter.
110
110
 
111
111
  ### Step 5b — Register the qmd retrieval lens (optional, skip-if-absent)
112
112
 
113
- Strictly optional and guarded on the binary — if `command -v qmd` finds nothing, **skip this entire step silently** (no error, no behavior change) and carry one advisory line into the Step 6 hand-back: *"qmd not installed — semantic retrieval unavailable; glob routing active."* The index is a **local rebuildable lens** — data stays in git; never commit index artifacts, and never use `qmd init` (that writes a project-local `.qmd`; the default global index keeps the repo clean).
113
+ Strictly optional and guarded on the binary — if `command -v qmd` finds nothing, **skip this entire step silently** (no error, no behavior change) and carry one advisory line into the Step 6 hand-back: _"qmd not installed — semantic retrieval unavailable; glob routing active."_ The index is a **local rebuildable lens** — data stays in git; never commit index artifacts, and never use `qmd init` (that writes a project-local `.qmd`; the default global index keeps the repo clean).
114
114
 
115
115
  If the binary exists, register the docs subtrees once the tree is scaffolded. **Do not register one collection rooted at `docs/`** — qmd 2.5.3 hard-codes the `**/*.md` pattern (a custom positional glob is silently discarded) and has no `--ignore`/`--exclude` flag, so a `docs/`-root collection provably sweeps the consumable inbox queue at `docs/memory/inbox/` into the index. The inbox is **not** in scope (it is distilled into `memory/facts`, which is — and its entries are deleted on digestion, which would leave dangling index entries). Register one collection **per indexable subtree** instead — never `docs/memory` as a whole, only `docs/memory/facts` — so the inbox is excluded by construction:
116
116
 
@@ -130,12 +130,12 @@ This augments routing; it never supersedes the Step 6 ownership resolution.
130
130
 
131
131
  ### Step 6 — Module proposal
132
132
 
133
- Modules are *declared*, never inferred from physical layout. Derive the repo's candidate bounded contexts directly from the code and docs: distinct wire surfaces (who owns routes/handlers), schema/data-access ownership, entry points and process units, plus any contexts `docs/architecture/` or feature `owns` globs already name.
133
+ Modules are _declared_, never inferred from physical layout. Derive the repo's candidate bounded contexts directly from the code and docs: distinct wire surfaces (who owns routes/handlers), schema/data-access ownership, entry points and process units, plus any contexts `docs/architecture/` or feature `owns` globs already name.
134
134
 
135
135
  - Propose the derived contexts as candidate modules. For each, partition existing flat feature docs by `owns`-glob overlap.
136
136
  - **Propose — don't force.** Declaration is opt-in: a single-context app stays flat (so does a monolith whose contexts all share one kernel); declare `docs/modules/{m}/` only when the author accepts a context as a module. A module is tied to code by its `owns` globs, **layout-blind** — a workspace is not a module (one workspace may hold several contexts; one context may span workspaces).
137
137
 
138
- If Step 5b skipped because `qmd` was absent, carry its one advisory line into the hand-back — *"qmd not installed — semantic retrieval unavailable; glob routing active."* — advisory, never an error, never a gate.
138
+ If Step 5b skipped because `qmd` was absent, carry its one advisory line into the hand-back — _"qmd not installed — semantic retrieval unavailable; glob routing active."_ — advisory, never an error, never a gate.
139
139
 
140
140
  Re-running you is safe — the structure work is already done (idempotent), so a second pass is just the module proposal.
141
141
 
@@ -143,7 +143,7 @@ Re-running you is safe — the structure work is already done (idempotent), so a
143
143
 
144
144
  > - `docs/x.md:NN` names `fn()` — no static definition found; confirm it is not generated/re-exported before treating as stale.
145
145
 
146
- End the block with: *"NEXT (optional): run the maintenance agent to confirm or dismiss these — advisory, not a gate; baseline is complete regardless."* Omit the whole block when the inventory observed nothing (a clean report is correct).
146
+ End the block with: _"NEXT (optional): run the maintenance agent to confirm or dismiss these — advisory, not a gate; baseline is complete regardless."_ Omit the whole block when the inventory observed nothing (a clean report is correct).
147
147
 
148
148
  If the user **declines** the advisory rather than running the follow-up, record each declined item in `docs/history/backlog.md` in the existing format (`- **[P0–P3]** <finding> — discovered by harness-manager`), priority = the finding's own severity on the **same P0–P3 scale as code work** — never a segregated section, never an auto-lowest tier — deduped against existing entries (already present ⇒ leave it). A backlog line is a record, never a gate.
149
149
 
@@ -157,9 +157,9 @@ Confirm all mandated files exist; `structure.md` carries the current `harness-ve
157
157
 
158
158
  Conformance, not fidelity. Report a table; fix nothing destructively without asking.
159
159
 
160
- - **Version currency** — `harness-version` present in `structure.md` and equal to installed? If behind/absent → recommend Reconcile. (This is the *repo-vs-installed* gap — it self-heals once the consumer reinstalls and re-runs you. The next two checks catch what reinstall *hasn't* happened yet, or was bypassed by a hand-edit.)
161
- - **Published-version currency** *(advisory, network)* — the installed `.claude/harness.json` records the kit's `version`; the published kit may have moved past it. Attempt `npm view @nurix/etna version` (the kit is a restricted package — needs npm auth + network). **Guard:** on *any* failure — offline, no auth, npm absent, timeout — skip and report one line: *"couldn't check the published harness version — re-run `npx @nurix/etna --name=code` to refresh to the latest."* On success, compare the published version against `.claude/harness.json`'s `version`; if published is ahead, recommend re-running the CLI to pull the newer kit. Never a gate, never blocks.
162
- - **Kit build fingerprint (digest)** *(informational)* — `.claude/harness.json` carries a `digest`: a deterministic fingerprint of the exact kit **build** the consumer installed (`build-data` computes it over the shipped bundle). Two installs share a digest iff they are byte-identical builds; a hotfix that changes kit bytes without bumping `version` still moves the digest — so it answers *which build am I on*, finer than `version`+`epoch` alone. **Don't recompute it over `.claude/` to self-check:** the installed layout is a superset of the build (the project `CLAUDE.md` sits at the repo root, `.claude/` adds `settings.json`/`harness.json`/local rule files), so paths and file sets differ **by design** — a recompute would never match. The actionable upgrade signals are the two checks above (epoch reconcile + published-version); the digest is provenance, and the seed for any future published-digest drift check.
160
+ - **Version currency** — `harness-version` present in `structure.md` and equal to installed? If behind/absent → recommend Reconcile. (This is the _repo-vs-installed_ gap — it self-heals once the consumer reinstalls and re-runs you. The next two checks catch what reinstall _hasn't_ happened yet, or was bypassed by a hand-edit.)
161
+ - **Published-version currency** _(advisory, network)_ — the installed `.claude/harness.json` records the kit's `version`; the published kit may have moved past it. Attempt `npm view @nurix/etna version` (the kit is a restricted package — needs npm auth + network). **Guard:** on _any_ failure — offline, no auth, npm absent, timeout — skip and report one line: _"couldn't check the published harness version — re-run `npx @nurix/etna --name=code` to refresh to the latest."_ On success, compare the published version against `.claude/harness.json`'s `version`; if published is ahead, recommend re-running the CLI to pull the newer kit. Never a gate, never blocks.
162
+ - **Kit build fingerprint (digest)** _(informational)_ — `.claude/harness.json` carries a `digest`: a deterministic fingerprint of the exact kit **build** the consumer installed (`build-data` computes it over the shipped bundle). Two installs share a digest iff they are byte-identical builds; a hotfix that changes kit bytes without bumping `version` still moves the digest — so it answers _which build am I on_, finer than `version`+`epoch` alone. **Don't recompute it over `.claude/` to self-check:** the installed layout is a superset of the build (the project `CLAUDE.md` sits at the repo root, `.claude/` adds `settings.json`/`harness.json`/local rule files), so paths and file sets differ **by design** — a recompute would never match. The actionable upgrade signals are the two checks above (epoch reconcile + published-version); the digest is provenance, and the seed for any future published-digest drift check.
163
163
  - **Scaffold completeness** — every mandated file present.
164
164
  - **Dissolved-version residue** — any `operations/guardrails.md`, repo-wide `docs/pillars/`, `architecture/overview.md`, a persisted `docs/boundaries/` tree, or other old-shape artifact lingering.
165
165
  - **Module declaration coverage** — do the repo's bounded contexts have declared module homes where the author intended them? (Surface gaps; never auto-declare.)
@@ -10,6 +10,7 @@ model: inherit
10
10
  You maintain codebase coherence by detecting drift between docs and code, and fixing it. Scope: stale feature docs, broken ownership, routing table drift, architecture drift, unowned source paths, backlog health.
11
11
 
12
12
  Out of scope (handled by the `boundary` skill, which derives contracts dynamically from source):
13
+
13
14
  - **Pre-implementation impact analysis** (checking a plan against cross-cutting contracts before coding) → `boundary` skill, `check` mode
14
15
  - **Diff-scoped contract analysis** (what could a change break across module edges) → `boundary` skill, `scan` mode
15
16
 
@@ -30,15 +31,18 @@ Out of scope (handled by the `boundary` skill, which derives contracts dynamical
30
31
  ## Step 2: Validate Ownership
31
32
 
32
33
  For each doc with `owns` frontmatter:
34
+
33
35
  - Verify the glob patterns match existing files
34
36
  - Report deleted paths, empty globs, orphaned ownership
35
37
 
36
38
  For each code symbol or path a doc explicitly **names** (function/export/route/type):
39
+
37
40
  - Verify it resolves in the code, independent of git-churn — Step 3's churn gate is blind to churn-free false claims
38
41
  - Flag unresolved named referents as drift, phrased as a question (e.g. `docs/x.md:NN names fn() — no static definition found; confirm it is not generated/re-exported before treating as stale`)
39
42
  - On codegen/reflection/DI/barrel stacks where static resolution is unreliable, skip — yielding nothing is correct
40
43
 
41
44
  Also check the **env contract** when the repo declares a canonical `.env.example` (or equivalent). The named-referent check above covers code symbols and paths but not env vars, which live in a separate canonical file:
45
+
42
46
  - Extract the `UPPER_SNAKE` env keys the code reads (`process.env.X` and the deploy scripts' generated env). Grep each against the canonical `.env.example`.
43
47
  - Raise any absence as a question (e.g. `server reads MASTER_KEK but no MASTER_KEK appears in .env.example — confirm the contract still holds`). Skip when no canonical file exists.
44
48
 
@@ -47,6 +51,7 @@ Also check the **env contract** when the repo declares a canonical `.env.example
47
51
  Run `git log --since="2 weeks ago" --name-only --pretty=format:"%h %s"` to find changed source files.
48
52
 
49
53
  For each changed file:
54
+
50
55
  - Match against `owns` patterns from every feature doc — flat and module-local alike (`docs/{features,modules/*/features}/**/*.md`) → identify the owning doc
51
56
  - If no owner exists → flag as unowned
52
57
  - If owner exists → compare last modified dates (`git log -1 --format="%ci" -- <path>`), flag docs where code changed more recently (14-day threshold)
@@ -61,7 +66,7 @@ If `./docs/routing.md` exists:
61
66
 
62
67
  Also flag **unowned paths** — top-level source directories with no owning feature doc (no `owns` glob covers them).
63
68
 
64
- Also catch a **stale greenfield self-label.** If `routing.md` (or `structure.md`) asserts the repo is greenfield — *"Greenfield. No source code or feature docs exist yet"* or similar — **but a real source tree exists** (the derived source roots from this step's item 2 above, or Step 5's Unowned-code derivation, are non-empty, e.g. a populated `packages/` of real workspaces), the self-label has gone stale: the scaffold filled in but the doc still announces an empty repo. Raise it as a question (e.g. `routing.md says "No source code exists yet" but packages/ holds 5 workspaces — confirm the greenfield label should be retired`).
69
+ Also catch a **stale greenfield self-label.** If `routing.md` (or `structure.md`) asserts the repo is greenfield — _"Greenfield. No source code or feature docs exist yet"_ or similar — **but a real source tree exists** (the derived source roots from this step's item 2 above, or Step 5's Unowned-code derivation, are non-empty, e.g. a populated `packages/` of real workspaces), the self-label has gone stale: the scaffold filled in but the doc still announces an empty repo. Raise it as a question (e.g. `routing.md says "No source code exists yet" but packages/ holds 5 workspaces — confirm the greenfield label should be retired`).
65
70
 
66
71
  ## Step 5: Check Architecture & Backlog
67
72
 
@@ -74,10 +79,12 @@ Also catch a **stale greenfield self-label.** If `routing.md` (or `structure.md`
74
79
  ## Step 6: Remediate
75
80
 
76
81
  For each stale doc:
82
+
77
83
  - If drift is clear (renamed function, new export, changed props) → update the doc directly
78
84
  - If drift is ambiguous (major refactor, unclear intent) → backlog it
79
85
 
80
86
  For unowned code paths:
87
+
81
88
  - Append: `- **[P2]** No feature doc owns \`{dir}/\` — discovered by maintenance` (`{dir}` = the actual unowned source directory)
82
89
 
83
90
  **Declined realignment:** When you propose a realignment and the user **declines or does not act**, never drop the finding and never block. Append it to `docs/history/backlog.md` as `- **[P0–P3]** <finding> — discovered by maintenance`, with priority = the finding's own severity **on the same P0–P3 scale as code items** — never a segregated "compliance" section, never auto-relegated to the lowest tier. Record once: dedupe against existing entries; if already present, leave it. (This is the decline branch — it pairs with dispatching a remediation sub-agent on a yes.)
@@ -87,8 +94,8 @@ For unowned code paths:
87
94
  1. Update `docs/structure.md` Health Log with today's date and summary
88
95
  2. Update `docs/memory/maintenance.md` with last review date, stale docs fixed, unowned paths, backlog items created
89
96
  3. Report findings: stale docs, broken ownership, unowned code, architecture drift, backlog health
90
- 4. **Inbox-distillation threshold.** Count undigested inbox entries — `## ` entry blocks across `docs/memory/inbox/*.md` (the inbox is consume-on-digest, so every block present is undigested). If the count is **≥5**, add one line to the report **proposing** a `distiller` `facts` run — propose only, never auto-run, no cron. If the user declines or ignores it, do nothing: the count keeps growing and the proposal reappears next pass — that recurrence *is* the dedupe, so never backlog it.
91
- 5. **Docs-distillation threshold.** Per target doc, count undigested fact-cards (`invalid_from: null`, the doc's path not in their `digested_into:`) that **touch** it by the structural intersection in `skills/distiller/references/docs-mode.md` Resolution 1 (provenance∩`owns` strong, entities∩declared-ownership supporting — qmd-independent). If **≥10** map to **one** doc, add one line to the report **proposing** a `distiller docs --doc <path>` run on that doc — propose only, never auto-run, no cron. Declined or ignored ⇒ the count keeps growing and the proposal reappears next pass; that recurrence *is* the dedupe, so never backlog the proposal.
97
+ 4. **Inbox-distillation threshold.** Count undigested inbox entries — `## ` entry blocks across `docs/memory/inbox/*.md` (the inbox is consume-on-digest, so every block present is undigested). If the count is **≥5**, add one line to the report **proposing** a `distiller` `facts` run — propose only, never auto-run, no cron. If the user declines or ignores it, do nothing: the count keeps growing and the proposal reappears next pass — that recurrence _is_ the dedupe, so never backlog it.
98
+ 5. **Docs-distillation threshold.** Per target doc, count undigested fact-cards (`invalid_from: null`, the doc's path not in their `digested_into:`) that **touch** it by the structural intersection in `skills/distiller/references/docs-mode.md` Resolution 1 (provenance∩`owns` strong, entities∩declared-ownership supporting — qmd-independent). If **≥10** map to **one** doc, add one line to the report **proposing** a `distiller docs --doc <path>` run on that doc — propose only, never auto-run, no cron. Declined or ignored ⇒ the count keeps growing and the proposal reappears next pass; that recurrence _is_ the dedupe, so never backlog the proposal.
92
99
 
93
100
  ## Step 8: Refresh Index (Optional)
94
101
 
@@ -143,17 +143,20 @@ grep -rn "Icons\[" src/ --include="*.jsx" --include="*.tsx"
143
143
  Scan for React performance issues:
144
144
 
145
145
  ### Missing memoization
146
+
146
147
  - Components rendering large lists without `React.memo`
147
148
  - Expensive computations without `useMemo`
148
149
  - Callback props without `useCallback` causing child re-renders
149
150
  - Focus on components in tables, lists, grids, repeated rows
150
151
 
151
152
  ### Request waterfalls
153
+
152
154
  - Sequential `await` calls that could be `Promise.all`
153
155
  - `useEffect` chains where one fetch triggers another
154
156
  - Component trees where parent fetches block child renders
155
157
 
156
158
  ### Missing virtualization
159
+
157
160
  - Lists rendering >50 items without react-window or similar
158
161
  - Tables with unbounded row counts
159
162
  - Grids without lazy loading
@@ -183,6 +186,7 @@ grep -rn "TODO\|FIXME\|HACK\|XXX" src/ --include="*.jsx" --include="*.tsx" --inc
183
186
  ### Report format
184
187
 
185
188
  **Dependencies**
189
+
186
190
  - **Vulnerabilities**: critical/high CVEs, new since last audit
187
191
  - **Outdated**: top outdated packages by semver distance
188
192
  - **Licenses**: non-permissive license flags
@@ -191,6 +195,7 @@ grep -rn "TODO\|FIXME\|HACK\|XXX" src/ --include="*.jsx" --include="*.tsx" --inc
191
195
  - **Dependency size**: largest installed packages
192
196
 
193
197
  **Code**
198
+
194
199
  - **Bundle size**: total vendor size, top offenders, growth since last review
195
200
  - **Tree-shaking issues**: namespace imports, barrel-file problems (cross-referenced with the heavy/bloat packages from Part A)
196
201
  - **Performance**: missing memoization, request waterfalls, missing virtualization
@@ -8,5 +8,5 @@
8
8
  ".prettierignore",
9
9
  ".vscode/settings.json"
10
10
  ],
11
- "digest": "a897772819ce"
11
+ "digest": "3a6fb5194539"
12
12
  }
@@ -10,40 +10,40 @@
10
10
 
11
11
  No alternatives. Just use these.
12
12
 
13
- | Package | Version | Use | Don't use |
14
- | ------------------------ | --------- | ---------------------- | ----------------------- |
15
- | react | ^19.2.3 | UI components | - |
16
- | vite | ^8.0.0 | Build tool, dev server | webpack, CRA |
17
- | tailwindcss | ^4.1.18 | Styling | styled-components |
18
- | @vitejs/plugin-react-swc | ^4.2.2 | JSX compilation | @vitejs/plugin-react |
19
- | react-router-dom | ^7.11.0 | Routing | - |
20
- | @reduxjs/toolkit | ^2.11.2 | State management | zustand, jotai |
21
- | react-redux | ^9.2.0 | Redux React bindings | - |
22
- | axios | ^1.13.2 | HTTP requests | fetch |
23
- | date-fns | ^4.1.0 | Date formatting | moment, dayjs |
24
- | @dnd-kit/core | ^6.3.1 | Drag and drop | react-beautiful-dnd |
25
- | motion | ^12.23.26 | Animations | react-spring |
26
- | sonner | ^2.0.7 | Toast notifications | react-toastify |
27
- | react-window | ^2.2.3 | List virtualization | react-virtualized |
28
- | nanoid | ^5.1.6 | ID generation | uuid |
29
- | express | ^5.2.1 | HTTP server | fastify, koa |
30
- | drizzle-orm | latest | Database ORM | prisma, sequelize, typeorm |
31
- | drizzle-kit | latest | Schema tooling | - |
32
- | zod | ^4.2.1 | Schema validation | yup, joi |
33
- | jose | ^6.1.3 | JWT handling | jsonwebtoken |
34
- | microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
35
- | react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
36
- | @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
37
- | shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
38
- | lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
39
- | @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
40
- | cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
41
- | @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
42
- | localforage | ^1.10.0 | Client-side storage | idb, dexie |
43
- | react-markdown | ^10.1.0 | Markdown rendering | marked, markdown-it |
44
- | fast-deep-equal | ^3.1.3 | Deep equality checks | lodash.isEqual |
45
- | @ngneat/falso | latest | Fake data generation | @faker-js/faker, chance |
46
- | pino | ^10.1.0 | Logging | winston |
13
+ | Package | Version | Use | Don't use |
14
+ | --- | --- | --- | --- |
15
+ | react | ^19.2.3 | UI components | - |
16
+ | vite | ^8.0.0 | Build tool, dev server | webpack, CRA |
17
+ | tailwindcss | ^4.1.18 | Styling | styled-components |
18
+ | @vitejs/plugin-react-swc | ^4.2.2 | JSX compilation | @vitejs/plugin-react |
19
+ | react-router-dom | ^7.11.0 | Routing | - |
20
+ | @reduxjs/toolkit | ^2.11.2 | State management | zustand, jotai |
21
+ | react-redux | ^9.2.0 | Redux React bindings | - |
22
+ | axios | ^1.13.2 | HTTP requests | fetch |
23
+ | date-fns | ^4.1.0 | Date formatting | moment, dayjs |
24
+ | @dnd-kit/core | ^6.3.1 | Drag and drop | react-beautiful-dnd |
25
+ | motion | ^12.23.26 | Animations | react-spring |
26
+ | sonner | ^2.0.7 | Toast notifications | react-toastify |
27
+ | react-window | ^2.2.3 | List virtualization | react-virtualized |
28
+ | nanoid | ^5.1.6 | ID generation | uuid |
29
+ | express | ^5.2.1 | HTTP server | fastify, koa |
30
+ | drizzle-orm | latest | Database ORM | prisma, sequelize, typeorm |
31
+ | drizzle-kit | latest | Schema tooling | - |
32
+ | zod | ^4.2.1 | Schema validation | yup, joi |
33
+ | jose | ^6.1.3 | JWT handling | jsonwebtoken |
34
+ | microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
35
+ | react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
36
+ | @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
37
+ | shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
38
+ | lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
39
+ | @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
40
+ | cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
41
+ | @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
42
+ | localforage | ^1.10.0 | Client-side storage | idb, dexie |
43
+ | react-markdown | ^10.1.0 | Markdown rendering | marked, markdown-it |
44
+ | fast-deep-equal | ^3.1.3 | Deep equality checks | lodash.isEqual |
45
+ | @ngneat/falso | latest | Fake data generation | @faker-js/faker, chance |
46
+ | pino | ^10.1.0 | Logging | winston |
47
47
 
48
48
  ## Frontend
49
49
 
@@ -51,7 +51,7 @@ Tailwind v4 + shadcn-based UI; conventions below.
51
51
 
52
52
  - **@nurix/components** — the UI component library (linked, pre-built); import by subpath, e.g. `@nurix/components/button`.
53
53
  - No components.json / shadcn CLI scaffold (.tsx, not .jsx) — consume the prebuilt library; never `npx shadcn add`.
54
- - 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` (linked @nurix/* ship nested react — keep one hook dispatcher).
54
+ - 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` (linked @nurix/\* ship nested react — keep one hook dispatcher).
55
55
  - Tailwind v4, CSS-only (no tailwind.config.js, no PostCSS): styling runs through the `@tailwindcss/vite` plugin.
56
56
  - CSS entry `globals.css`, imports in order — `@import "./personality.css"` (token source) → `@import "tailwindcss"` → the library's `styles.css` — then `@theme inline {…}` mapping vars to tokens.
57
57
  - Tokens: CSS vars in `:root, :root[data-theme="light"]` + the archetype selector `[data-style="…"]` (personality.css), consumed as semantic Tailwind tokens (bg-card, text-foreground). Honor the archetype's radius/theme decisions (e.g. re-assert `--radius-*` to 0 for a flat archetype; add `@custom-variant dark` only if the project supports dark mode). The library bundles class-variance-authority, clsx, tailwind-merge.
@@ -71,7 +71,11 @@ app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
71
71
  ## API Response Format
72
72
 
73
73
  ```json
74
- { "status": 1, "message": "Message sent successfully", "data": { "delivered": [{ "user@example.com": 2 }] } }
74
+ {
75
+ "status": 1,
76
+ "message": "Message sent successfully",
77
+ "data": { "delivered": [{ "user@example.com": 2 }] }
78
+ }
75
79
  ```
76
80
 
77
81
  Error: `{ "status": 0, "message": "Error description", "data": null }`
@@ -7,45 +7,21 @@ description: Boundary diagnostic for implementation plans. Given a plan file, re
7
7
 
8
8
  You diagnose whether a plan's changes would break an application boundary.
9
9
 
10
- A boundary is a contract between two pieces of code (or code and infra) that
11
- share an assumption with **no compile-time link** between them: the column a raw
12
- SQL string names, the JSON envelope a client unwraps, the event string a
13
- dispatcher parses, the env var a deploy script writes. Changing one side ships
14
- green and breaks the other silently. Your job is to find those edges in the
15
- plan's path *before* execution.
16
-
17
- [`references/boundary-taxonomy.md`](references/boundary-taxonomy.md) is the
18
- catalog of boundary types (~170 across persistence, wire/API, frontend,
19
- auth/tenancy, async/messaging, config/build, runtime/infra), with per-type
20
- severities and safe-change checklists. Read it first — it tells you what to
21
- look for; the code tells you what exists.
10
+ A boundary is a contract between two pieces of code (or code and infra) that share an assumption with **no compile-time link** between them: the column a raw SQL string names, the JSON envelope a client unwraps, the event string a dispatcher parses, the env var a deploy script writes. Changing one side ships green and breaks the other silently. Your job is to find those edges in the plan's path _before_ execution.
11
+
12
+ [`references/boundary-taxonomy.md`](references/boundary-taxonomy.md) is the catalog of boundary types (~170 across persistence, wire/API, frontend, auth/tenancy, async/messaging, config/build, runtime/infra), with per-type severities and safe-change checklists. Read it first — it tells you what to look for; the code tells you what exists.
22
13
 
23
14
  ## Run
24
15
 
25
- **Input:** a plan path (given, or the newest in `docs/history/plans/`) — or a
26
- diff / named code area for non-plan work. Everything below is identical either
27
- way; a diff's hunks stand in for the plan's steps.
28
-
29
- 1. **Build the touch list.** Parse the plan's Proposed Changes: files to be
30
- created or modified, entities/state added or changed, API changes, anything
31
- the author flags as a cross-module contract. Note missing subsections.
32
-
33
- 2. **Identify the boundaries in the touched code.** Read each touched file (and
34
- its immediate imports). Against the taxonomy, list the contracts this code
35
- participates in — the schema it queries, the envelope it emits, the events
36
- it publishes or parses, the auth checks it sits behind, the env it reads.
37
-
38
- 3. **Trace the other side.** A boundary has two sides; the danger lives on the
39
- one the plan *doesn't* mention. For each contract, grep the shared name or
40
- shape across the repo — the column name in other SQL strings, the response
41
- field in client unwrappers, the event kind in subscribers, the route in
42
- fetch calls and scripts, the env key in deploy tooling. Record consumers as
43
- `file:line`.
44
-
45
- 4. **Judge each intersection.** Does the planned change alter a shape a traced
46
- consumer depends on, break an invariant the code establishes (append-only
47
- vocabularies, idempotency keys, fail-closed checks, ordering guarantees), or
48
- add a new cross-module edge? Severity:
16
+ **Input:** a plan path (given, or the newest in `docs/history/plans/`) — or a diff / named code area for non-plan work. Everything below is identical either way; a diff's hunks stand in for the plan's steps.
17
+
18
+ 1. **Build the touch list.** Parse the plan's Proposed Changes: files to be created or modified, entities/state added or changed, API changes, anything the author flags as a cross-module contract. Note missing subsections.
19
+
20
+ 2. **Identify the boundaries in the touched code.** Read each touched file (and its immediate imports). Against the taxonomy, list the contracts this code participates in — the schema it queries, the envelope it emits, the events it publishes or parses, the auth checks it sits behind, the env it reads.
21
+
22
+ 3. **Trace the other side.** A boundary has two sides; the danger lives on the one the plan _doesn't_ mention. For each contract, grep the shared name or shape across the repo — the column name in other SQL strings, the response field in client unwrappers, the event kind in subscribers, the route in fetch calls and scripts, the env key in deploy tooling. Record consumers as `file:line`.
23
+
24
+ 4. **Judge each intersection.** Does the planned change alter a shape a traced consumer depends on, break an invariant the code establishes (append-only vocabularies, idempotency keys, fail-closed checks, ordering guarantees), or add a new cross-module edge? Severity:
49
25
  - **CRITICAL** — can corrupt persisted data, or open an auth/money path.
50
26
  - **HIGH** — silent cross-module breakage that would ship green.
51
27
  - **MEDIUM** — drift-prone coupling (string-matched, duplicated constants).
@@ -67,10 +43,7 @@ way; a diff's hunks stand in for the plan's steps.
67
43
 
68
44
  ## Rules
69
45
 
70
- - **Read-only.** You never edit the plan, the code, or any doc. The user folds
71
- your amendments into the plan.
72
- - **Verify in source.** Never flag from plan text alone — read both sides of
73
- every boundary you report, and cite both as `file:line`.
74
- - **No consumer, no finding.** An intersection with no traced other side isn't
75
- a violation; at most note it as a new edge the plan introduces.
46
+ - **Read-only.** You never edit the plan, the code, or any doc. The user folds your amendments into the plan.
47
+ - **Verify in source.** Never flag from plan text alone — read both sides of every boundary you report, and cite both as `file:line`.
48
+ - **No consumer, no finding.** An intersection with no traced other side isn't a violation; at most note it as a new edge the plan introduces.
76
49
  - **A clean report is valid.** Zero violations means say so — don't pad.