@nurix/etna 0.16.0 → 0.17.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.
- package/bin/etna.js +148 -67
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/.prettierignore +12 -0
- package/data/harnesses/code/.prettierrc.json +3 -0
- package/data/harnesses/code/.vscode/settings.json +10 -0
- package/data/harnesses/code/CLAUDE.md +5 -8
- package/data/harnesses/code/agents/change-review.md +13 -14
- package/data/harnesses/code/agents/harness-manager.md +14 -26
- package/data/harnesses/code/agents/maintenance.md +10 -18
- package/data/harnesses/code/harness.json +8 -3
- package/data/harnesses/code/hooks/hooks.json +2 -2
- package/data/harnesses/code/hooks/lib/{redact.js → redact.mjs} +2 -4
- package/data/harnesses/{code-fable/hooks/prompt-recall.js → code/hooks/prompt-recall.mjs} +5 -7
- package/data/harnesses/{code-fable/hooks/session-reflect.js → code/hooks/session-reflect.mjs} +9 -7
- package/data/harnesses/code/rules/general.md +23 -40
- package/data/harnesses/code/rules/nomenclature.md +0 -4
- package/data/harnesses/code/rules/typescript.md +19 -0
- package/data/harnesses/code/skills/boundary/SKILL.md +53 -239
- package/data/harnesses/code/skills/brainstorm/harvest.md +2 -2
- package/data/harnesses/code/skills/documentation/SKILL.md +2 -4
- package/data/harnesses/code/skills/documentation/references/templates.md +12 -89
- package/data/harnesses/code-fable/.prettierignore +12 -0
- package/data/harnesses/code-fable/.prettierrc.json +3 -0
- package/data/harnesses/code-fable/.vscode/settings.json +10 -0
- package/data/harnesses/code-fable/CLAUDE.md +5 -8
- package/data/harnesses/code-fable/agents/change-review.md +13 -14
- package/data/harnesses/code-fable/agents/harness-manager.md +14 -26
- package/data/harnesses/code-fable/agents/maintenance.md +10 -18
- package/data/harnesses/code-fable/harness.json +8 -3
- package/data/harnesses/code-fable/hooks/hooks.json +2 -2
- package/data/harnesses/code-fable/hooks/lib/{redact.js → redact.mjs} +2 -4
- package/data/harnesses/{code/hooks/prompt-recall.js → code-fable/hooks/prompt-recall.mjs} +5 -7
- package/data/harnesses/{code/hooks/session-reflect.js → code-fable/hooks/session-reflect.mjs} +9 -7
- package/data/harnesses/code-fable/rules/general.md +23 -40
- package/data/harnesses/code-fable/rules/nomenclature.md +0 -4
- package/data/harnesses/code-fable/rules/typescript.md +19 -0
- package/data/harnesses/code-fable/skills/boundary/SKILL.md +53 -239
- package/data/harnesses/code-fable/skills/brainstorm/harvest.md +2 -2
- package/data/harnesses/code-fable/skills/documentation/SKILL.md +2 -4
- package/data/harnesses/code-fable/skills/documentation/references/templates.md +12 -89
- package/data/harnesses/discover/.prettierignore +12 -0
- package/data/harnesses/discover/.prettierrc.json +3 -0
- package/data/harnesses/discover/.vscode/settings.json +10 -0
- package/data/harnesses/discover/harness.json +6 -1
- package/data/harnesses/discover/rules/evaluation.md +13 -1
- package/data/harnesses/discover/rules/ingestion.md +15 -0
- package/data/harnesses/discover/rules/tradecraft.md +13 -0
- package/data/harnesses/hr/.prettierignore +12 -0
- package/data/harnesses/hr/.prettierrc.json +3 -0
- package/data/harnesses/hr/.vscode/settings.json +10 -0
- package/data/harnesses/hr/harness.json +6 -1
- package/data/harnesses/kb-agi/.prettierignore +12 -0
- package/data/harnesses/kb-agi/.prettierrc.json +3 -0
- package/data/harnesses/kb-agi/.vscode/settings.json +10 -0
- package/data/harnesses/kb-agi/harness.json +6 -1
- package/package.json +4 -1
|
@@ -4,12 +4,12 @@ Harvest is **optional and offered, never assumed**. By default the session folde
|
|
|
4
4
|
|
|
5
5
|
## Routing
|
|
6
6
|
|
|
7
|
-
The harvest is a structured diff between the session pillars and the live docs, routed by scope: module-local findings → `docs/modules/{m}/pillars/`, cross-module
|
|
7
|
+
The harvest is a structured diff between the session pillars and the live docs, routed by scope: module-local findings → `docs/modules/{m}/pillars/`, cross-module + IA/contract changes → `docs/architecture/`, backlog → `docs/history/`.
|
|
8
8
|
|
|
9
9
|
| Session source | Destination |
|
|
10
10
|
|---|---|
|
|
11
11
|
| `thesis.md` narrative | `docs/history/plans/YYYY-MM-DD-{slug}.md` (Status: Draft, `documentation` skill §8 Plan template) |
|
|
12
|
-
| `domain-model.md` | `docs/architecture/domain-model.md`; if it changes the IA or a cross-cutting contract,
|
|
12
|
+
| `domain-model.md` | `docs/architecture/domain-model.md`; if it changes the IA or a cross-cutting contract, note the contract change there — the `boundary` skill will pick it up from source at the next plan check |
|
|
13
13
|
| Decisions spanning 2+ modules | one ADR per cohesive theme → `docs/architecture/adr/ADR-NNN-{slug}.md`, authored to the **`documentation` skill §10 ADR template** (frontmatter `status:` is the lifecycle source of truth — no body Status line; required sections Decision/Context/Consequences); rejected alternatives → the ADR's **Options Considered** table |
|
|
14
14
|
| Module-local decisions / doctrine / glossary / rejected | `docs/modules/{m}/pillars/{decisions,doctrine,glossary,rejected}.md` |
|
|
15
15
|
| Cross-module doctrine / glossary | `docs/architecture/domain-model.md` / `docs/architecture/glossary.md` |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: documentation
|
|
3
|
-
description: Template & generator library for technical docs — the skill agents call to produce a doc from a template. Use to (1) document a feature or module, (2) create or update a changelog entry, (3) document data flows or Redux state, (4) add to protected files, (5)
|
|
3
|
+
description: Template & generator library for technical docs — the skill agents call to produce a doc from a template. Use to (1) document a feature or module, (2) create or update a changelog entry, (3) document data flows or Redux state, (4) add to protected files, (5) record an architecture decision (ADR), (6) create or update the project root README, (7) create or update a plan, (8) derive ownership frontmatter (`owns`/`touches`/`depends_on`) from code, (9) scaffold a standard doc (README, structure.md, CHANGELOG, backlog, memory) from its template, or (10) co-author any technical doc. Baselining / reconciling a repo's docs to the installed harness version is the **`harness-manager` agent** (which calls this skill for each template) — this skill does not orchestrate baseline. Triggers on "document this", "create docs", "update changelog", "add to protected files", "ADR", "architecture decision", "root README", "plan", "feature doc".
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Technical Documentation Skill
|
|
@@ -30,8 +30,6 @@ User request
|
|
|
30
30
|
│
|
|
31
31
|
├─ "Add to protected files" ───────▶ Protected Files Template
|
|
32
32
|
│
|
|
33
|
-
├─ "Create/update a boundary" ─────▶ boundary skill (this skill holds only the boundary-file template)
|
|
34
|
-
│
|
|
35
33
|
├─ "Record architecture decision" ─▶ ADR Template
|
|
36
34
|
│
|
|
37
35
|
├─ "Create/update root README" ────▶ Project Root README Template
|
|
@@ -122,6 +120,6 @@ For docs that don't match templates:
|
|
|
122
120
|
|
|
123
121
|
| File | Use For |
|
|
124
122
|
|------|---------|
|
|
125
|
-
| `references/templates.md` | docs/README.md, structure.md, frontmatter, scaffolds (CHANGELOG, backlog, memory),
|
|
123
|
+
| `references/templates.md` | docs/README.md, structure.md, frontmatter, scaffolds (CHANGELOG, backlog, memory), feature, changelog, plan, protected files, ADR, project root README templates |
|
|
126
124
|
| `references/style-guide.md` | Writing rules, formatting conventions |
|
|
127
125
|
| `references/examples.md` | Good vs bad documentation examples |
|
|
@@ -93,7 +93,6 @@ Each topic has one canonical location. Read from here, not from plans or changel
|
|
|
93
93
|
| ----- | --------- | --------- |
|
|
94
94
|
| System architecture + steering | `docs/architecture/` | domain-model, glossary, non-goals, references, adr/ |
|
|
95
95
|
| Feature behavior | `docs/features/` (or `docs/modules/{m}/features/`) | {key files} |
|
|
96
|
-
| Cross-module contracts | `docs/boundaries/` | one file per boundary (maintained by the `boundary` skill) |
|
|
97
96
|
| Declared modules (bounded contexts) | `docs/modules/{m}/` | `features/` + `pillars/` |
|
|
98
97
|
| Setup & development | `docs/operations/` | {key files} |
|
|
99
98
|
| Historical plans | `docs/history/plans/` | YYYY-MM-DD-name.md |
|
|
@@ -112,7 +111,6 @@ Plan (Status: Draft) → Implementation → Feature Doc or Architecture Update
|
|
|
112
111
|
|
|
113
112
|
- `docs/features/`: Living reference for implemented features. Each spec includes YAML frontmatter with `owns`, `touches`, `depends_on` fields declaring code ownership.
|
|
114
113
|
- `docs/architecture/`: System-wide patterns and the cross-module steering layer (domain model, glossary, non-goals, references, ADRs). Update when cross-cutting concerns change.
|
|
115
|
-
- `docs/boundaries/`: Horizontal typed application boundaries — one file per cross-module contract. Generated/maintained by the `boundary` skill; read before touching a shape it defines.
|
|
116
114
|
- `docs/modules/{m}/`: Vertical bounded contexts, **declared** (not inferred from layout) and tied to code by their `owns` globs. Each owns `features/` + module-local `pillars/` (doctrine, lazy). There is no repo-wide `docs/pillars/`. Worth declaring at ≥2 genuine bounded contexts; a single-context app stays flat under `docs/features/`.
|
|
117
115
|
- `docs/operations/`: How-to procedures for setup, development, and deployment. Update when workflows change.
|
|
118
116
|
- `docs/history/plans/`: Historical. Must have `Status:` field. Never modify after completion.
|
|
@@ -150,7 +148,7 @@ anchors:
|
|
|
150
148
|
- `owns`: Glob patterns for files this feature doc is the canonical reference for
|
|
151
149
|
- `touches`: Files this feature interacts with but doesn't own
|
|
152
150
|
- `depends_on`: Other docs that must be read for full context
|
|
153
|
-
- `anchors` (optional): A list of qmd queries (or `#docid`s) that re-resolve to the code/facts this doc abstracts as they move; anchors are retrieval context plus a drift tripwire, never a contract — an anchor that returns nothing IS the drift signal, nothing auto-rewrites from an anchor result, and the doc's prose stays the human-owned abstraction. They detect **doc-area drift** (the subject moving or vanishing from the corpus), not a pure code rename — the query also matches the doc's own prose, so a rename that leaves the text unchanged won't shift the result; code-symbol drift is the maintenance named-referent check's job, and anchors complement it rather than replace it. Resolved via `qmd query --format json -c <collection>` against this repo's collections; absent qmd ⇒ anchors are inert (no error). Never required on any doc. The feature
|
|
151
|
+
- `anchors` (optional): A list of qmd queries (or `#docid`s) that re-resolve to the code/facts this doc abstracts as they move; anchors are retrieval context plus a drift tripwire, never a contract — an anchor that returns nothing IS the drift signal, nothing auto-rewrites from an anchor result, and the doc's prose stays the human-owned abstraction. They detect **doc-area drift** (the subject moving or vanishing from the corpus), not a pure code rename — the query also matches the doc's own prose, so a rename that leaves the text unchanged won't shift the result; code-symbol drift is the maintenance named-referent check's job, and anchors complement it rather than replace it. Resolved via `qmd query --format json -c <collection>` against this repo's collections; absent qmd ⇒ anchors are inert (no error). Never required on any doc. The feature template ships the exemplar, but `anchors:` may appear on any living doc the maintenance anchor-drift check globs — `docs/features/`, `docs/architecture/`, and `docs/operations/` — so the convention and the check stay one mental model.
|
|
154
152
|
|
|
155
153
|
---
|
|
156
154
|
|
|
@@ -243,7 +241,7 @@ description: Shared knowledge accumulated across agent sessions. All agents shou
|
|
|
243
241
|
## Documentation Baseline
|
|
244
242
|
|
|
245
243
|
- **Baselined:** {today}
|
|
246
|
-
- **Structure:** v{harness-version} (architecture, features, operations, history, memory; +
|
|
244
|
+
- **Structure:** v{harness-version} (architecture, features, operations, history, memory; + modules/, tests/ when present)
|
|
247
245
|
- **Spec version:** v{harness-version}
|
|
248
246
|
<!-- v{harness-version} resolves to the installed design epoch — read it from `.claude/harness.json` (`epoch`) / `docs/structure.md` frontmatter (`harness-version`); never hardcode a literal version here. -->
|
|
249
247
|
|
|
@@ -284,86 +282,11 @@ Append entries below, oldest at bottom. Format:
|
|
|
284
282
|
Memory file initialized during documentation baseline.
|
|
285
283
|
```
|
|
286
284
|
|
|
287
|
-
> The per-actor memory **inbox** (`docs/memory/inbox/`) is *not* a baseline scaffold — the `session-reflect` hook creates it mechanically on the first reflected session. See **§
|
|
285
|
+
> The per-actor memory **inbox** (`docs/memory/inbox/`) is *not* a baseline scaffold — the `session-reflect` hook creates it mechanically on the first reflected session. See **§11 Memory inbox entry** for its format.
|
|
288
286
|
|
|
289
287
|
---
|
|
290
288
|
|
|
291
|
-
## 5.
|
|
292
|
-
|
|
293
|
-
> **This skill does not generate boundaries.** Typed-boundary generation is owned by the **`boundary`** skill (`generate` mode), which detects the stack + IA and applies its boundary taxonomy (`references/boundary-taxonomy.md`) to emit typed files. The baseline does **not** scaffold `docs/boundaries/` — `/boundary generate` runs right after the baseline ("baseline boundaries"). This section is the generic **boundary-file template** plus the guidance for *recognizing* what deserves a boundary.
|
|
294
|
-
|
|
295
|
-
### What deserves a boundary
|
|
296
|
-
|
|
297
|
-
A boundary is a **horizontal, cross-module contract** where the failure is silent and crosses module boundaries — the developer in module A has no reason to know module B will break. No import error, no runtime exception — just wrong behavior.
|
|
298
|
-
|
|
299
|
-
Test: "If an agent edits this while working on a single feature, could it silently break something in a different feature?" If yes, it's a boundary.
|
|
300
|
-
|
|
301
|
-
**Include:**
|
|
302
|
-
|
|
303
|
-
- **Shared state shapes** — Redux store slices, persisted state, global context. Any shape that multiple modules read. Document every key, its type, and what reads it. Call out which slices are persisted and how rehydration handles shape changes (e.g., new fields become `undefined` for existing users).
|
|
304
|
-
- **Entity registration checklists** — When adding a new entity/resource type requires touching N files across N modules to avoid silent data loss. List every file and what breaks if skipped.
|
|
305
|
-
- **Cross-entity references by value** — When entity A stores entity B's identifier (slug, name, ID) as a plain value with no referential integrity. Document which fields reference what, and that renaming the target never propagates to the source.
|
|
306
|
-
- **Format contracts** — When two systems produce identifiers in different formats (e.g., server returns `[a-z0-9]+`, client generates `[a-z0-9_]+`). Document both formats, where each is used, and what breaks on mismatch (e.g., lookup by key returns `undefined`, key-splitting logic produces wrong matches).
|
|
307
|
-
- **Cross-module string coupling** — Action types, event names, status enums, or document type strings referenced by raw string literal instead of imported constant. List every file that hard-codes the string and what breaks if the source is renamed.
|
|
308
|
-
- **Pipeline ordering dependencies** — Multi-step pipelines where Step N assumes Step N-1 has already written data to shared state. Document the implicit dependency and what happens if ordering changes (silent quality degradation vs. hard failure vs. hang).
|
|
309
|
-
- **Completion signal contracts** — When modules communicate via return values, status fields, or Redux state transitions. Document the expected shape/type (e.g., `Promise<boolean>`, status enum values) and what happens if the contract changes (e.g., returning `undefined` instead of `true` causes permanent "failed" status).
|
|
310
|
-
- **Host/plugin contracts** — Config objects consumed by a framework/host where some fields are validated and others aren't. Document which fields are unvalidated and what breaks silently if they change.
|
|
311
|
-
- **Persistence shape safety** — How the persistence layer handles schema evolution. Document what happens when you add, remove, or rename a field in persisted state (e.g., no migration → stale data, new fields default to `undefined`).
|
|
312
|
-
|
|
313
|
-
**Exclude:**
|
|
314
|
-
|
|
315
|
-
- Module-internal architecture (well-encapsulated, no cross-module blast radius)
|
|
316
|
-
- Authentication/authorization flows (behind adapters, feature code doesn't touch them)
|
|
317
|
-
- Hook taxonomies and API reference (useful docs, but not boundaries — they don't cause cascading failures)
|
|
318
|
-
- Networking details (WebSocket, HTTP client setup) — unless the event routing has cross-module string coupling
|
|
319
|
-
- Feature folder conventions and code style (conventions, not breakage vectors)
|
|
320
|
-
- Anything where failure produces an import error, a clear runtime exception, or a visible UI error — those are self-diagnosing and don't need a boundary
|
|
321
|
-
|
|
322
|
-
### How to research a boundary
|
|
323
|
-
|
|
324
|
-
When mapping a boundary (the `boundary` skill's `generate`/`create` job — this guidance is shared), investigate:
|
|
325
|
-
|
|
326
|
-
1. **Shared state consumers** — For each Redux slice/context, find all files that read from it. Flag any file reading a slice it doesn't own (cross-module dependency).
|
|
327
|
-
2. **String-coupled actions** — Grep for Redux action type strings referenced as raw strings rather than imported constants. These are invisible breakage points.
|
|
328
|
-
3. **Entity lifecycle** — For each entity type, trace the full lifecycle: creation → change tracking → save payload → API → server. Identify every file that must be touched to support a new entity type.
|
|
329
|
-
4. **Identifier format mismatches** — Compare how identifiers are generated (server vs. client) and how they're used as keys. Look for format divergence.
|
|
330
|
-
5. **Pipeline data dependencies** — For multi-step processes, check what each step reads from shared state and what previous step wrote it. Test: "If I reorder these steps, does it fail loudly or silently?"
|
|
331
|
-
6. **Persistence rehydration** — Check what reconciler is used, whether transforms exist, and what happens to existing users when a persisted shape changes.
|
|
332
|
-
|
|
333
|
-
### Generic boundary-file template
|
|
334
|
-
|
|
335
|
-
One file per boundary in `docs/boundaries/`. The `boundary` skill emits typed files using its boundary taxonomy; this is the generic fallback shape.
|
|
336
|
-
|
|
337
|
-
```markdown
|
|
338
|
-
---
|
|
339
|
-
anchors: # optional — see §3 frontmatter reference
|
|
340
|
-
- "qmd query: store slice rehydration fallback"
|
|
341
|
-
---
|
|
342
|
-
|
|
343
|
-
# {Boundary Name}
|
|
344
|
-
|
|
345
|
-
[BOUNDARY: {type} · {severity}] <!-- type from the Application Boundary Scale; severity CRITICAL | HIGH | MED | LOW -->
|
|
346
|
-
|
|
347
|
-
**Bounds:** {module A} ↔ {module B} <!-- which modules sit on each side -->
|
|
348
|
-
|
|
349
|
-
## Shape
|
|
350
|
-
<!-- `transcribe`: a synthesized contract with no single code home (composed store tree, API envelope, the IA entity model, tenancy) — written inline, canonical here.
|
|
351
|
-
`point`: a self-locating shape (DB schema, route table) — a `file:line` pointer + invariants. Never copy a self-locating shape; it rots on the next change.
|
|
352
|
-
greenfield/pre-code `point` (contract decided, no code yet — e.g. boundary generate after a brainstorm): there's no file:line to point at, so instead (a) record the decided conventions inline here, (b) add a `planned <path>` line naming where the canonical source will land (e.g. `planned packages/api/src/db/schema.ts`), and (c) mark this row `point*` in the README index. Converts to (or gains) a real file:line pointer when the module lands. README index footnote: "* point-mode boundary whose pointer lands at implementation". -->
|
|
353
|
-
|
|
354
|
-
## Invariants
|
|
355
|
-
<!-- The rules that must hold across the boundary. -->
|
|
356
|
-
|
|
357
|
-
## Blast radius
|
|
358
|
-
<!-- What breaks, and where, if an invariant is violated. -->
|
|
359
|
-
|
|
360
|
-
## Safe-change checklist
|
|
361
|
-
<!-- Ordered steps to change this contract without silent breakage. Mark steps that fail silently if skipped. -->
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## 6. Feature Documentation (docs/features/{feature}.md)
|
|
289
|
+
## 5. Feature Documentation (docs/features/{feature}.md)
|
|
367
290
|
|
|
368
291
|
Use for: every feature in `docs/features/`. The same file persists from design (Status: Draft) through implementation to live reference (Status: Active). Sections fill in as the feature matures — no template swap.
|
|
369
292
|
|
|
@@ -514,7 +437,7 @@ Resolved Open Questions can be summarized into Background; unresolved ones stay
|
|
|
514
437
|
|
|
515
438
|
---
|
|
516
439
|
|
|
517
|
-
##
|
|
440
|
+
## 6. Changelog
|
|
518
441
|
|
|
519
442
|
Use for: recording code changes with function-level detail.
|
|
520
443
|
|
|
@@ -563,11 +486,11 @@ Brief description of what changed and why.
|
|
|
563
486
|
|
|
564
487
|
---
|
|
565
488
|
|
|
566
|
-
##
|
|
489
|
+
## 7. Plan (docs/history/plans/YYYY-MM-DD-feature-name.md)
|
|
567
490
|
|
|
568
491
|
Use for: every implementation plan. Plans are created here directly with `Status: Draft`, flip to `Status: In Progress` when work starts, and freeze at `Status: Complete` or `Status: Abandoned`. Once frozen, never edit — write a new dated plan if scope changes.
|
|
569
492
|
|
|
570
|
-
The `boundary` skill
|
|
493
|
+
The `boundary` skill parses the **Proposed Changes** sections to check boundary impact before execution. Keep that structure stable — section headings and bullet shape are load-bearing for the parser.
|
|
571
494
|
|
|
572
495
|
```
|
|
573
496
|
# {Feature Name}
|
|
@@ -603,7 +526,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
603
526
|
|
|
604
527
|
### Cross-Module Contracts Affected
|
|
605
528
|
|
|
606
|
-
- List which
|
|
529
|
+
- List which cross-cutting contracts this plan touches (db schema, wire envelope, auth, events, env/config, …)
|
|
607
530
|
- "None" is a valid answer and means the `boundary` check will pass cleanly
|
|
608
531
|
|
|
609
532
|
## Implementation Steps
|
|
@@ -630,7 +553,7 @@ Why this work is happening *now*. Link to the spec for *what* we're building; th
|
|
|
630
553
|
|
|
631
554
|
---
|
|
632
555
|
|
|
633
|
-
##
|
|
556
|
+
## 8. Protected Files
|
|
634
557
|
|
|
635
558
|
Use for: documenting critical files that need approval before modification.
|
|
636
559
|
|
|
@@ -675,7 +598,7 @@ path/to/another/file.js
|
|
|
675
598
|
|
|
676
599
|
---
|
|
677
600
|
|
|
678
|
-
##
|
|
601
|
+
## 9. Architecture Decision Record (ADR)
|
|
679
602
|
|
|
680
603
|
Use for: capturing a single, point-in-time architectural decision with its context, alternatives considered, and consequences. Lives in `docs/architecture/adr/`.
|
|
681
604
|
|
|
@@ -792,7 +715,7 @@ tags: [adr]
|
|
|
792
715
|
|
|
793
716
|
---
|
|
794
717
|
|
|
795
|
-
##
|
|
718
|
+
## 10. Project Root README
|
|
796
719
|
|
|
797
720
|
Use for: the human-facing entry point at the repository root (`/README.md`) — what visitors and new contributors land on. Distinct from `docs/README.md` (the agent/doc index — see §1). The two coexist; don't merge them.
|
|
798
721
|
|
|
@@ -899,7 +822,7 @@ The baseline audit **does** scaffold the project root README when missing. The r
|
|
|
899
822
|
|
|
900
823
|
---
|
|
901
824
|
|
|
902
|
-
##
|
|
825
|
+
## 11. Memory inbox entry (docs/memory/inbox/{actor}.md)
|
|
903
826
|
|
|
904
827
|
Use for: the capture tier of the knowledge gradient — the durable lessons of each session (corrections, root-caused failures, decisions with rationale, discovered constraints), reflected by the `session-reflect` hook at session end. It is the raw input to distillation: `distiller facts` digests entries into fact-cards and **consumes** them, so the file holds exactly what is undigested.
|
|
905
828
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Markdown: Prettier unwraps prose to one logical line per paragraph
|
|
3
|
+
// (see .prettierrc → proseWrap:never) on save; the editor soft-wraps for
|
|
4
|
+
// reading, so no hard line breaks get baked into the source.
|
|
5
|
+
"[markdown]": {
|
|
6
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
7
|
+
"editor.formatOnSave": true,
|
|
8
|
+
"editor.wordWrap": "on"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -9,8 +9,7 @@ This file defines how AI agents (Claude, GPT, etc.) should work on this project.
|
|
|
9
9
|
> A missing `docs/structure.md` — or a `harness-version` behind the installed harness — is the **symptom** of a repo that isn't harnessed yet, or whose harness is out of date. Don't reconcile it by hand. Drive the **reconcile chain** — you (the main session) own it, because `harness-manager` is a sub-agent that can't run skills or spawn sub-agents:
|
|
10
10
|
>
|
|
11
11
|
> 1. Invoke **`harness-manager`** (`"baseline this repo"` / `"reconcile the harness"`). It reconciles `docs/`, stamps the version, then hands back.
|
|
12
|
-
> 2. If it hands back
|
|
13
|
-
> 3. Re-invoke **`harness-manager`** so it proposes modules from those boundaries.
|
|
12
|
+
> 2. If it hands back with a follow-up (typically the module proposal), re-invoke it to finish.
|
|
14
13
|
>
|
|
15
14
|
> Then continue. Each component's internals live in the component, not here.
|
|
16
15
|
|
|
@@ -37,7 +36,7 @@ Three peer modes plus a Completion step — enter wherever the user's thinking a
|
|
|
37
36
|
| **Spec** | new feature work | `spec-mode` agent + `documentation` skill | Plan |
|
|
38
37
|
| **Plan** | a spec is approved | `documentation` skill → `docs/history/plans/YYYY-MM-DD-{slug}.md` | Completion |
|
|
39
38
|
|
|
40
|
-
On **Completion**: freeze the plan (`Status: Complete`) and flip the feature spec to `Status: Active`, extending it with how-it-works sections; then distil the plan's trail — if the memory inbox (`docs/memory/inbox/`) holds entries, run `distiller facts` (inbox→fact-cards), then `distiller docs` for the just-completed feature's doc drafts any pending deltas for approval (presented, never auto-written). The `boundary` skill
|
|
39
|
+
On **Completion**: freeze the plan (`Status: Complete`) and flip the feature spec to `Status: Active`, extending it with how-it-works sections; then distil the plan's trail — if the memory inbox (`docs/memory/inbox/`) holds entries, run `distiller facts` (inbox→fact-cards), then `distiller docs` for the just-completed feature's doc drafts any pending deltas for approval (presented, never auto-written). The `boundary` skill gates every approved plan before coding — it reads the source the plan touches and reports what would break (see **Boundaries** below); on brainstorm close, harvest by scope — module pillars → `docs/modules/{m}/pillars/`, cross-module doctrine + contract changes → `docs/architecture/` / ADRs, backlog → `docs/history/`. Open questions block close.
|
|
41
40
|
|
|
42
41
|
---
|
|
43
42
|
|
|
@@ -48,7 +47,7 @@ Before modifying code in an unfamiliar area:
|
|
|
48
47
|
1. If **[`docs/routing.md`](docs/routing.md)** exists, read it for file-pattern → module/doc/agent mapping. If it doesn't exist yet, skip.
|
|
49
48
|
2. Glob `docs/{features,modules/*/features}/**/*.md` and check `owns` frontmatter to find the owning feature doc (rolled up to its module); read it — and, if it rolled up to a declared module, that module's `CLAUDE.md` + `pillars/` — before changes.
|
|
50
49
|
3. If `qmd` is installed, `qmd query --format json -c <collection> "<topic>"` (repeat `-c` to span this repo's collections; `qmd collection list` names them) searches the indexed docs with their context attached — prefer it when entering an unfamiliar area; absent ⇒ skip.
|
|
51
|
-
4.
|
|
50
|
+
4. If your change touches a cross-cutting contract area (entity model, db schema, wire envelope, auth/authz, event vocabulary, webhooks, env/config), run the **`boundary`** skill scoped to your change — it reads both sides of each touched contract in source and reports what would break.
|
|
52
51
|
5. If a `docs/memory/` file exists for the domain you're working in, read it for domain knowledge and failure modes
|
|
53
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.
|
|
54
53
|
|
|
@@ -92,11 +91,9 @@ The spec-mode agent checks for ownership conflicts during research. If conflicts
|
|
|
92
91
|
|
|
93
92
|
## Boundaries
|
|
94
93
|
|
|
95
|
-
|
|
94
|
+
A boundary is a horizontal cross-cutting contract — entity model, db schema, wire envelope, auth/authz, event vocabulary, webhooks, env/config — where editing one side silently breaks the other. Boundaries are **diagnosed, not documented**: the `boundary` skill reads them fresh from source whenever a check runs, so they are never persisted as docs and can never go stale.
|
|
96
95
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Without `docs/boundaries/` populated (`generate`), the `check` and `init` modes have nothing to check against.
|
|
96
|
+
**Invoke the `boundary` skill after a plan is approved and before its first implementation step.** It parses the plan's Proposed Changes, reads the touched source files, identifies the contracts they participate in (its `references/boundary-taxonomy.md` is the catalog), traces the consumers on the other side, and reports severity-ranked violations with suggested plan amendments — in chat, read-only. Fold the amendments into the plan before coding. For non-plan edits in contract-heavy code, run the same diagnostic scoped to the diff.
|
|
100
97
|
|
|
101
98
|
> Agents and skills live under `.claude/agents/` and `.claude/skills/`. Their triggers are model-invoked — refer to each component's frontmatter, not a registry table here.
|
|
102
99
|
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: change-review
|
|
3
|
-
description: Velocity + change-risk analysis. First classifies recent commits into a pipe-delimited velocity/severity CSV by dispatching parallel haiku sub-agents (module, feature, impact, severity, churn), then derives a commit heatmap, risk zones (high churn
|
|
3
|
+
description: Velocity + change-risk analysis. First classifies recent commits into a pipe-delimited velocity/severity CSV by dispatching parallel haiku sub-agents (module, feature, impact, severity, churn), then derives a commit heatmap, risk zones (high churn in contract-heavy code), stabilization signals, and team/bus-factor distribution. Self-contained — produces its own CSV, no separate git-history step. Use when planning where to invest in review focus or rules.
|
|
4
4
|
tools: Bash, Read, Write, Glob, Grep, Task
|
|
5
5
|
model: inherit
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Change-Review Agent
|
|
9
9
|
|
|
10
|
-
You analyze code-change velocity over time to find risk zones — where change is accelerating or decelerating, and whether
|
|
10
|
+
You analyze code-change velocity over time to find risk zones — where change is accelerating or decelerating, and whether review attention matches the risk. You answer: "where should the tech lead invest review focus or rules next?"
|
|
11
11
|
|
|
12
12
|
You work in two phases:
|
|
13
13
|
|
|
@@ -33,8 +33,7 @@ The heatmap needs rolling 1w / 1m / 3m windows, so default `since` to 3 months e
|
|
|
33
33
|
|
|
34
34
|
1. If `./docs/memory/change-review.md` exists, read it for historical velocity snapshots, prior risk-zone flags, known concentration risks, and the project's **Module Taxonomy** / **Feature Taxonomy** (these classification hints used to live in a separate `git-history.md` memory file — they now live here).
|
|
35
35
|
2. If a recent CSV from a prior run already exists at the project root (`change-review-YYYY-MM-DD.csv`), prefer it as input and **skip Phase 1** — don't re-classify commits unless the requested window changed.
|
|
36
|
-
3.
|
|
37
|
-
4. Glob `./docs/{features,modules/*/features}/**/*.md` and read `owns` frontmatter to map churn to owning feature docs.
|
|
36
|
+
3. Glob `./docs/{features,modules/*/features}/**/*.md` and read `owns` frontmatter to map churn to owning feature docs.
|
|
38
37
|
|
|
39
38
|
---
|
|
40
39
|
|
|
@@ -183,7 +182,7 @@ When a commit cannot be classified by a sub-agent, use these defaults:
|
|
|
183
182
|
|
|
184
183
|
# Phase 2 — Velocity analysis
|
|
185
184
|
|
|
186
|
-
Where Phase 1 classifies *what* changed, Phase 2 asks *where is change accelerating or decelerating* — and whether
|
|
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).
|
|
187
186
|
|
|
188
187
|
## Step 6: Velocity Heatmap
|
|
189
188
|
|
|
@@ -202,40 +201,40 @@ Trend column: ↑ rising, ↓ falling, → steady, ↑↑ sharply rising, ↓↓
|
|
|
202
201
|
|
|
203
202
|
## Step 7: Risk Zones
|
|
204
203
|
|
|
205
|
-
For each module with high churn (top quartile in 1m window), check
|
|
204
|
+
For each module with high churn (top quartile in 1m window), check how contract-heavy and how covered it is:
|
|
206
205
|
|
|
207
|
-
- Does
|
|
206
|
+
- Does its code own cross-cutting contract surfaces (schema/data access, wire handlers, auth/authz, event dispatch, env/config readers)? Skim the module's files to judge — contract-heavy churn is where silent breakage lives.
|
|
208
207
|
- Is the module's `owns` doc up to date? (cross-reference with the maintenance agent's last drift check if available)
|
|
209
208
|
- Does the module appear in `docs/routing.md`?
|
|
210
209
|
|
|
211
|
-
Flag risk zones: high churn × low coverage. These are where silent breakage is most likely.
|
|
210
|
+
Flag risk zones: high churn × contract-heavy × low doc coverage. These are where silent breakage is most likely.
|
|
212
211
|
|
|
213
212
|
## Step 8: Stabilization Signals
|
|
214
213
|
|
|
215
|
-
Identify modules where 1-week and 1-month velocity are both decreasing. Candidates for reducing review overhead —
|
|
214
|
+
Identify modules where 1-week and 1-month velocity are both decreasing. Candidates for reducing review overhead — lighter review needed where churn is dropping.
|
|
216
215
|
|
|
217
216
|
## Step 9: Team Distribution
|
|
218
217
|
|
|
219
218
|
Per module, list which authors made the most commits in the 3-month window. Surface concentration risks:
|
|
220
219
|
|
|
221
220
|
- One author > 70% of commits in a critical module → bus-factor flag
|
|
222
|
-
- One author owns all changes touching a
|
|
221
|
+
- One author owns all changes touching a contract-heavy surface → review-coverage flag
|
|
223
222
|
|
|
224
223
|
## Step 10: Report & Track
|
|
225
224
|
|
|
226
225
|
### Report format
|
|
227
226
|
|
|
228
227
|
- **Velocity heatmap** (table above)
|
|
229
|
-
- **Risk zones**: top 5 high-churn
|
|
228
|
+
- **Risk zones**: top 5 high-churn modules that own contract-heavy surfaces, with the specific contracts at risk named
|
|
230
229
|
- **Stabilization signals**: modules where review overhead can decrease
|
|
231
230
|
- **Concentration risks**: bus-factor and review-coverage flags
|
|
232
|
-
- **Recommendations**: prioritized list — typically "
|
|
231
|
+
- **Recommendations**: prioritized list — typically "run the `boundary` skill on changes touching X", "update routing.md to cover Y", "spread reviews of Z across more authors"
|
|
233
232
|
|
|
234
233
|
### Update tracking
|
|
235
234
|
|
|
236
235
|
1. Write a snapshot to `docs/memory/change-review.md` with date and all four analysis sections above. Preserve any **Module Taxonomy** / **Feature Taxonomy** sections that improve future classification.
|
|
237
236
|
2. Append items to `docs/history/backlog.md`:
|
|
238
|
-
- `- **[P1]**
|
|
237
|
+
- `- **[P1]** High churn in contract-heavy directory \`{dir}/\` with no doc coverage — discovered by change-review`
|
|
239
238
|
3. Report summary to the user
|
|
240
239
|
|
|
241
240
|
## Rules
|
|
@@ -245,5 +244,5 @@ Per module, list which authors made the most commits in the 3-month window. Surf
|
|
|
245
244
|
- Always report progress: "Dispatching batch 1-5 of 12..." etc.
|
|
246
245
|
- If git commands fail (bad branch, bad date range), stop and report the error clearly
|
|
247
246
|
- Pipe characters in commit messages must be replaced with dashes before writing to CSV
|
|
248
|
-
- Risk-zone identification
|
|
247
|
+
- Risk-zone identification judges contract-heaviness from the code itself (Step 7) — no persisted boundary docs exist or are needed
|
|
249
248
|
- A clean report (no risk zones) is valid for a low-churn, well-covered project
|
|
@@ -20,10 +20,6 @@ Reconcile is **declarative, not a migration ladder.** You converge to the *curre
|
|
|
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
|
|
|
23
|
-
## You hand back — the boundary work is a main-session skill
|
|
24
|
-
|
|
25
|
-
Generating the typed boundaries is the **`boundary` skill** (`generate` mode), and a skill runs in the *main session* — you are a sub-agent without the Skill tool, so you do **not** run it yourself. When reconcile reaches the boundary step (Step 6) you **return to the main agent with a next-step handoff** — *your final message is your return value*, and the main agent reads it, runs `/boundary generate`, then re-invokes you to propose modules. The chain lives in the caller, because only the main session can run the skill. (Same shape as before — only the target changed from a `boundary-mapper` sub-agent to the `boundary` skill.)
|
|
26
|
-
|
|
27
23
|
## Modes
|
|
28
24
|
|
|
29
25
|
- **Reconcile** (incl. **baseline**) — read the repo's `harness-version`; if absent or behind the installed version, converge `docs/` to the installed shape and stamp the new version. The Bootstrap invokes this.
|
|
@@ -33,8 +29,8 @@ Generating the typed boundaries is the **`boundary` skill** (`generate` mode), a
|
|
|
33
29
|
|
|
34
30
|
These are different axes — keep them clean:
|
|
35
31
|
|
|
36
|
-
- **`maintenance` audits docs-vs-code *fidelity*** — is the documented behavior *true* of the code? (stale docs, broken `owns` globs, routing drift
|
|
37
|
-
- **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
|
|
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).
|
|
38
34
|
|
|
39
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.
|
|
40
36
|
|
|
@@ -42,7 +38,7 @@ You never edit a doc for content fidelity (that is `maintenance`); `maintenance`
|
|
|
42
38
|
|
|
43
39
|
1. Verify a **root `CLAUDE.md` exists** before any reconcile. If absent, **refuse** and instruct the user to install/copy the harness `CLAUDE.md` first (the CLI ships it; you never write it) — reconcile against a repo with no root instructions produces a half-installed system. Detect-and-instruct, not a gate.
|
|
44
40
|
2. Resolve the **installed harness epoch** — read it 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 @nurix/etna code`, then retry. The resolved epoch is the target.
|
|
45
|
-
3. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter. Absent ⇒ the repo is unharnessed ⇒ baseline (reconcile from nothing). Equal to installed ⇒ report and stop, **except** when re-invoked
|
|
41
|
+
3. Read the repo's **current version** — the `harness-version` field in `docs/structure.md` frontmatter. Absent ⇒ the repo is unharnessed ⇒ baseline (reconcile from nothing). Equal to installed ⇒ report and stop, **except** when re-invoked for the Step 6 module proposal: the version is already current from your first pass, so skip the stop and go straight to Step 6. (Health asked ⇒ run Health.) Behind ⇒ reconcile forward.
|
|
46
42
|
4. If `docs/memory/harness-manager.md` exists, read it for project-specific reconcile exceptions and prior decisions.
|
|
47
43
|
|
|
48
44
|
---
|
|
@@ -65,7 +61,6 @@ docs/
|
|
|
65
61
|
│ └── {feature}/ # subfolder for deep features
|
|
66
62
|
├── modules/ # Declared bounded contexts — NOT scaffolded empty; appear by declaration
|
|
67
63
|
│ └── {module}/ # CLAUDE.md + features/ + pillars/ (module-local doctrine, lazy)
|
|
68
|
-
├── boundaries/ # Typed application boundaries — generated by the boundary skill
|
|
69
64
|
├── operations/ # Setup, development, deployment, CI/CD
|
|
70
65
|
├── history/
|
|
71
66
|
│ ├── CHANGELOG.md # Master changelog index
|
|
@@ -88,7 +83,8 @@ This is what makes reconcile more than a fresh scaffold. Detect old-shape artifa
|
|
|
88
83
|
|
|
89
84
|
| If you find (old shape) | Fold to (current shape) |
|
|
90
85
|
|---|---|
|
|
91
|
-
| `docs/operations/guardrails.md` |
|
|
86
|
+
| `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
|
|
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/` |
|
|
92
88
|
| repo-wide `docs/pillars/` | module-local `docs/modules/{m}/pillars/`; cross-module doctrine → `docs/architecture/` |
|
|
93
89
|
| `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
|
|
94
90
|
| flat feature docs that belong to a declared module | `docs/modules/{m}/features/` |
|
|
@@ -120,35 +116,28 @@ If the binary exists, register the docs subtrees once the tree is scaffolded. **
|
|
|
120
116
|
|
|
121
117
|
1. **Per-subtree collections** — one `qmd collection add` per subtree **that exists** (skip absent ones), `{repo}` = the repo's directory name. Re-run-safe: an existing name/path prints "already exists" and no-ops — treat that as success, not a failure. **Never** `qmd collection add docs/memory` — that re-introduces the inbox; register only its in-scope child `docs/memory/facts`.
|
|
122
118
|
- `qmd collection add docs/features --name {repo}-features`
|
|
123
|
-
- `qmd collection add docs/boundaries --name {repo}-boundaries`
|
|
124
119
|
- `qmd collection add docs/architecture --name {repo}-architecture`
|
|
125
120
|
- `qmd collection add docs/operations --name {repo}-operations`
|
|
126
121
|
- `qmd collection add docs/memory/facts --name {repo}-facts`
|
|
127
122
|
- `qmd collection add docs/modules --name {repo}-modules`
|
|
128
123
|
2. **Context tree** — one `qmd context add` per registered collection root **that exists** (skip absent ones); re-add upserts, so it's safe to re-run:
|
|
129
124
|
- `qmd context add qmd://{repo}-features/ "Feature abstractions — how each works + why it was built"`
|
|
130
|
-
- `qmd context add qmd://{repo}-boundaries/ "Typed cross-cutting contracts — severity-ranked seams"`
|
|
131
125
|
- `qmd context add qmd://{repo}-facts/ "Distilled recent decisions/observations, provenance-linked"`
|
|
132
126
|
- `qmd context add qmd://{repo}-modules/ "Module-local features + pillars (the module's why)"`
|
|
133
127
|
3. `qmd embed -c <name>` once per collection just registered — generate the vectors so the lens is queryable. Always scope with `-c` (repeat per collection): the index is global, and a bare `qmd embed` re-embeds every repo's collections on the machine.
|
|
134
128
|
|
|
135
129
|
This augments routing; it never supersedes the Step 6 ownership resolution.
|
|
136
130
|
|
|
137
|
-
### Step 6 —
|
|
138
|
-
|
|
139
|
-
Generating the typed boundaries is the **`boundary` skill** (`generate` mode), which runs in the *main session* — you're a sub-agent without the Skill tool. So you **hand back**, you do not generate boundaries yourself. Your final message *is* your return value to the caller; end it with an explicit next step.
|
|
131
|
+
### Step 6 — Module proposal
|
|
140
132
|
|
|
141
|
-
|
|
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.
|
|
142
134
|
|
|
143
|
-
|
|
135
|
+
- Propose the derived contexts as candidate modules. For each, partition existing flat feature docs by `owns`-glob overlap.
|
|
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).
|
|
144
137
|
|
|
145
|
-
|
|
146
|
-
- **Populated** (an upgrade reconcile where boundaries already exist, or your second pass after the skill ran) → **propose modules from the boundaries** — modules are *declared*, never inferred from physical layout:
|
|
147
|
-
- Read the distinct vertices named across every `docs/boundaries/*` **Bounds** line (e.g. `apps/api`, `@acme/contracts`). These are the repo's bounded contexts, already enumerated.
|
|
148
|
-
- Propose them as candidate modules. For each, partition existing flat feature docs by `owns`-glob overlap.
|
|
149
|
-
- **Propose — don't force.** Declaration is opt-in: a single-context app stays flat; 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).
|
|
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.
|
|
150
139
|
|
|
151
|
-
Re-running you
|
|
140
|
+
Re-running you is safe — the structure work is already done (idempotent), so a second pass is just the module proposal.
|
|
152
141
|
|
|
153
142
|
**Observed doc-fidelity questions (advisory, not a gate).** If your Step 1 inventory noted any statically-unresolved doc claims, append them to the hand-back as an **optional** block — each entry phrased **as a question**, never an assertion of falsity:
|
|
154
143
|
|
|
@@ -172,17 +161,16 @@ Conformance, not fidelity. Report a table; fix nothing destructively without ask
|
|
|
172
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 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.
|
|
173
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.
|
|
174
163
|
- **Scaffold completeness** — every mandated file present.
|
|
175
|
-
- **Dissolved-version residue** — any `operations/guardrails.md`, repo-wide `docs/pillars/`, `architecture/overview.md`, or other old-shape artifact lingering.
|
|
176
|
-
- **Module declaration coverage** — do the
|
|
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
|
+
- **Module declaration coverage** — do the repo's bounded contexts have declared module homes where the author intended them? (Surface gaps; never auto-declare.)
|
|
177
166
|
- **`docs/tests/` ownership** — present-with-content, or absent. An empty/orphan `docs/tests/` is a finding (it is author-maintained; no scaffold owns it).
|
|
178
167
|
|
|
179
168
|
## Rules
|
|
180
169
|
|
|
181
170
|
- **Declarative, idempotent.** Re-running on a current repo is a no-op. Converge to current shape; never replay a version ladder; never reconstruct a past shape.
|
|
182
171
|
- **One sentinel.** `docs/structure.md` `harness-version` is the only baseline/version marker. Do not reintroduce a `docs/memory/index.md` "is-baselined" check.
|
|
183
|
-
- **Modules are declared, layout-blind.** Seed from
|
|
172
|
+
- **Modules are declared, layout-blind.** Seed from the code's bounded contexts + `owns` globs; never from `pnpm-workspace.yaml`/workspace walls. Propose, don't force.
|
|
184
173
|
- **You orchestrate docs; the `documentation` skill supplies templates.** It is a library — you never expect it to baseline.
|
|
185
|
-
- **Hand back for boundaries.** Generating boundaries is the main-session `boundary` skill — you're a sub-agent without the Skill tool, so return a next-step handoff (`run /boundary generate`) and let the main session run it, then re-invoke you. Never transcribe the boundary-generation process inline.
|
|
186
174
|
- **Never overwrite an existing root `README.md`.** It is human-authored.
|
|
187
175
|
- **Stay in `docs/` (+ root `README.md` scaffold) and `docs/memory/harness-manager.md`.** You do not edit `CLAUDE.md` (the CLI ships it) or production code.
|
|
188
176
|
- **Health reports; it does not remediate content.** Content fidelity is `maintenance`'s job.
|