@nurix/etna 0.18.11 → 0.18.13
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/README.md +8 -9
- package/bin/etna.js +63 -2
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/CLAUDE.md +9 -10
- package/data/harnesses/code/agents/brainstorm.md +3 -3
- package/data/harnesses/code/agents/change-review.md +4 -4
- package/data/harnesses/code/agents/maintenance.md +177 -59
- package/data/harnesses/code/agents/spec-mode.md +3 -3
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/hooks/generate-ownership-index.mjs +148 -0
- package/data/harnesses/code/hooks/hooks.json +12 -0
- package/data/harnesses/code/skills/boundary/references/boundary-taxonomy.md +3 -3
- package/data/harnesses/code/skills/brainstorm/README.md +20 -12
- package/data/harnesses/code/skills/brainstorm/SKILL.md +4 -4
- package/data/harnesses/code/skills/brainstorm/exit-artifacts.md +62 -0
- package/data/harnesses/code/skills/brainstorm/templates/source-of-truth.md +49 -0
- package/data/harnesses/code/skills/distiller/SKILL.md +3 -3
- package/data/harnesses/code/skills/distiller/references/docs-mode.md +7 -7
- package/data/harnesses/code/skills/documentation/SKILL.md +23 -23
- package/data/harnesses/code/skills/documentation/references/templates.md +24 -65
- package/data/harnesses/etna/CLAUDE.md +18 -27
- package/data/harnesses/etna/agents/brainstorm.md +3 -3
- package/data/harnesses/etna/agents/change-review.md +4 -4
- package/data/harnesses/etna/agents/maintenance.md +177 -59
- package/data/harnesses/etna/agents/spec-mode.md +3 -3
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/hooks/generate-ownership-index.mjs +148 -0
- package/data/harnesses/etna/hooks/hooks.json +12 -0
- package/data/harnesses/etna/rules/npm-cli.md +88 -0
- package/data/harnesses/etna/skills/boundary/references/boundary-taxonomy.md +3 -3
- package/data/harnesses/etna/skills/brainstorm/README.md +20 -12
- package/data/harnesses/etna/skills/brainstorm/SKILL.md +4 -4
- package/data/harnesses/etna/skills/brainstorm/exit-artifacts.md +62 -0
- package/data/harnesses/etna/skills/brainstorm/templates/source-of-truth.md +49 -0
- package/data/harnesses/etna/skills/distiller/SKILL.md +3 -3
- package/data/harnesses/etna/skills/distiller/references/docs-mode.md +7 -7
- package/data/harnesses/etna/skills/documentation/SKILL.md +23 -23
- package/data/harnesses/etna/skills/documentation/references/templates.md +24 -65
- package/data/harnesses/hr/harness.json +2 -2
- package/data/harnesses/hr/skills/evaluator/criteria/testing.md +4 -4
- package/data/harnesses/mobile/CLAUDE.md +9 -10
- package/data/harnesses/mobile/agents/brainstorm.md +3 -3
- package/data/harnesses/mobile/agents/change-review.md +4 -4
- package/data/harnesses/mobile/agents/maintenance.md +177 -59
- package/data/harnesses/mobile/agents/spec-mode.md +3 -3
- package/data/harnesses/mobile/harness.json +2 -2
- package/data/harnesses/mobile/hooks/generate-ownership-index.mjs +148 -0
- package/data/harnesses/mobile/hooks/hooks.json +12 -0
- package/data/harnesses/mobile/skills/boundary/references/boundary-taxonomy.md +3 -3
- package/data/harnesses/mobile/skills/brainstorm/README.md +20 -12
- package/data/harnesses/mobile/skills/brainstorm/SKILL.md +4 -4
- package/data/harnesses/mobile/skills/brainstorm/exit-artifacts.md +62 -0
- package/data/harnesses/mobile/skills/brainstorm/templates/source-of-truth.md +49 -0
- package/data/harnesses/mobile/skills/distiller/SKILL.md +3 -3
- package/data/harnesses/mobile/skills/distiller/references/docs-mode.md +7 -7
- package/data/harnesses/mobile/skills/documentation/SKILL.md +23 -23
- package/data/harnesses/mobile/skills/documentation/references/templates.md +24 -65
- package/package.json +1 -1
- package/data/harnesses/code/agents/harness-manager.md +0 -184
- package/data/harnesses/code/skills/brainstorm/harvest.md +0 -26
- package/data/harnesses/etna/agents/harness-manager.md +0 -184
- package/data/harnesses/etna/skills/brainstorm/harvest.md +0 -26
- package/data/harnesses/mobile/agents/harness-manager.md +0 -184
- package/data/harnesses/mobile/skills/brainstorm/harvest.md +0 -26
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A Claude Code skill that is a **thinking partner for designing software** — not a form to fill in. It runs one constant loop (distill → abstract → sync → record) over a conversation, files the thinking into a small set of substance-first pillars, and treats _coherence_ as a measurable target rather than a vibe.
|
|
4
4
|
|
|
5
|
-
The
|
|
5
|
+
The single principle: **the conversation is the work; the artifacts serve it.**
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -67,7 +67,7 @@ coherent ⇔ open_questions == 0 ∧ last sync ran after the last pillar write
|
|
|
67
67
|
|
|
68
68
|
## The sync agent
|
|
69
69
|
|
|
70
|
-
The background reconciler
|
|
70
|
+
The background reconciler. One sync in flight at a time; at most one queued behind it. It runs after substantive writes, mandatorily on entering converge and at `stop`, and on demand. It audits exactly four sources:
|
|
71
71
|
|
|
72
72
|
1. **Cross-pillar contradiction** — thesis vs domain model vs decisions vs doctrine vs build.
|
|
73
73
|
2. **Aspect coverage** — any mapped aspect with no content → a question.
|
|
@@ -96,9 +96,9 @@ The complexity dial sets _defaults_, not a cage — any lazy pillar materializes
|
|
|
96
96
|
|
|
97
97
|
---
|
|
98
98
|
|
|
99
|
-
## Build modes
|
|
99
|
+
## Build modes
|
|
100
100
|
|
|
101
|
-
|
|
101
|
+
The writing posture is a **mode** chosen at intake, folded into `build.md`:
|
|
102
102
|
|
|
103
103
|
- **greenfield** (default) — present-tense everywhere, no phantom history. Execution sections closed.
|
|
104
104
|
- **brownfield** — migration vocabulary is legitimate in `build.md`; other pillars still describe the target.
|
|
@@ -108,9 +108,15 @@ v1 applied a present-tense "greenfield" writing doctrine unconditionally — whi
|
|
|
108
108
|
|
|
109
109
|
---
|
|
110
110
|
|
|
111
|
-
##
|
|
111
|
+
## Exit artifacts
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
The session writes a **kept** design record at `docs/brainstorm/{topic}/` (one subfolder per topic). At `stop`, after the final sync, the skill _offers_ what to **publish** from it (`AskUserQuestion`, multi-select — a session can emit more than one):
|
|
114
|
+
|
|
115
|
+
- **Source of truth** — one consolidated, README-style canonical doc for the thing designed (`templates/source-of-truth.md`); lands in the repo's feature/architecture doc home, else a topic `Readme.md`.
|
|
116
|
+
- **Plans** — one or more executable plan docs → `docs/history/plans/` (Status: Draft).
|
|
117
|
+
- **Harvest into the living docs** — conclusions dispersed by scope into ADRs, the domain model, and the backlog.
|
|
118
|
+
|
|
119
|
+
The `docs/brainstorm/{topic}/` record is **kept** whichever you pick — never deleted; it is the provenance every artifact traces back to. See `exit-artifacts.md`.
|
|
114
120
|
|
|
115
121
|
---
|
|
116
122
|
|
|
@@ -118,7 +124,7 @@ By default the session folder _is_ the product — self-contained, resumed by th
|
|
|
118
124
|
|
|
119
125
|
1. **No production code outside the session folder.** Illustrative snippets are fine inside it.
|
|
120
126
|
2. **Speak English to the user; codes (`Q3`, `D7`) live in the files.**
|
|
121
|
-
3. **`AskUserQuestion` appears in exactly
|
|
127
|
+
3. **`AskUserQuestion` appears in exactly four places:** the intake frame, interview mode, converge picks, the `stop` exit-artifact pick.
|
|
122
128
|
4. **Suggested, never seized** — mode shifts, abstractions, probes are offered once.
|
|
123
129
|
5. **Questions are the only convergence currency** — nothing pending may live only in the transcript.
|
|
124
130
|
6. **No auto-invocation** — only `/brainstorm start` and `/brainstorm stop`.
|
|
@@ -128,9 +134,11 @@ By default the session folder _is_ the product — self-contained, resumed by th
|
|
|
128
134
|
## Files
|
|
129
135
|
|
|
130
136
|
```
|
|
131
|
-
brainstorm/
|
|
132
|
-
├── SKILL.md
|
|
133
|
-
├── README.md
|
|
134
|
-
├──
|
|
135
|
-
└── templates/
|
|
137
|
+
brainstorm/ # the skill (in .claude/skills/)
|
|
138
|
+
├── SKILL.md # the skill definition Claude Code loads (~1.8k words)
|
|
139
|
+
├── README.md # this file
|
|
140
|
+
├── exit-artifacts.md # what /brainstorm stop publishes: source-of-truth / plans / harvest
|
|
141
|
+
└── templates/ # pillar templates + source-of-truth.md, used in the record and at stop
|
|
136
142
|
```
|
|
143
|
+
|
|
144
|
+
The session itself is written to `docs/brainstorm/{topic}/` (kept, committed) — not here.
|
|
@@ -6,7 +6,7 @@ argument-hint: "start | stop"
|
|
|
6
6
|
|
|
7
7
|
# Brainstorm
|
|
8
8
|
|
|
9
|
-
Think with the user, then file — never the reverse. The artifacts exist to serve the conversation; the conversation never exists to populate artifacts. The constant across every scale of idea is **the loop**; everything else — pillar count, ceremony,
|
|
9
|
+
Think with the user, then file — never the reverse. The artifacts exist to serve the conversation; the conversation never exists to populate artifacts. The constant across every scale of idea is **the loop**; everything else — pillar count, ceremony, exit artifacts — scales with complexity.
|
|
10
10
|
|
|
11
11
|
## The loop — every turn, every mode
|
|
12
12
|
|
|
@@ -50,7 +50,7 @@ Then propose the **aspect map**: the thinking dimensions for _this specific idea
|
|
|
50
50
|
|
|
51
51
|
### 3. Bootstrap
|
|
52
52
|
|
|
53
|
-
Session folder:
|
|
53
|
+
Session folder: `docs/brainstorm/{topic}/` — a **committed, kept** design record, one subfolder per design topic (slug the topic; confirm it in one line). Resume an existing topic by reusing its folder if it already holds a `state.md`. The record stays in the repo after the exit artifacts publish (it is the provenance they distil from — see `exit-artifacts.md`), so it lives under `docs/` like any other durable project knowledge, not at the repo root. Create only the pillars the complexity calls for, from `templates/` (never overwrite existing files; if a template is missing, create the file from the field lists in **Pillars**). Write top-level `state.md`:
|
|
54
54
|
|
|
55
55
|
```
|
|
56
56
|
STATE: open
|
|
@@ -121,7 +121,7 @@ Zero means _"audited against the four sources and clean"_ — never _"nothing ca
|
|
|
121
121
|
|
|
122
122
|
1. Run a final sync (wait for any in-flight sync first).
|
|
123
123
|
2. **Coherent** → say so and proceed. **Questions open** → list them plainly (English first, codes in parentheses) and offer per question: resolve now (mini-converge) / park explicitly (backlog or non-goals, with reason) / leave open and stop anyway — the folder keeps full state and resumes exactly where it left off.
|
|
124
|
-
3. **
|
|
124
|
+
3. **Publish exit artifacts** — see `exit-artifacts.md`. Offer the choice (`AskUserQuestion`, multi-select): a **source of truth** (one consolidated README-style doc — the standing reference for the thing designed), **plans** (executable work → `docs/history/plans/`), and/or **harvest into the living docs** (conclusions dispersed by scope into ADRs, the domain model, the backlog). The `docs/brainstorm/{topic}/` record is **kept** (committed) whichever you pick — it is the provenance every artifact traces back to and the seed the next session resumes from.
|
|
125
125
|
4. Write `STATE: closed` + one-line reason. Print: _"Run `/brainstorm start` to resume."_
|
|
126
126
|
|
|
127
127
|
## Conduct — holds for the whole session
|
|
@@ -129,7 +129,7 @@ Zero means _"audited against the four sources and clean"_ — never _"nothing ca
|
|
|
129
129
|
1. **Speak English; codes live in files.** In conversation, name every pillar item by what it _is_ in plain words. Append the code in parentheses only when traceability needs it (_"…can a user change answer depth? (tracked as Q6)"_). Never lead with a bare `Q3`/`D7`. The user is not looking at the files.
|
|
130
130
|
2. **No production code outside the session folder.** Illustrative load-bearing snippets are fine inside it (`samples/` or fenced in pillars). If asked for production code: offer a sketch inside the folder, or `/brainstorm stop` first.
|
|
131
131
|
3. **The writing posture comes from `build.md`'s mode.** Greenfield: every pillar describes the system as it _will be_, present tense, as though the chosen design was always the plan — no migration vocabulary, no phantom history (banned list in `templates/build.md`). Brownfield/hybrid: migration vocabulary is legitimate, and `build.md` is its home; other pillars still describe the _target_ state.
|
|
132
|
-
4. **`AskUserQuestion` appears in exactly
|
|
132
|
+
4. **`AskUserQuestion` appears in exactly four places:** the intake frame batch, interview mode, converge picks, and the `stop` exit-artifact pick. Everywhere else: prose.
|
|
133
133
|
5. **Suggested, never seized.** Mode shifts, abstractions, probes — one offer each, accept refusal without re-litigating.
|
|
134
134
|
6. **Questions are the only convergence currency.** Flaws, gaps, contradictions, uncovered aspects — everything unresolved funnels into `questions.md` or it doesn't exist. Nothing pending may live only in the conversation transcript.
|
|
135
135
|
7. **No auto-invocation.** Only `/brainstorm start` and `/brainstorm stop` enter or leave a session. Read `state.md` at the start of every turn while a session folder exists.
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Exit artifacts
|
|
2
|
+
|
|
3
|
+
What `/brainstorm stop` publishes from a closed session. The `docs/brainstorm/{topic}/` record is **kept
|
|
4
|
+
either way** — committed provenance, never a scratchpad. Exit artifacts copy the session's _conclusions_
|
|
5
|
+
outward into the form the work needs; the record stays as the source they trace back to.
|
|
6
|
+
|
|
7
|
+
At `stop`, after the final sync, **offer the artifact choice** (`AskUserQuestion`, multi-select — a session
|
|
8
|
+
can publish more than one):
|
|
9
|
+
|
|
10
|
+
| Artifact | Use when the outcome is… | Lands in | Voice |
|
|
11
|
+
| --- | --- | --- | --- |
|
|
12
|
+
| **Source of truth** | a standing reference — "what this thing **is**" | the repo's feature/architecture doc home, else a topic `Readme.md` | README — present tense, reader-first (`templates/source-of-truth.md`) |
|
|
13
|
+
| **Plans** | work to execute — "what to **build**, in what order" | one or more `docs/history/plans/YYYY-MM-DD-{slug}.md` (Status: Draft) | plan — steps, sequencing, status |
|
|
14
|
+
| **Harvest into living docs** | findings that belong inside an existing doc system | dispersed by scope (table below) | matches each destination |
|
|
15
|
+
|
|
16
|
+
A session commonly emits a **source of truth** for the thing designed _and_ **plans** for building it.
|
|
17
|
+
Picking "source of truth" does **not** also disperse headlines across the doc tree — that is what "harvest"
|
|
18
|
+
does; pick it too if you want both the one-doc reference and the integrated headlines.
|
|
19
|
+
|
|
20
|
+
## Source of truth
|
|
21
|
+
|
|
22
|
+
One consolidated, README-style document — the canonical reference for the thing designed. Distil every
|
|
23
|
+
pillar into it: `thesis.md` → what it is; `domain-model.md` → how it works + parts; `decisions.md` →
|
|
24
|
+
present-tense rationale (no `D-N` codes, no options-considered — those stay in the record and ADRs);
|
|
25
|
+
`non-goals.md` + accepted tradeoffs → constraints; still-open questions → a one-line pointer back to the
|
|
26
|
+
record. Template: `templates/source-of-truth.md`.
|
|
27
|
+
|
|
28
|
+
Place it at the repo's canonical home for that kind of knowledge: a feature/system → `docs/features/{slug}.md`
|
|
29
|
+
(carry the doc system's `owns:` / `module:` / `keywords:` / `status:` frontmatter); cross-cutting →
|
|
30
|
+
`docs/architecture/{slug}.md`; no doc taxonomy → a `Readme.md` at the topic's folder. One document — if a
|
|
31
|
+
section outgrows it, link out rather than sprawl.
|
|
32
|
+
|
|
33
|
+
## Plans
|
|
34
|
+
|
|
35
|
+
One or more executable plan docs in `docs/history/plans/` (Status: Draft), authored to the `documentation`
|
|
36
|
+
skill's §8 Plan template. Source: the `thesis.md` narrative for scope, `build.md` for migration strategy /
|
|
37
|
+
gotchas / rollout (execution content is plan content, not architecture). Split by deliverable, not by pillar
|
|
38
|
+
— one plan per cohesive unit of work.
|
|
39
|
+
|
|
40
|
+
## Harvest into living docs
|
|
41
|
+
|
|
42
|
+
A structured diff between the session pillars and the live docs, dispersed by scope. Modules are labels,
|
|
43
|
+
not folders — a finding scoped to one module still lands in `docs/architecture/` and names the module in prose.
|
|
44
|
+
|
|
45
|
+
| Session source | Destination |
|
|
46
|
+
| --- | --- |
|
|
47
|
+
| Decisions (any scope) | one ADR per cohesive theme → `docs/architecture/adr/NNN-{slug}.md` (`documentation` skill ADR template; `status:` frontmatter is the lifecycle source of truth; rejected alternatives → the ADR's Options Considered table) |
|
|
48
|
+
| `domain-model.md` | `docs/architecture/domain-model.md`; note any IA / cross-cutting contract change there — the `boundary` skill reads it from source at the next plan check |
|
|
49
|
+
| Doctrine / glossary / rejected | `docs/architecture/{domain-model,glossary}.md`, or the relevant ADR |
|
|
50
|
+
| `tech.md` deviations | `docs/architecture/references.md` or the relevant ADR |
|
|
51
|
+
| `non-goals.md` / `references.md` | `docs/architecture/{non-goals,references}.md` |
|
|
52
|
+
| `backlog.md` | `docs/history/backlog.md` (P0–P3) |
|
|
53
|
+
| Still-open questions | `docs/architecture/open-questions.md`, each with a _Resolution lands in_ pointer |
|
|
54
|
+
|
|
55
|
+
Append a changelog entry at `docs/history/changelog/YYYY-MM-DD-brainstorm-{slug}.md` listing what was published where.
|
|
56
|
+
|
|
57
|
+
## After publishing — keep the record
|
|
58
|
+
|
|
59
|
+
**Keep `docs/brainstorm/{topic}/` — never delete it.** The exit artifacts now carry the distilled
|
|
60
|
+
conclusions, but the record stays committed as their provenance: a traceable source for every published
|
|
61
|
+
headline, the seed the next `/brainstorm start` on this topic resumes from, and a high-surprisal input the
|
|
62
|
+
`distiller` ingests. Retire a topic's folder by hand only when the design line is truly dead.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# [Thing] — source of truth
|
|
2
|
+
|
|
3
|
+
> This is a **source-of-truth doc**: the standing, canonical reference for [thing]. Write it like a
|
|
4
|
+
> README — present tense, reader-first, the thing described as it _is_. It is **not a plan** (no steps,
|
|
5
|
+
> status, or sequencing — those go to `docs/history/plans/`) and **not the brainstorm record** (no
|
|
6
|
+
> `Q-N`/`D-N` codes, no "Why / How to apply" ledger, no rejected alternatives — those stay in
|
|
7
|
+
> `docs/brainstorm/{topic}/` and any ADRs). One document; if a section outgrows it, link out, don't sprawl.
|
|
8
|
+
>
|
|
9
|
+
> **Placement.** In a repo with a feature-doc system this lands as `docs/features/{slug}.md` and carries
|
|
10
|
+
> that system's frontmatter (`owns:` / `module:` / `keywords:` / `status:`). Cross-cutting → `docs/architecture/{slug}.md`.
|
|
11
|
+
> No doc taxonomy → a `Readme.md` at the topic's home.
|
|
12
|
+
|
|
13
|
+
## What it is
|
|
14
|
+
|
|
15
|
+
[One paragraph, present tense: what the thing is, what it does, who uses it. Distilled from `thesis.md`.]
|
|
16
|
+
|
|
17
|
+
## How it works
|
|
18
|
+
|
|
19
|
+
[The model — entities, relationships, the main flow — lifted from `domain-model.md` into plain,
|
|
20
|
+
reader-first description. Prose and tables; a diagram only if it earns its tokens.]
|
|
21
|
+
|
|
22
|
+
## Parts
|
|
23
|
+
|
|
24
|
+
[One row per component / module / piece: name · role · what it owns · what it depends on.]
|
|
25
|
+
|
|
26
|
+
| Part | Role | Owns | Depends on |
|
|
27
|
+
| --- | --- | --- | --- |
|
|
28
|
+
| | | | |
|
|
29
|
+
|
|
30
|
+
## Why it's shaped this way
|
|
31
|
+
|
|
32
|
+
[The load-bearing decisions, folded into present-tense rationale — "the index is single-writer because
|
|
33
|
+
concurrent writes corrupted it," not "we decided X over Y." No decision codes, no options-considered
|
|
34
|
+
table. The full rationale and the roads not taken live in the brainstorm record and ADRs — cite them,
|
|
35
|
+
don't reproduce them.]
|
|
36
|
+
|
|
37
|
+
## Constraints & non-goals
|
|
38
|
+
|
|
39
|
+
[Accepted tradeoffs phrased as current fact ("a 5-second lag is accepted for predictable throughput")
|
|
40
|
+
and what is explicitly out of scope.]
|
|
41
|
+
|
|
42
|
+
## Open questions
|
|
43
|
+
|
|
44
|
+
[One line pointing at `docs/brainstorm/{topic}/pillars/questions.md` if any remain open. Omit if none.]
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
_Distilled from `docs/brainstorm/{topic}/`. That record holds the rationale, the rejected alternatives,
|
|
49
|
+
and the provenance for everything above._
|
|
@@ -38,13 +38,13 @@ Distill the inbox's undigested entries into fact-cards. The algorithm is in [`re
|
|
|
38
38
|
|
|
39
39
|
**Thin or empty inbox ⇒ not a NOOP — distill the decision record.** A project whose sessions produced no reflected lessons is **not** a project with nothing to distill. Architecture decisions and reversals are high-surprisal by nature — they exist precisely because they were _not_ predictable. So when the inbox is thin/empty, also ingest, as surprisal sources for steps 2–5:
|
|
40
40
|
- `docs/architecture/adr/**` — each accepted ADR is a surprising decision (its `Decision` + **Options Considered** — the rejected-alternatives section in the `documentation` §10 ADR template — carry the prediction error).
|
|
41
|
-
- `docs/
|
|
41
|
+
- `docs/brainstorm/{topic}/` — the kept Brainstorming-Mode design records (`pillars/decisions.md`, `rejected.md`, etc.): the reasoning, reversals, and roads-not-taken behind each design call, retained as committed provenance. The richest surprisal source the harness produces. (Where a repo keeps no brainstorm record in `docs/` — e.g. an older transient-workspace harness — fall back to `docs/memory/brainstorm.md`, the owner pronouncements recorded outside the inbox.) Provenance points at the ADR file / brainstorm pillar, not a session id. These sources are **never consumed** — reconciliation (step 4) is what keeps a re-run over them idempotent.
|
|
42
42
|
|
|
43
43
|
2. **Surprisal filter → survivors** (method §1). Present the LLM with (a) a summary of the _current_ fact-set, (b) the undigested entries. Keep only what is **surprising** relative to (a). Predictable ⇒ dropped — no importance scores, no templates, prediction error is the only retention signal. Inbox entries arrive semi-distilled (the reflection hook already dropped routine work), so the filter's job here is narrower: drop what the existing fact-set already predicts. (First run, empty fact-set: keep decisions, reversals, discovered constraints, and failures with a cause worth remembering.)
|
|
44
44
|
|
|
45
45
|
3. **Decompose survivors → EDU candidates** (method §2). Each survivor becomes **one** atomic, self-contained statement — entity names normalized, minimal context baked into the sentence — with `provenance` pointing at the session ids and commits its inbox entry names. Decomposition, **not** summarization: one survivor may yield several cards; no information is destroyed; everything stays auditable back to its session and commits.
|
|
46
46
|
|
|
47
|
-
4. **Reconcile each candidate against existing cards** (method §3). Query the existing facts for semantic neighbors, then decide **ADD / UPDATE / SUPERSEDE / NOOP** for each. Gate on the **facts collection holding cards**, not on the binary and not on the collection merely being registered — a present qmd whose `{repo}-facts` collection is _registered but empty_ (the common first run:
|
|
47
|
+
4. **Reconcile each candidate against existing cards** (method §3). Query the existing facts for semantic neighbors, then decide **ADD / UPDATE / SUPERSEDE / NOOP** for each. Gate on the **facts collection holding cards**, not on the binary and not on the collection merely being registered — a present qmd whose `{repo}-facts` collection is _registered but empty_ (the common first run: the `maintenance` agent's baseline mode registers + embeds `{repo}-facts` over a freshly-scaffolded `docs/memory/facts/` that has zero cards) returns nothing useful, exactly like an unregistered collection.
|
|
48
48
|
- **Cards present** — `command -v qmd` succeeds **and** `docs/memory/facts/` holds at least one card (`docs/memory/facts/*.md` is non-empty): query scoped to the collection — `qmd query --format json -c {repo}-facts "<the candidate statement>"`. `{repo}` = the repo's directory name. Scope with `-c` always. (If the query returns nothing on a non-empty card set, the collection is registered-but- unbuilt — treat that as the fallback trigger below, not as "no neighbors.")
|
|
49
49
|
- **No cards to query** (qmd absent, **or** `docs/memory/facts/*.md` empty — the common first-run case where the facts dir was scaffolded but never distilled into): fall back to filename/grep similarity over `docs/memory/facts/*.md` (slug overlap + entity-name grep), and **note in the report** that reconciliation ran without semantic retrieval. Step 7 builds/refreshes the collection at the end of the run, so the _next_ run — with cards now present — reconciles semantically.
|
|
50
50
|
|
|
@@ -82,7 +82,7 @@ Distill fact-cards into proposed edits to `docs/` (the cold, human-owned SSoT)
|
|
|
82
82
|
- **Supersede ≠ delete.** Bi-temporal only: set `invalid_from:` + `superseded_by:` on the old card and leave the file in place. Nothing is ever removed from `docs/memory/facts/`.
|
|
83
83
|
- **Findings are questions, not verdicts.** When a candidate appears to contradict an existing card, phrase it as a question (is X now superseded by Y?) — never assert staleness or falsity.
|
|
84
84
|
- **Never auto-runs.** Invoked by the user, by the Completion flow (kit `CLAUDE.md`), or by accepting the maintenance proposal. No cron, no daemon, no hook self-trigger — a workflow step the agent runs is not a self-trigger.
|
|
85
|
-
- **qmd is strictly optional.** Guard every qmd call on `command -v qmd`; absent ⇒ silent skip. Reconciliation additionally needs the `{repo}-facts` collection to hold **cards** — not merely to be registered. "Unbuilt" here means **no cards** (`docs/memory/facts/*.md` empty), not "unregistered":
|
|
85
|
+
- **qmd is strictly optional.** Guard every qmd call on `command -v qmd`; absent ⇒ silent skip. Reconciliation additionally needs the `{repo}-facts` collection to hold **cards** — not merely to be registered. "Unbuilt" here means **no cards** (`docs/memory/facts/*.md` empty), not "unregistered": the `maintenance` agent's baseline mode registers + embeds `{repo}-facts` over an empty scaffolded facts dir, so on a qmd-equipped, freshly-baselined repo the collection _appears in_ `qmd collection list` yet indexes zero cards. Binary present but collection cardless (first run) falls back to filename/grep too, same as qmd being absent.
|
|
86
86
|
|
|
87
87
|
## Output locations
|
|
88
88
|
|
|
@@ -66,16 +66,16 @@ Read [`method.md`](method.md) (surprisal / EDU / reconciliation / bi-temporal vo
|
|
|
66
66
|
### 1. Resolve the target doc, read the three roots in order
|
|
67
67
|
|
|
68
68
|
1. `method.md` (algorithm vocabulary).
|
|
69
|
-
2. The **target doc** — full current prose + the `
|
|
69
|
+
2. The **target doc** — full current prose + the doc's `owns:` globs (the paths it owns). This is the SSoT you are proposing to revise; you read it before you draft so conflicts surface as questions, not silent overwrites.
|
|
70
70
|
- `--doc <path>` → that doc.
|
|
71
|
-
- `--feature <slug>` / bare → the spec that just flipped to `Active` (Completion names it), or the feature doc whose `
|
|
71
|
+
- `--feature <slug>` / bare → the spec that just flipped to `Active` (Completion names it), or the feature doc whose `owns:` glob covers the plan's Proposed-Changes paths. Match the `owns:` globs against changed paths. Architecture/operations docs declare no `owns:` — for those, fall to entity/semantic match.
|
|
72
72
|
- No doc resolves → Edge Case A.
|
|
73
73
|
3. The **pillar headlines** — the doctrine pillar (`## Pn —` headlines) and the decisions pillar (`## Dn —` headlines) plus each one's one-line Principle/Decision statement. Read **every** decision headline except those marked superseded: a decision carrying a `Reversed by D-M` marker (or a legacy `Status: tentative`) is NOT a binding pillar headline and is skipped; absence of any status marker means the decision is live (the new append-only model has no `Status: committed` field — a live decision is simply one nothing has reversed). Headlines only, never the bodies — this is the conservative contradiction-check substrate (Resolution 4).
|
|
74
74
|
|
|
75
75
|
### 2. INPUT SELECTION — gather the cards "touching" the target (Resolution 1) — _closes F2, F3, F5_
|
|
76
76
|
|
|
77
|
-
1. **Structural retriever (always runs, qmd-independent).** Read every card in `docs/memory/facts/*.md`. A card _structurally touches_ the target when its `provenance` paths or `entities` intersect the target's `
|
|
78
|
-
2. **Semantic retriever (qmd, optional).** If `command -v qmd` succeeds, for the target's identity (title + each
|
|
77
|
+
1. **Structural retriever (always runs, qmd-independent).** Read every card in `docs/memory/facts/*.md`. A card _structurally touches_ the target when its `provenance` paths or `entities` intersect the target's `owns:` globs — match defined precisely in Resolution 1.
|
|
78
|
+
2. **Semantic retriever (qmd, optional).** If `command -v qmd` succeeds, for the target's identity (title + each `owns:`-glob stem + any `anchors:` query) run `qmd query --format json -c {repo}-facts "<the doc's subject>"`. `{repo}` = repo dir name; scope with `-c` always; repeat `-c` per relevant `{repo}-*` facts collection (the set `qmd collection list` names). qmd absent ⇒ skip silently, note in the report that selection ran structural-only (changes recall, not correctness).
|
|
79
79
|
3. **Bi-temporal + digestion gate (F2, F3).** From the union, drop:
|
|
80
80
|
- any card with `invalid_from` ≠ `null` (superseded — list as "skipped: superseded");
|
|
81
81
|
- any card whose `digested_into:` already lists the target doc path (already consumed here);
|
|
@@ -169,8 +169,8 @@ A card **touches** the target doc iff it satisfies **either** retriever, and is
|
|
|
169
169
|
|
|
170
170
|
**(a) Structural intersection (exact, always evaluated).** True when ANY of:
|
|
171
171
|
|
|
172
|
-
1. **Provenance match (STRONG signal).** A `commit <sha>` entry in the card's `provenance` resolves to changed files (`git show --name-only <sha>` when the commit is local); a changed file under the target's `
|
|
173
|
-
2. **Entity match (SUPPORTING signal).** A normalized name in the card's `entities` equals (case-insensitively, after kebab/camel normalization) a module/feature stem in one of the target's `
|
|
172
|
+
1. **Provenance match (STRONG signal).** A `commit <sha>` entry in the card's `provenance` resolves to changed files (`git show --name-only <sha>` when the commit is local); a changed file under the target's `owns:` globs is a match. (`session <id>` entries carry no paths and do not participate; an ADR/brainstorm path matches the globs directly.) This is strong because the card derives from a commit that edited code the doc owns.
|
|
173
|
+
2. **Entity match (SUPPORTING signal).** A normalized name in the card's `entities` equals (case-insensitively, after kebab/camel normalization) a module/feature stem in one of the target's `owns:` globs, the doc title, or a symbol the doc explicitly names. **Bare prose mentions do NOT count** — only declared ownership (its `owns:` globs), so "touching" can't be triggered by a doc that merely discusses an entity it doesn't own.
|
|
174
174
|
|
|
175
175
|
**(b) Semantic neighborhood (qmd, optional, recall-only).** A card returned by `qmd query -c {repo}-facts "<doc subject>"` within qmd's default result window. Semantic hits with **no** structural intersection are still candidates but flagged `[semantic-only]` in the delta — the link is associative, not provenance-grounded, so the reviewer treats it as lower-trust and may reject on link-strength alone.
|
|
176
176
|
|
|
@@ -189,7 +189,7 @@ A card may touch **several** docs (its entities span modules) — expected, hand
|
|
|
189
189
|
| **`## Architecture` / `## Key Functions`** (feature doc) | Additive correction only when a card names a concrete, code-anchored fact (a new function, a moved file). Prefer Current Behavior unless the card is structural. | Code-anchored structure, not prose. |
|
|
190
190
|
| **A new changelog entry** in `docs/history/changelog/` (via `documentation` skill's Changelog template, `### Added`/`### Modified`/`### Removed`) | Draft a changelog line for a code change a card witnesses, when a plan just completed. | Append-only history; a _new_ file, never an edit. |
|
|
191
191
|
|
|
192
|
-
**Never writable by distill②** (hard stops): `## Goal`, `## Goals & Non-Goals`, `## Approach`, `## Open Questions`, `## State`, the optional `anchors:`
|
|
192
|
+
**Never writable by distill②** (hard stops): `## Goal`, `## Goals & Non-Goals`, `## Approach`, `## Open Questions`, `## State`, the focal frontmatter (`owns`/`module`/`keywords`/`status`) and the optional `anchors:` block (ownership and discovery live there, on the spec/maintenance axis, not the distiller's — P19), any **pillar** file, any **plan** (frozen), any **existing** changelog entry (frozen history), any **boundary** file. A card implying one of these needs a change becomes a **question** (below) or, for pillars, an **escape item** (Resolution 4).
|
|
193
193
|
|
|
194
194
|
**Per-line provenance (the invariant, mechanized).** Every drafted line carries `[from: fact-<slug>]` for each contributing card. A line with no such tag is a **defect** — not presented (Acceptance A2). On accept the tag is stripped from the final doc prose (it was review scaffolding); the durable forward-link survives as `digested_into:` (Resolution 3) — so traceability is preserved without polluting human-owned prose.
|
|
195
195
|
|
|
@@ -1,15 +1,15 @@
|
|
|
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) record an architecture decision (ADR), (6) create or update the project root README, (7) create or update a plan, (8) derive
|
|
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 a feature doc's `owns:` frontmatter (the code-path globs it owns) 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 **`maintenance` agent (baseline mode)** (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
|
|
7
7
|
|
|
8
|
-
**This skill is a template & generator library, not an orchestrator.** It supplies the templates, the
|
|
8
|
+
**This skill is a template & generator library, not an orchestrator.** It supplies the templates, the frontmatter-derivation generator, and the co-authoring workflow that _agents_ call to produce individual docs. It does **not** baseline, audit, or reconcile a repo's doc tree — that is the **`maintenance` agent (baseline mode)**, which calls this skill for each template it scaffolds. Reach here to generate _one_ doc from a template; reach for the `maintenance` agent (baseline mode) to bring a whole repo into shape.
|
|
9
9
|
|
|
10
10
|
Document contracts and architecture, not implementation details. Show function signatures and API shapes — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments. Breaking changes belong in changelogs only, not module docs.
|
|
11
11
|
|
|
12
|
-
**No redirect docs.** When moving a doc to a new location, delete the old file entirely. Update all references (
|
|
12
|
+
**No redirect docs.** When moving a doc to a new location, delete the old file entirely. Update all references (cross-doc links, memory files) to point to the new path. Never leave a stub file that says "Moved to X" — redirect docs rot, clutter the repo, and create false search hits.
|
|
13
13
|
|
|
14
14
|
**Present tense, current state only.** Active docs (everything outside `docs/history/`) describe the system _as it is now_ — what exists and how it works today. They never narrate how it got there: no migration/fold history, no dated "shipped/verified/built on YYYY-MM-DD" markers, no "ex-`@nurix/X`, folded 2026-06-12" provenance, no "was X → now Y" change journeys, no "removed/deleted in the <date> fold". The historical record — when and how things changed — lives **only** in `docs/history/` (changelog, plans, ADRs); `docs/memory/` is the agent's dated log and is likewise exempt. A doc may cite an ADR for the _why_ (the decision rationale), but must not narrate the _when/how it changed_. Routing/index docs point only to current authority docs — never to a historical plan or changelog as the "read first" source. When you find historical narration in an active doc, rewrite it to the present-tense fact and let `docs/history/` carry the story.
|
|
15
15
|
|
|
@@ -20,7 +20,7 @@ Document contracts and architecture, not implementation details. Show function s
|
|
|
20
20
|
```
|
|
21
21
|
User request
|
|
22
22
|
│
|
|
23
|
-
├─ "Baseline/reconcile docs" ──────▶
|
|
23
|
+
├─ "Baseline/reconcile docs" ──────▶ maintenance agent (baseline mode) (it calls this skill per template)
|
|
24
24
|
│
|
|
25
25
|
├─ "Document feature/module" ──────▶ Module Template
|
|
26
26
|
│
|
|
@@ -54,25 +54,25 @@ User request
|
|
|
54
54
|
|
|
55
55
|
---
|
|
56
56
|
|
|
57
|
-
##
|
|
57
|
+
## Frontmatter Derivation
|
|
58
58
|
|
|
59
|
-
When creating or updating a feature doc, derive its **`
|
|
59
|
+
When creating or updating a feature doc, derive its **`owns:` frontmatter** — the code-path globs it is canonical for — from the source the doc describes. Code ownership lives in each feature doc's `owns:` frontmatter (the SessionStart hook unions them into the injected ownership index); there is no hand-maintained ownership map.
|
|
60
60
|
|
|
61
61
|
### When to run
|
|
62
62
|
|
|
63
|
-
- **Baseline / reconcile** — for every feature doc whose code paths aren't yet
|
|
64
|
-
- **New feature doc** — when creating a doc via the Feature/Module template,
|
|
65
|
-
- **Doc update** — when the documented scope changes, update the doc's
|
|
63
|
+
- **Baseline / reconcile** — for every feature doc whose code paths aren't yet declared in its `owns:` frontmatter (the `maintenance` agent (baseline mode) calls this)
|
|
64
|
+
- **New feature doc** — when creating a doc via the Feature/Module template, project its `owns:` globs
|
|
65
|
+
- **Doc update** — when the documented scope changes, update the doc's `owns:` globs
|
|
66
66
|
|
|
67
|
-
### How to derive
|
|
67
|
+
### How to derive the frontmatter
|
|
68
68
|
|
|
69
|
-
A
|
|
69
|
+
A feature doc's launch-map frontmatter is `owns:` (required), `module:` (optional), `keywords:` (required), and `status:` (required).
|
|
70
70
|
|
|
71
|
-
**1.
|
|
71
|
+
**1. `owns:`** (the path scope)
|
|
72
72
|
|
|
73
|
-
Read the doc's content. Extract every source file path it references (file listings, function locations, component paths). Group them into the narrowest glob patterns that cover all referenced files without overlapping another doc's
|
|
73
|
+
Read the doc's content. Extract every source file path it references (file listings, function locations, component paths). Group them into the narrowest glob patterns that cover all referenced files without overlapping another doc's `owns:` globs at equal specificity. A doc may own several globs.
|
|
74
74
|
|
|
75
|
-
| Doc references |
|
|
75
|
+
| Doc references | Glob |
|
|
76
76
|
| ------------------------------------ | ------------------------- |
|
|
77
77
|
| Multiple files under one directory | `src/feature/**` |
|
|
78
78
|
| Specific files in a shared directory | List each file explicitly |
|
|
@@ -80,22 +80,22 @@ Read the doc's content. Extract every source file path it references (file listi
|
|
|
80
80
|
|
|
81
81
|
Glob each pattern against the codebase; drop any that match nothing.
|
|
82
82
|
|
|
83
|
-
**2.
|
|
83
|
+
**2. `module:`**
|
|
84
84
|
|
|
85
|
-
The
|
|
85
|
+
The single bounded-context label this feature belongs to, or omit it for a cross-cutting feature that belongs to no single context. A module is a label, not a folder — features sharing a `module:` value are what ties that module to code (a filter over the generated ownership index).
|
|
86
86
|
|
|
87
|
-
**3.
|
|
87
|
+
**3. `keywords:` & `status:`**
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
`keywords:` are the discovery terms topic→doc lookup rides. `status:` is `active`, `draft`, or `deprecated` — it steers the model toward live docs and away from draft/deprecated ones.
|
|
90
90
|
|
|
91
|
-
|
|
91
|
+
A doc's dependencies on other docs are expressed inline in its prose (links); cross-cutting contracts are diagnosed by the `boundary` skill from source, not persisted.
|
|
92
92
|
|
|
93
93
|
### Rules
|
|
94
94
|
|
|
95
|
-
- One canonical doc per path. A
|
|
95
|
+
- One canonical doc per path. A doc's `owns:` globs must not overlap another doc's at equal specificity — the narrower glob wins; equal-specificity overlap is an ownership conflict to resolve.
|
|
96
96
|
- Use glob patterns for directories, explicit paths for individual files. Don't list paths that don't exist in the codebase.
|
|
97
|
-
- When a doc covers a deep feature with sub-specs (e.g., `editor/`), each sub-spec
|
|
98
|
-
- For baseline/reconcile with many docs, use parallel sub-agents to read source and propose
|
|
97
|
+
- When a doc covers a deep feature with sub-specs (e.g., `editor/`), each sub-spec owns its own globs — don't duplicate a path across siblings.
|
|
98
|
+
- For baseline/reconcile with many docs, use parallel sub-agents to read source and propose `owns:` globs.
|
|
99
99
|
|
|
100
100
|
---
|
|
101
101
|
|
|
@@ -119,6 +119,6 @@ For docs that don't match templates:
|
|
|
119
119
|
|
|
120
120
|
| File | Use For |
|
|
121
121
|
| --- | --- |
|
|
122
|
-
| `references/templates.md` | docs/README.md, structure.md,
|
|
122
|
+
| `references/templates.md` | docs/README.md, structure.md, the feature-frontmatter contract, scaffolds (CHANGELOG, backlog, memory), feature, changelog, plan, protected files, ADR, project root README templates |
|
|
123
123
|
| `references/style-guide.md` | Writing rules, formatting conventions |
|
|
124
124
|
| `references/examples.md` | Good vs bad documentation examples |
|