@nurix/etna 0.19.25 → 0.19.26
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 +1 -1
- package/bin/etna.js +3 -3
- package/data/harness-index.json +1 -1
- package/data/harnesses/code/CLAUDE.md +7 -6
- package/data/harnesses/code/agents/maintenance.md +3 -3
- package/data/harnesses/code/agents/retro.md +20 -19
- package/data/harnesses/code/codex/agents/maintenance.toml +5 -5
- package/data/harnesses/code/codex/agents/retro.toml +21 -19
- package/data/harnesses/code/harness.json +2 -2
- package/data/harnesses/code/rules/changelog.md +37 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +1 -2
- package/data/harnesses/code/skills/documentation/templates/changelog-entry.md +41 -46
- package/data/harnesses/code/skills/documentation/templates/structure.md +2 -4
- package/data/harnesses/etna/CLAUDE.md +27 -1
- package/data/harnesses/etna/agents/maintenance.md +3 -3
- package/data/harnesses/etna/agents/retro.md +46 -0
- package/data/harnesses/etna/codex/agents/maintenance.toml +5 -5
- package/data/harnesses/etna/codex/agents/retro.toml +45 -0
- package/data/harnesses/etna/harness.json +2 -2
- package/data/harnesses/etna/rules/changelog.md +37 -0
- package/data/harnesses/etna/skills/documentation/SKILL.md +1 -2
- package/data/harnesses/etna/skills/documentation/templates/changelog-entry.md +41 -46
- package/data/harnesses/etna/skills/documentation/templates/structure.md +2 -4
- package/package.json +2 -2
- package/data/harnesses/code/skills/documentation/templates/refinement-ledger.md +0 -33
- package/data/harnesses/etna/skills/documentation/templates/refinement-ledger.md +0 -33
package/README.md
CHANGED
|
@@ -117,4 +117,4 @@ npm run build:data
|
|
|
117
117
|
|
|
118
118
|
## Publishing
|
|
119
119
|
|
|
120
|
-
CI auto-publishes on push to `dev` when `packages/cli/**` or `harness/**` change — see [`.github/workflows/publish-etna-to-npm.yml`](../../.github/workflows/publish-etna-to-npm.yml). The `publishConfig.access` is `
|
|
120
|
+
CI auto-publishes on push to `dev` when `packages/cli/**` or `harness/**` change — see [`.github/workflows/publish-etna-to-npm.yml`](../../.github/workflows/publish-etna-to-npm.yml). The `publishConfig.access` is `public`, so `npx @nurix/etna` installs and self-updates without any npm token. Publishing still requires auth: the `NPM_PUBLISH_TOKEN` GitHub Actions secret must be a granular access token with **Bypass 2FA** enabled — classic automation tokens are rejected by the npmjs.com 2FA policy on the `nurix-tools` account.
|
package/bin/etna.js
CHANGED
|
@@ -484,9 +484,9 @@ function parseArgs(args) {
|
|
|
484
484
|
//
|
|
485
485
|
// Guards: ETNA_SELFUPDATED=1 is set on the child to stop an infinite re-exec loop;
|
|
486
486
|
// ETNA_NO_SELFUPDATE lets a caller opt out (CI, offline, or running an intentionally
|
|
487
|
-
// pinned/local-dev build). Degrades gracefully — any failure (offline,
|
|
488
|
-
//
|
|
489
|
-
// `npm view`
|
|
487
|
+
// pinned/local-dev build). Degrades gracefully — any failure (offline, npm/npx missing)
|
|
488
|
+
// falls through to running THIS copy. @nurix/etna publishes with public access, so the
|
|
489
|
+
// `npm view` and the re-exec `npx` both resolve unauthenticated — no npm token needed.
|
|
490
490
|
function selfUpdateOrReexec() {
|
|
491
491
|
if (process.env.ETNA_SELFUPDATED || process.env.ETNA_NO_SELFUPDATE) return;
|
|
492
492
|
const here = readJson(join(pkgRoot, 'package.json')).version;
|
package/data/harness-index.json
CHANGED
|
@@ -71,7 +71,7 @@ Boundaries are **diagnosed, not documented** — the `boundary` skill derives th
|
|
|
71
71
|
|
|
72
72
|
- **Every markdown document goes through the `documentation` skill.** Before creating or substantively editing any `.md` document — a doc, a README, an index, a record — invoke the `documentation` skill and apply its templates and `references/style-guide.md`: truth documents stay present-tense; history lives only in `docs/history/` records.
|
|
73
73
|
- **[override]** Keep `docs/` updated when code changes affect documented behavior. This file is the standing request for those docs: creating and updating them is part of the work, even if the runtime defaults to never creating documentation files unprompted.
|
|
74
|
-
- After plan completion **[override]**:
|
|
74
|
+
- After plan completion **[override]**: write the `docs/history/changelog/` entry as a **draft** immediately, while the context is fresh — no confirmation needed — and append its `docs/history/CHANGELOG.md` row; the commit fills what the draft left open and freezes it. Non-plan work needs no separate prompt: every non-exempt commit carries its own entry (the `changelog` rule).
|
|
75
75
|
- When moving or renaming source files: update the `owns:` globs of the feature doc that owns them so the generated ownership index stays accurate. A new doc that owns code declares its paths in its own `owns:` frontmatter — there is no separate map to update.
|
|
76
76
|
- `docs/structure.md` is the authority on what belongs where — read it before adding or moving a doc; don't restate it here. One canonical source per topic — link, don't copy. Only `CLAUDE.md`, `AGENTS.md`, and `README.md` live at the repo root.
|
|
77
77
|
|
|
@@ -93,13 +93,14 @@ When recording a learning, ask: _is this true of this project, or true of this u
|
|
|
93
93
|
|
|
94
94
|
---
|
|
95
95
|
|
|
96
|
-
##
|
|
96
|
+
## Changelog
|
|
97
97
|
|
|
98
|
-
A commit marks the user's behavioral verification of the work, and the
|
|
98
|
+
A commit marks the user's behavioral verification of the work, and the working session is the last holder of the refinement context that produced it — asks, iterations, rejections, skill outcomes, discoveries. That context is captured in the changelog and distilled on demand. The `changelog` rule carries the trigger and the lifecycle; this is the policy:
|
|
99
99
|
|
|
100
|
-
- **Every non-mechanical commit
|
|
101
|
-
- **
|
|
102
|
-
- **
|
|
100
|
+
- **Every non-mechanical commit is covered by an entry** at `docs/history/changelog/YYYY-MM-DD-{three-words}.md`, staged inside the commit it describes — whatever tool or session performs the commit — plus a row in `docs/history/CHANGELOG.md`. Format, required fields, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`; the failure fields (rejected attempts, overridden skill output) and verbatim taste quotes are required, not optional — the entry's value concentrates there.
|
|
101
|
+
- **An entry may exist before its commit.** A plan reaching `Status: Complete` writes its entry as a **draft** immediately, while the context is fresh; the commit fills what the draft left open. **Immutability begins at commit, not creation** — a draft is mutable, a committed entry never is, and a correction is a new entry that links back. Doc-health passes skip the genre.
|
|
102
|
+
- **A commit is the smallest unit an entry may describe**; above that the mapping is judgment. Work exceeding a draft's scope gets a *second* entry rather than stretching the first.
|
|
103
|
+
- **Distillation is the `retro` agent** — run on demand (before a brainstorm or LLD, before a new project, after a refinement arc), it converts accumulated entries into a typed punch list (doc content, doc structure, skill evolution, pins, harness rules), appends actionable items to the backlog, and proposes only — application runs through the normal documentation loop.
|
|
103
104
|
|
|
104
105
|
---
|
|
105
106
|
|
|
@@ -137,8 +137,7 @@ docs/
|
|
|
137
137
|
│ └── {topic}-brainstorm/ # created by the `brainstorm` skill; NOT scaffolded empty; moves to history/brainstorms/ on a passed harvest
|
|
138
138
|
├── history/
|
|
139
139
|
│ ├── CHANGELOG.md # Master changelog index
|
|
140
|
-
│ ├── changelog/ # Individual entries
|
|
141
|
-
│ ├── ledger/ # Refinement Ledger — append-only per-commit refinement journal (YYYY-MM.md; written at commit time, NOT scaffolded empty)
|
|
140
|
+
│ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
|
|
142
141
|
│ ├── plans/ # Implementation plans (Status field required)
|
|
143
142
|
│ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
|
|
144
143
|
│ └── backlog.md # Tracked work items by priority (P0-P3)
|
|
@@ -168,6 +167,7 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
|
|
|
168
167
|
| repo-wide `docs/pillars/` | cross-module doctrine → `docs/architecture/`; delete the folder |
|
|
169
168
|
| `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/` |
|
|
170
169
|
| `docs/OWNERSHIP_INDEX.md` (legacy derived ownership index) | delete — ownership is the union of feature `owns:` frontmatter, surfaced by the generated index |
|
|
170
|
+
| `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
|
|
171
171
|
| `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
|
|
172
172
|
| `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
|
|
173
173
|
| a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
|
|
@@ -201,7 +201,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
|
|
|
201
201
|
## Rules
|
|
202
202
|
|
|
203
203
|
- **Never delete feature docs** — only update or flag for review.
|
|
204
|
-
- **Never modify `docs/history/plans
|
|
204
|
+
- **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
|
|
205
205
|
- **Preserve existing doc structure and formatting** when updating.
|
|
206
206
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
207
207
|
- **Be specific:** include file paths, line numbers, and what changed.
|
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: retro
|
|
3
|
-
description: Session-distillation agent for the
|
|
3
|
+
description: Session-distillation agent for the changelog. Reads the per-unit-of-work entries under `docs/history/changelog/` accumulated since its last run and distills the refinement delta — what user-driven iteration added that the one-shot build lacked — into a typed punch list of doc-content gaps, doc-structure moves (missing doc / mothership split / merge), skill-evolution findings backed by survived-vs-overridden counts, unpinned discoveries needing an enforced artifact (test, token, guardrail, schema), and cross-project harness rules. Proposes only — actionable items land in the backlog, never applied directly. Run on demand: before a brainstorm or LLD session, before starting a new project, or after a refinement arc. Triggers on "run retro", "distill the changelog", "refinement retro", "/retro".
|
|
4
4
|
tools: Read, Glob, Grep, Bash, Write, Edit
|
|
5
5
|
model: inherit
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
# Retro —
|
|
8
|
+
# Retro — changelog distillation
|
|
9
9
|
|
|
10
|
-
You distill refinement history into documentation and harness feedback. Your input is the
|
|
10
|
+
You distill refinement history into documentation and harness feedback. Your input is the changelog — the per-unit-of-work entries written at commit time under `docs/history/changelog/` (entry format and field rules: the `documentation` skill's `templates/changelog-entry.md`). Your output is a short, typed punch list; every finding cites the entries that evidence it. You propose — you never apply.
|
|
11
11
|
|
|
12
12
|
## Before starting
|
|
13
13
|
|
|
14
|
-
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last
|
|
15
|
-
2. Collect the input set: every
|
|
16
|
-
3.
|
|
14
|
+
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last entry seen); below it live prior skill-efficacy tallies and suppressed findings. No file ⇒ first run ⇒ distill everything. **An unparseable or unrecognised marker is not an error** — treat it as "distill from the start of the folder" and re-stamp in the current format.
|
|
15
|
+
2. Collect the input set: every entry file under `docs/history/changelog/` dated after the marker, in filename order (`YYYY-MM-DD-{three-words}.md` sorts chronologically). Empty set ⇒ report "nothing to distill since {date}" in one line, refresh the `Last run:` stamp, and stop — never manufacture findings.
|
|
16
|
+
3. **Skip entries carrying no field block.** An entry with no `Ask:`/`Skills:`/`Pin:` fields predates the format and holds no distillable signal; it is not a defect and never a finding.
|
|
17
|
+
4. Read `docs/memory/` for cross-reference: a changelog discovery that also appears in memory is confirmed knowledge; a memory entry with no changelog trace is itself a promotion candidate.
|
|
17
18
|
|
|
18
19
|
## Distill
|
|
19
20
|
|
|
20
|
-
Classify every finding into exactly one bucket. Work from the
|
|
21
|
+
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
21
22
|
|
|
22
|
-
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing
|
|
23
|
-
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the
|
|
24
|
-
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the
|
|
25
|
-
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any
|
|
23
|
+
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
24
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the union of feature-doc `owns:` globs (glob `docs/features/`).
|
|
25
|
+
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
26
|
+
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
26
27
|
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
27
28
|
|
|
28
29
|
## Report & record
|
|
29
30
|
|
|
30
|
-
1. Report in chat, ≤2 pages: a four-line scoreboard (
|
|
31
|
+
1. Report in chat, ≤2 pages: a four-line scoreboard (entries distilled · discoveries pinned vs unpinned · skill table: invoked/survived · dominant refinement class), then the punch list — each item `bucket · finding (one sentence) · evidence (entry refs) · proposed action (one sentence)`. More than 12 findings ⇒ keep the top 12 by recurrence and state the tail count.
|
|
31
32
|
2. Append the actionable items to `docs/history/backlog.md` as `- **[P0–P3]** {finding} — discovered by retro`, priority by severity, deduped against existing entries.
|
|
32
33
|
3. Update `docs/memory/retro.md` (create on first write). The file **always opens with a human-legible stamp**, refreshed on **every** run — including a nothing-to-distill run — so anyone browsing `docs/memory/` sees at a glance when retro last ran and how far it read:
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
```
|
|
36
|
+
Last run: {YYYY-MM-DD} · {N} entries distilled (through {last entry filename}) · {M} findings → backlog
|
|
37
|
+
```
|
|
37
38
|
|
|
38
|
-
|
|
39
|
+
Below the stamp: updated skill-efficacy tallies and findings the user declined (suppressed, not re-raised), as dated entries `## YYYY-MM-DD — {topic}`.
|
|
39
40
|
|
|
40
41
|
## Rules
|
|
41
42
|
|
|
42
|
-
- **Evidence or silence** — no finding without
|
|
43
|
-
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or
|
|
44
|
-
- **
|
|
43
|
+
- **Evidence or silence** — no finding without entry citations; a clean report is valid.
|
|
44
|
+
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or changelog entries; application runs through the normal documentation loop in the main session.
|
|
45
|
+
- **Committed entries are immutable input** — never rewrite, renumber, or "clean up" an entry, whatever its quality; a malformed entry is at most a finding against the committing procedure.
|
|
45
46
|
- **Respect suppressions** in `docs/memory/retro.md` — a declined finding is recorded once, never re-raised every run.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name = "maintenance"
|
|
3
3
|
description = "The single docs steward. Default behavior is the docs-vs-code coherence audit — detects and fixes docs drifting from code (stale docs, broken ownership, unowned source paths, architecture/backlog drift). An additive **baseline mode** layers structural reconcile on top: when the repo's `harness-version` marker is missing or behind, it converges `docs/` to the installed harness shape (scaffold the standard tree, fold dissolved-shape artifacts forward, stamp the version, propose modules) before running the audit. Mode is auto-selected from the marker. Run weekly, after major changes, or to baseline/upgrade a repo. Cross-cutting contract analysis is the `boundary` skill (`check` for plans, `scan` for diffs) — it derives contracts dynamically from source; there are no persisted boundary docs to audit. Triggers on \"run maintenance\", \"docs health\", \"baseline this repo\", \"reconcile the harness\", \"upgrade the harness\", \"is this repo on the current harness\", \"/maintenance\"."
|
|
4
4
|
developer_instructions = '''
|
|
5
|
+
|
|
5
6
|
# Maintenance Agent
|
|
6
7
|
|
|
7
8
|
You are the **single docs steward**. You keep a repo's `docs/` coherent with its code, and — when the repo's structure is behind the installed harness — you reconcile that structure first.
|
|
@@ -134,13 +135,12 @@ docs/
|
|
|
134
135
|
│ └── {topic}-brainstorm/ # created by the `brainstorm` skill; NOT scaffolded empty; moves to history/brainstorms/ on a passed harvest
|
|
135
136
|
├── history/
|
|
136
137
|
│ ├── CHANGELOG.md # Master changelog index
|
|
137
|
-
│ ├── changelog/ # Individual entries
|
|
138
|
-
│ ├── ledger/ # Refinement Ledger — append-only per-commit refinement journal (YYYY-MM.md; written at commit time, NOT scaffolded empty)
|
|
138
|
+
│ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
|
|
139
139
|
│ ├── plans/ # Implementation plans (Status field required)
|
|
140
140
|
│ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
|
|
141
141
|
│ └── backlog.md # Tracked work items by priority (P0-P3)
|
|
142
142
|
├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
|
|
143
|
-
└── tests/ #
|
|
143
|
+
└── tests/ # Behavioral test checklists ({feature}.md, step → **Assert**), derived at plan Completion via the `documentation` skill; author-maintained, present only when test docs exist
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillars/`**, **no `docs/boundaries/`**. Code ownership lives in feature `owns:` frontmatter; a module is a `module:` label, not a folder; boundaries are diagnosed from source; brainstorm records live in `docs/research/` (active) and `docs/history/brainstorms/` (harvested).
|
|
@@ -149,7 +149,7 @@ There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillar
|
|
|
149
149
|
|
|
150
150
|
### Step B1 — Inventory and classify
|
|
151
151
|
|
|
152
|
-
Glob every markdown file. Classify each: Architecture, Features, Operations, Plans, Changelogs, Backlog, Brainstorm records (stay), Stale/Deprecated (delete), Root docs (stay). For each topic keep the most complete version as canonical; extract unique content from the rest before deleting. **No redirect stubs** — when you move a file, delete the original and fix every reference (cross-doc links, memory files). Anything already under `docs/research/{topic}-brainstorm/` (or legacy `-brainstorming/`) or `docs/history/brainstorms/{topic}/` is a **design record** — leave it in place untouched; never reclassify its contents as Architecture/Stale or relocate them.
|
|
152
|
+
Glob every markdown file. Classify each: Architecture, Features, Operations, Tests (behavioral checklists — stay), Plans, Changelogs, Backlog, Brainstorm records (stay), Stale/Deprecated (delete), Root docs (stay). For each topic keep the most complete version as canonical; extract unique content from the rest before deleting. **No redirect stubs** — when you move a file, delete the original and fix every reference (cross-doc links, memory files). Anything already under `docs/research/{topic}-brainstorm/` (or legacy `-brainstorming/`) or `docs/history/brainstorms/{topic}/` is a **design record** — leave it in place untouched; never reclassify its contents as Architecture/Stale or relocate them.
|
|
153
153
|
|
|
154
154
|
While reading each markdown doc to classify it, if the doc names a code symbol it asserts exists that **statically resolves to nothing**, note it as an observation for the Part A audit — **only** on stacks where static resolution is reliable (stay silent on codegen/reflection/DI/barrel stacks); scoped to docs already being read here, never a whole-repo prose sweep; **docs only**, never code-file comments.
|
|
155
155
|
|
|
@@ -198,7 +198,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
|
|
|
198
198
|
## Rules
|
|
199
199
|
|
|
200
200
|
- **Never delete feature docs** — only update or flag for review.
|
|
201
|
-
- **Never modify `docs/history/plans
|
|
201
|
+
- **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
|
|
202
202
|
- **Preserve existing doc structure and formatting** when updating.
|
|
203
203
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
204
204
|
- **Be specific:** include file paths, line numbers, and what changed.
|
|
@@ -1,43 +1,45 @@
|
|
|
1
1
|
# dropped Claude tools: Read, Glob, Grep, Bash, Write, Edit
|
|
2
2
|
name = "retro"
|
|
3
|
-
description = "Session-distillation agent for the
|
|
3
|
+
description = "Session-distillation agent for the changelog. Reads the per-unit-of-work entries under `docs/history/changelog/` accumulated since its last run and distills the refinement delta — what user-driven iteration added that the one-shot build lacked — into a typed punch list of doc-content gaps, doc-structure moves (missing doc / mothership split / merge), skill-evolution findings backed by survived-vs-overridden counts, unpinned discoveries needing an enforced artifact (test, token, guardrail, schema), and cross-project harness rules. Proposes only — actionable items land in the backlog, never applied directly. Run on demand: before a brainstorm or LLD session, before starting a new project, or after a refinement arc. Triggers on \"run retro\", \"distill the changelog\", \"refinement retro\", \"/retro\"."
|
|
4
4
|
developer_instructions = '''
|
|
5
|
-
# Retro — Refinement Ledger distillation
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
# Retro — changelog distillation
|
|
7
|
+
|
|
8
|
+
You distill refinement history into documentation and harness feedback. Your input is the changelog — the per-unit-of-work entries written at commit time under `docs/history/changelog/` (entry format and field rules: the `documentation` skill's `templates/changelog-entry.md`). Your output is a short, typed punch list; every finding cites the entries that evidence it. You propose — you never apply.
|
|
8
9
|
|
|
9
10
|
## Before starting
|
|
10
11
|
|
|
11
|
-
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last
|
|
12
|
-
2. Collect the input set: every
|
|
13
|
-
3.
|
|
12
|
+
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last entry seen); below it live prior skill-efficacy tallies and suppressed findings. No file ⇒ first run ⇒ distill everything. **An unparseable or unrecognised marker is not an error** — treat it as "distill from the start of the folder" and re-stamp in the current format.
|
|
13
|
+
2. Collect the input set: every entry file under `docs/history/changelog/` dated after the marker, in filename order (`YYYY-MM-DD-{three-words}.md` sorts chronologically). Empty set ⇒ report "nothing to distill since {date}" in one line, refresh the `Last run:` stamp, and stop — never manufacture findings.
|
|
14
|
+
3. **Skip entries carrying no field block.** An entry with no `Ask:`/`Skills:`/`Pin:` fields predates the format and holds no distillable signal; it is not a defect and never a finding.
|
|
15
|
+
4. Read `docs/memory/` for cross-reference: a changelog discovery that also appears in memory is confirmed knowledge; a memory entry with no changelog trace is itself a promotion candidate.
|
|
14
16
|
|
|
15
17
|
## Distill
|
|
16
18
|
|
|
17
|
-
Classify every finding into exactly one bucket. Work from the
|
|
19
|
+
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
18
20
|
|
|
19
|
-
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing
|
|
20
|
-
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the
|
|
21
|
-
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the
|
|
22
|
-
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any
|
|
21
|
+
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
22
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the union of feature-doc `owns:` globs (glob `docs/features/`).
|
|
23
|
+
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
24
|
+
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
23
25
|
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
24
26
|
|
|
25
27
|
## Report & record
|
|
26
28
|
|
|
27
|
-
1. Report in chat, ≤2 pages: a four-line scoreboard (
|
|
29
|
+
1. Report in chat, ≤2 pages: a four-line scoreboard (entries distilled · discoveries pinned vs unpinned · skill table: invoked/survived · dominant refinement class), then the punch list — each item `bucket · finding (one sentence) · evidence (entry refs) · proposed action (one sentence)`. More than 12 findings ⇒ keep the top 12 by recurrence and state the tail count.
|
|
28
30
|
2. Append the actionable items to `docs/history/backlog.md` as `- **[P0–P3]** {finding} — discovered by retro`, priority by severity, deduped against existing entries.
|
|
29
31
|
3. Update `docs/memory/retro.md` (create on first write). The file **always opens with a human-legible stamp**, refreshed on **every** run — including a nothing-to-distill run — so anyone browsing `docs/memory/` sees at a glance when retro last ran and how far it read:
|
|
30
32
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
```
|
|
34
|
+
Last run: {YYYY-MM-DD} · {N} entries distilled (through {last entry filename}) · {M} findings → backlog
|
|
35
|
+
```
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
Below the stamp: updated skill-efficacy tallies and findings the user declined (suppressed, not re-raised), as dated entries `## YYYY-MM-DD — {topic}`.
|
|
36
38
|
|
|
37
39
|
## Rules
|
|
38
40
|
|
|
39
|
-
- **Evidence or silence** — no finding without
|
|
40
|
-
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or
|
|
41
|
-
- **
|
|
41
|
+
- **Evidence or silence** — no finding without entry citations; a clean report is valid.
|
|
42
|
+
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or changelog entries; application runs through the normal documentation loop in the main session.
|
|
43
|
+
- **Committed entries are immutable input** — never rewrite, renumber, or "clean up" an entry, whatever its quality; a malformed entry is at most a finding against the committing procedure.
|
|
42
44
|
- **Respect suppressions** in `docs/memory/retro.md` — a declined finding is recorded once, never re-raised every run.
|
|
43
45
|
'''
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Every unit of work leaves one record: `docs/history/changelog/YYYY-MM-DD-{three-words}.md`. The three words name the work, not the commit. Format, field rules, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`.
|
|
4
|
+
|
|
5
|
+
An entry is not a summary line. It carries the refinement context only the working session holds — the ask in the user's own words, what was rejected, which skills survived or were overridden, what running the thing taught, what now guards it.
|
|
6
|
+
|
|
7
|
+
## When an entry is owed
|
|
8
|
+
|
|
9
|
+
| Trigger | What to write |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| A plan reaches `Status: Complete` | A draft entry for that plan, linked to it — written now, while the session still holds the context |
|
|
12
|
+
| The user asks for a changelog | The entry for the work in hand. No commit required |
|
|
13
|
+
| A commit is made | Every non-exempt commit is covered by an entry — the commit skill writes or completes it |
|
|
14
|
+
|
|
15
|
+
**Exempt** (closed list): release and bot commits, harness installs and bumps, lockfile-only changes, pure renames and moves, and changelog housekeeping itself.
|
|
16
|
+
|
|
17
|
+
## The entry's life
|
|
18
|
+
|
|
19
|
+
| State | Meaning |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| **Draft** | Created before its commit exists. Mutable — fields filled as far as the session can |
|
|
22
|
+
| **Complete** | Missing fields filled in from the diff and the session |
|
|
23
|
+
| **Frozen** | The moment it rides in a commit. Never edited again |
|
|
24
|
+
|
|
25
|
+
**Immutability begins at commit, not at creation.** A draft in the working tree is meant to be edited — that is what lets a completed plan record its context before anything is committed. Once an entry is committed it is history: a correction is a new entry linking back, never an edit.
|
|
26
|
+
|
|
27
|
+
## Granularity
|
|
28
|
+
|
|
29
|
+
A commit is the smallest unit an entry may describe. Above that the mapping is judgment — four commits may be four entries or one, whichever reads better as history.
|
|
30
|
+
|
|
31
|
+
An entry spanning several commits rides in the **last** of them and names the earlier ones in `Commits:`. An entry can never carry its own commit's SHA, so that field lists predecessors only and is omitted when one entry maps to one commit.
|
|
32
|
+
|
|
33
|
+
When the work done exceeds what a draft describes, do not stretch the draft — write a second entry. The first stays an honest account of the plan; the second records the work beyond it.
|
|
34
|
+
|
|
35
|
+
## The index
|
|
36
|
+
|
|
37
|
+
Every entry appends one row to `docs/history/CHANGELOG.md` — date, link, one-line summary — in the same pass that writes the entry, so the table never trails the folder.
|
|
@@ -60,8 +60,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
60
60
|
| Baseline / reconcile docs | `maintenance` agent (baseline mode) — it calls this skill per template |
|
|
61
61
|
| Document feature/module (LLD) | [`templates/feature.md`](templates/feature.md) |
|
|
62
62
|
| Document data flow / state / Redux | [`templates/feature.md`](templates/feature.md) — they are sections of the feature doc |
|
|
63
|
-
| Create/update changelog | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record) |
|
|
64
|
-
| Record per-commit refinement (ledger block) | [`templates/refinement-ledger.md`](templates/refinement-ledger.md) (record — written at commit time, distilled by the `retro` agent) |
|
|
63
|
+
| Create/update changelog entry | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record — one per unit of work; carries the refinement fields, frozen inside its commit, distilled by the `retro` agent) |
|
|
65
64
|
| Create/update plan | [`templates/plan.md`](templates/plan.md) (record) |
|
|
66
65
|
| Record/revise architecture decision | [`templates/architecture-decision.md`](templates/architecture-decision.md) — one AD per subject; revisions update it in place |
|
|
67
66
|
| System at a glance | [`templates/system-overview.md`](templates/system-overview.md) |
|
|
@@ -1,62 +1,57 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# Changelog Entry
|
|
2
2
|
|
|
3
|
-
Record. Use for:
|
|
3
|
+
Record. Use for: the per-unit-of-work journal of what changed and how it was refined — one file per entry under `docs/history/changelog/YYYY-MM-DD-{three-words}.md`, written by whoever does the work and frozen inside the commit it describes. The three words name the work, not the commit. Trigger and lifecycle policy: the `changelog` rule; distillation is the `retro` agent.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
An entry is not a summary line. Its value concentrates in the fields a diff cannot reconstruct — the ask in the user's own words, what was rejected, which skills survived or were overridden, what running the thing taught.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
# YYYY-MM-DD - [Title]
|
|
9
|
-
|
|
10
|
-
## Summary
|
|
11
|
-
|
|
12
|
-
Brief description of what changed and why.
|
|
13
|
-
|
|
14
|
-
## Changes
|
|
7
|
+
## Entry format
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
```
|
|
10
|
+
# {YYYY-MM-DD} · {surface} — {one-line outcome}
|
|
11
|
+
|
|
12
|
+
**Plan:** [history/plans/YYYY-MM-DD-slug.md](../plans/YYYY-MM-DD-slug.md)
|
|
13
|
+
**Commits:** {sha}, {sha}
|
|
14
|
+
|
|
15
|
+
- **Ask:** {what the user asked, compressed — taste and preference statements quoted verbatim}
|
|
16
|
+
- **Iterations:** {N} · rejected: {what was rejected and why} | none
|
|
17
|
+
- **Skills:** {skill}@{version} — survived | partially survived | overridden ({why, briefly}) | none used
|
|
18
|
+
- **Change:** {added/changed X, which does Y, because Z — behavior first, mechanism second}
|
|
19
|
+
- **Discovered:** {non-obvious fact learned by running the product — environment quirk, platform ceiling, seam behavior, dependency constraint} | none
|
|
20
|
+
- **Class:** {one or more keywords — suggestive vocabulary, not a closed enum; see Field rules}
|
|
21
|
+
- **Pin:** {enforced artifact written in this entry's commit: test / token / guardrail / schema} | none — candidate: {what should hold it}
|
|
22
|
+
```
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
- `oldFunction()` from `path/to/file.js`
|
|
29
|
-
- Replaced by: `newFunction()`
|
|
24
|
+
`**Plan:**` appears only on plan-linked entries. `**Commits:**` appears only when one entry covers several commits, and lists the predecessors — an entry can never carry its own commit's SHA.
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
- `buggyFunction()` in `path/to/file.js`
|
|
33
|
-
- Bug: What was wrong, when it manifested
|
|
34
|
-
- Fix: What changed
|
|
26
|
+
## Lifecycle
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
| State | Meaning |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| **Draft** | Created before its commit exists — typically the moment a plan reaches `Status: Complete`. Mutable; fields filled as far as the session can |
|
|
31
|
+
| **Complete** | Missing fields filled in from the diff and the session |
|
|
32
|
+
| **Frozen** | The moment it rides in a commit. Never edited, renumbered, or reconciled |
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
**Immutability begins at commit, not at creation.** A draft in the working tree is meant to be edited; that is what lets a completed plan capture its context before anything is committed. A committed entry is history — a correction is a new entry that links back. Entries are exempt from doc-health passes by genre: they are history and can never be "wrong".
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
- Old: Previous behavior
|
|
42
|
-
- New: Current behavior
|
|
43
|
-
- Impact: What breaks
|
|
44
|
-
- Migration: How to fix
|
|
36
|
+
## Field rules
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
- **Every field present; "none" stated explicitly.** An absent field is a template violation. Sessions assert success by default — the required `rejected:` and `overridden` entries are the counterweight; an honestly empty failure field is information too.
|
|
39
|
+
- **`surface`** uses the repo's ownership vocabulary — the owning feature doc's topic or an `owns:` path stem — so entries are queryable per surface.
|
|
40
|
+
- **`Ask` quotes taste verbatim.** The user's preference wording is the one thing no skill can infer and no rebuild recovers; the entry is its durable home.
|
|
41
|
+
- **`Skills` records efficacy honestly** — survived / partially survived / overridden with a reason. These verdicts are the raw data the `retro` agent aggregates into skill-evolution findings; sanitizing them into success stories destroys the mechanism's value.
|
|
42
|
+
- **`Discovered` holds what only running the product teaches.** If it was learned in use, it is recorded the same day — this field feeds the pin candidates.
|
|
43
|
+
- **`Class` is a suggestive vocabulary, not a closed enum.** Tag with one or more keywords, preferring an existing term over a synonym so the `retro` agent can cluster; coin a new one when nothing fits — a recurring coinage is itself retro signal that the vocabulary (or the doc set) is missing a category. Suggested keywords: `ux` · `ui` · `visual` · `taste` · `layout` · `motion` · `interaction` · `copy` · `a11y` · `responsiveness` · `navigation` · `state` · `structure` · `architecture` · `seam` · `contract` · `schema` · `data` · `content` · `seed` · `performance` · `caching` · `resilience` · `error-handling` · `security` · `auth` · `observability` · `logging` · `testing` · `tooling` · `dependency` · `ops` · `deploy` · `env` · `ci` · `i18n` · `docs`.
|
|
44
|
+
- **`Pin` closes the loop:** the enforced artifact written in this commit, or the named candidate for the `retro` agent to flag. A taste-verified behavior with `Pin: none` and no candidate is a template smell.
|
|
45
|
+
- **Out-of-session entries** (the writing session did not do the work): fill what the diff and conversation evidence support; mark the rest `unknown — committed out-of-session`.
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
## Granularity
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
2. {Step}
|
|
49
|
+
A commit is the smallest unit an entry may describe. Above that the mapping is judgment — four commits may be four entries or one. When the work exceeds what a draft describes, write a **second** entry rather than stretching the first: the plan-linked entry stays an honest account of the plan.
|
|
52
50
|
|
|
53
|
-
##
|
|
51
|
+
## The index
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
- A future agent diagnosing a regression starts from this evidence
|
|
53
|
+
Every entry appends one row to `docs/history/CHANGELOG.md` — date, link, one-line summary — in the same pass that writes the entry.
|
|
57
54
|
|
|
58
|
-
##
|
|
55
|
+
## Exemptions (closed list)
|
|
59
56
|
|
|
60
|
-
-
|
|
61
|
-
- `src/path/file2.js` - Supporting updates
|
|
62
|
-
```
|
|
57
|
+
No entry for: release and bot commits, harness installs and bumps, lockfile-only changes, pure renames and moves, and changelog housekeeping itself. Everything else gets an entry, however short.
|
|
@@ -29,8 +29,7 @@ Each topic has one canonical location. Read from here, not from plans or changel
|
|
|
29
29
|
| Environment / config surface | `docs/operations/` | environment.md |
|
|
30
30
|
| Testing strategy | `docs/tests/` | strategy.md |
|
|
31
31
|
| Historical plans | `docs/history/plans/` | YYYY-MM-DD-name.md |
|
|
32
|
-
| Change records | `docs/history/changelog/` |
|
|
33
|
-
| Refinement Ledger | `docs/history/ledger/` | YYYY-MM.md (append-only, written at commit time) |
|
|
32
|
+
| Change records | `docs/history/changelog/` | `YYYY-MM-DD-{three-words}.md` — one per unit of work, written at commit time |
|
|
34
33
|
| Migration runbooks | `docs/history/migrations/` | YYYY-MM-DD-name.md |
|
|
35
34
|
| Deep-research artifacts | `docs/history/research/{topic}/` | README.md + findings.md + sources.md |
|
|
36
35
|
| Brainstorm design records | `docs/research/{topic}-brainstorm/` (active; legacy `-brainstorming/`) → `docs/history/brainstorms/{topic}/` (harvested; user deletes or commits) | thesis.md + forks.md + ledger.md + state.md |
|
|
@@ -51,8 +50,7 @@ Every doc is a **truth document** (states current absolutes, topic-named, update
|
|
|
51
50
|
- `docs/operations/`: How-to procedures for setup, development, and deployment, plus the environment registry. Update when workflows change. One-shot migrations do NOT live here — they are records (`docs/history/migrations/`).
|
|
52
51
|
- `docs/tests/`: Testing strategy and test docs. Present when the repo has a test posture worth documenting.
|
|
53
52
|
- `docs/history/plans/`: Records. Must have `Status:` field. Never modify after completion.
|
|
54
|
-
- `docs/history/changelog/`: Records.
|
|
55
|
-
- `docs/history/ledger/`: Records. The Refinement Ledger — an append-only per-commit refinement journal (monthly `YYYY-MM.md` files) written by the committing agent, each block staged inside the commit it describes; block format is the `documentation` skill's `templates/refinement-ledger.md`, distillation is the `retro` agent. Blocks are immutable — never edited, never reconciled; the folder is never scaffolded empty.
|
|
53
|
+
- `docs/history/changelog/`: Records. One entry per unit of work (`YYYY-MM-DD-{three-words}.md`), written by whoever does the work and frozen inside the commit it describes. Entries carry the refinement context a diff cannot show — the ask in the user's words, iterations and rejections, skill survived/overridden verdicts, discoveries, pins. Format is the `documentation` skill's `templates/changelog-entry.md`; trigger and lifecycle are the `changelog` rule; distillation is the `retro` agent. Immutability begins at commit — a draft in the working tree is mutable until then, never after. Every entry appends a row to `docs/history/CHANGELOG.md`.
|
|
56
54
|
- `docs/history/migrations/`: Records. One-shot migration/upgrade runbooks — authored before execution, outcome-stamped and frozen after.
|
|
57
55
|
- `docs/history/research/{topic}/`: Deep-research artifacts — the dumped output of a research pass, one folder per topic (conventionally `README.md` synthesis + `findings.md` verified claims & citations + `sources.md`). A point-in-time, cited record — **not** a living authority doc: it owns no code (no `owns:` frontmatter) and is never edited to "stay current." A spec/plan links to it for grounding; a new question gets a new topic folder.
|
|
58
56
|
- `docs/research/{topic}-brainstorm/` → `docs/history/brainstorms/{topic}/`: Brainstorm design records — the Brainstorming-Mode session for a topic (working surface `thesis.md` + `forks.md` + `ledger.md` + `state.md` + `basis/` + `fragments/`, plus an untracked `ops/` capture layer deleted at stop), written by the `brainstorm` skill and its twin agent. An active session lives under `docs/research/` (legacy folders carry the older `-brainstorming/` suffix); on a **passed harvest** it **moves** to `docs/history/brainstorms/` — the completion marker — and the **user decides whether the moved folder is deleted or committed** as provenance. Each of the two folders carries a `Readme.md` index (the skill reads it at start instead of scanning). Author-created (never scaffolded empty), one folder per design conversation. Owns no code (no `owns:` frontmatter); the harvest routes its conclusions into `architecture/`/`features/`/`history/`. (Distinct from `docs/history/research/{topic}/` above — that is a frozen deep-research record, not a brainstorm session.)
|
|
@@ -6,6 +6,21 @@ etna governs itself with the **`etna`** harness — deliberately forked from the
|
|
|
6
6
|
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
+
## Documentation Is Not a Veto
|
|
10
|
+
|
|
11
|
+
**A document records what is; it never constrains what should be.** When a proposed change contradicts a doc — a feature doc, a harness `Readme.md`, an architecture passage, a past decision record — the doc is the thing that is out of date. Never cite it as a reason the change cannot proceed: the doc is downstream of the decision it would be defending, so that reasoning is circular and it is how a system ossifies.
|
|
12
|
+
|
|
13
|
+
Every change picks one order, and names which:
|
|
14
|
+
|
|
15
|
+
| Order | Sequence |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Harness first** | change the components → update the docs to match → check for inconsistencies |
|
|
18
|
+
| **Docs first** | rewrite the docs → reconcile them → bring the components to match |
|
|
19
|
+
|
|
20
|
+
Both are valid. The only legitimate blockers are **mechanical**: a contract that breaks at runtime, data that would be lost, a build that hard-fails, a reader left pointing at what no writer produces. "The documentation says otherwise" is never one — that is a task, not an objection.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
9
24
|
## Maintenance
|
|
10
25
|
|
|
11
26
|
Invoke the `maintenance` agent whenever the docs look like they need it — not just at first setup: a missing `docs/structure.md` (the repo isn't reconciled — baseline before applying anything below), a `harness-version` marker behind the installed version, docs contradicting the components they describe, unowned source paths, or drift noticed while working. Never reconcile these by hand — the agent auto-selects its mode (baseline when the marker is missing or behind, coherence audit otherwise) and hands back; if it returns a follow-up (typically the module proposal), re-invoke it to finish. Each component's internals live in the component, not here.
|
|
@@ -88,7 +103,7 @@ Invoke the `boundary` skill after a plan is approved and before its first implem
|
|
|
88
103
|
|
|
89
104
|
- **Every markdown document goes through the `documentation` skill.** Before creating or substantively editing any `.md` document — a doc, a README, an index, a record — invoke the `documentation` skill and apply its templates and `references/style-guide.md` (truth documents present-tense; history only in records). Instruction files — `CLAUDE.md`, rules, agents, skills — follow [`docs/architecture/writing-style.md`](docs/architecture/writing-style.md) instead.
|
|
90
105
|
- **[override]** Keep `docs/` updated when a change alters documented behaviour — creating and updating docs is part of the work.
|
|
91
|
-
- After plan completion **[override]**:
|
|
106
|
+
- After plan completion **[override]**: write the `docs/history/changelog/` entry as a **draft** immediately, while the context is fresh — no confirmation needed — and append its `docs/history/CHANGELOG.md` row; the commit fills what the draft left open and freezes it. Non-plan work needs no separate prompt: every non-exempt commit carries its own entry (the `changelog` rule).
|
|
92
107
|
- When moving or renaming a component: update the `owns:` globs of the feature doc that owns it so the ownership index stays accurate. A new doc that owns code declares its paths in its own `owns:` frontmatter.
|
|
93
108
|
- `docs/structure.md` is the authority on what belongs where — read it before adding or moving a doc; one canonical source per topic, link don't copy. Only `CLAUDE.md`, `AGENTS.md`, and `README.md` live at the repo root.
|
|
94
109
|
|
|
@@ -96,6 +111,17 @@ Invoke the `boundary` skill after a plan is approved and before its first implem
|
|
|
96
111
|
|
|
97
112
|
---
|
|
98
113
|
|
|
114
|
+
## Changelog
|
|
115
|
+
|
|
116
|
+
A commit marks the user's behavioral verification of the work, and the working session is the last holder of the refinement context that produced it — asks, iterations, rejections, skill outcomes, discoveries. That context is captured in the changelog and distilled on demand. The `changelog` rule carries the trigger and the lifecycle; this is the policy:
|
|
117
|
+
|
|
118
|
+
- **Every non-mechanical commit is covered by an entry** at `docs/history/changelog/YYYY-MM-DD-{three-words}.md`, staged inside the commit it describes — whatever tool or session performs the commit — plus a row in `docs/history/CHANGELOG.md`. Format, required fields, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`; the failure fields (rejected attempts, overridden skill output) and verbatim taste quotes are required, not optional — the entry's value concentrates there.
|
|
119
|
+
- **An entry may exist before its commit.** A plan reaching `Status: Complete` writes its entry as a **draft** immediately, while the context is fresh; the commit fills what the draft left open. **Immutability begins at commit, not creation** — a draft is mutable, a committed entry never is, and a correction is a new entry that links back. Doc-health passes skip the genre.
|
|
120
|
+
- **A commit is the smallest unit an entry may describe**; above that the mapping is judgment. Work exceeding a draft's scope gets a *second* entry rather than stretching the first.
|
|
121
|
+
- **Distillation is the `retro` agent** — run on demand (before a brainstorm or LLD, before a new project, after a refinement arc), it converts accumulated entries into a typed punch list (doc content, doc structure, skill evolution, pins, harness rules), appends actionable items to the backlog, and proposes only — application runs through the normal documentation loop.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
99
125
|
## Project Memory
|
|
100
126
|
|
|
101
127
|
Project-specific learnings live in `docs/memory/` (git-tracked). Cross-project user preferences live in `~/.claude/` (untracked).
|
|
@@ -137,8 +137,7 @@ docs/
|
|
|
137
137
|
│ └── {topic}-brainstorm/ # created by the `brainstorm` skill; NOT scaffolded empty; moves to history/brainstorms/ on a passed harvest
|
|
138
138
|
├── history/
|
|
139
139
|
│ ├── CHANGELOG.md # Master changelog index
|
|
140
|
-
│ ├── changelog/ # Individual entries
|
|
141
|
-
│ ├── ledger/ # Refinement Ledger — append-only per-commit refinement journal (YYYY-MM.md; written at commit time, NOT scaffolded empty)
|
|
140
|
+
│ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
|
|
142
141
|
│ ├── plans/ # Implementation plans (Status field required)
|
|
143
142
|
│ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
|
|
144
143
|
│ └── backlog.md # Tracked work items by priority (P0-P3)
|
|
@@ -168,6 +167,7 @@ This is what makes baseline more than a fresh scaffold. Detect old-shape artifac
|
|
|
168
167
|
| repo-wide `docs/pillars/` | cross-module doctrine → `docs/architecture/`; delete the folder |
|
|
169
168
|
| `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/` |
|
|
170
169
|
| `docs/OWNERSHIP_INDEX.md` (legacy derived ownership index) | delete — ownership is the union of feature `owns:` frontmatter, surfaced by the generated index |
|
|
170
|
+
| `docs/history/ledger/YYYY-MM.md` (the Refinement Ledger, now merged into the changelog) | split each `### ` block into its own `docs/history/changelog/YYYY-MM-DD-{three-words}.md` entry — content preserved **verbatim**, heading promoted to `#`, three words naming the work; append one row per entry to `docs/history/CHANGELOG.md`; delete the `docs/history/ledger/` folder. Records are moved, never rewritten |
|
|
171
171
|
| `docs/operations/guardrails.md` | fold durable contract notes into `docs/architecture/` |
|
|
172
172
|
| `docs/architecture/overview.md` | split into `domain-model.md` / `glossary.md` / `non-goals.md` / `references.md` / `open-questions.md` |
|
|
173
173
|
| a legacy `docs/brainstorm/{topic}/`, or a root `brainstorm/`/`brainstorming/` folder | move each **active** record to `docs/research/{topic}-brainstorm/` and each **harvested** one to `docs/history/brainstorms/{topic}/` (dropping the suffix); create/refresh both `Readme.md` indexes; delete the emptied folder |
|
|
@@ -201,7 +201,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
|
|
|
201
201
|
## Rules
|
|
202
202
|
|
|
203
203
|
- **Never delete feature docs** — only update or flag for review.
|
|
204
|
-
- **Never modify `docs/history/plans
|
|
204
|
+
- **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
|
|
205
205
|
- **Preserve existing doc structure and formatting** when updating.
|
|
206
206
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
207
207
|
- **Be specific:** include file paths, line numbers, and what changed.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: retro
|
|
3
|
+
description: Session-distillation agent for the changelog. Reads the per-unit-of-work entries under `docs/history/changelog/` accumulated since its last run and distills the refinement delta — what user-driven iteration added that the one-shot build lacked — into a typed punch list of doc-content gaps, doc-structure moves (missing doc / mothership split / merge), skill-evolution findings backed by survived-vs-overridden counts, unpinned discoveries needing an enforced artifact (test, token, guardrail, schema), and cross-project harness rules. Proposes only — actionable items land in the backlog, never applied directly. Run on demand: before a brainstorm or LLD session, before starting a new project, or after a refinement arc. Triggers on "run retro", "distill the changelog", "refinement retro", "/retro".
|
|
4
|
+
tools: Read, Glob, Grep, Bash, Write, Edit
|
|
5
|
+
model: inherit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Retro — changelog distillation
|
|
9
|
+
|
|
10
|
+
You distill refinement history into documentation and harness feedback. Your input is the changelog — the per-unit-of-work entries written at commit time under `docs/history/changelog/` (entry format and field rules: the `documentation` skill's `templates/changelog-entry.md`). Your output is a short, typed punch list; every finding cites the entries that evidence it. You propose — you never apply.
|
|
11
|
+
|
|
12
|
+
## Before starting
|
|
13
|
+
|
|
14
|
+
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last entry seen); below it live prior skill-efficacy tallies and suppressed findings. No file ⇒ first run ⇒ distill everything. **An unparseable or unrecognised marker is not an error** — treat it as "distill from the start of the folder" and re-stamp in the current format.
|
|
15
|
+
2. Collect the input set: every entry file under `docs/history/changelog/` dated after the marker, in filename order (`YYYY-MM-DD-{three-words}.md` sorts chronologically). Empty set ⇒ report "nothing to distill since {date}" in one line, refresh the `Last run:` stamp, and stop — never manufacture findings.
|
|
16
|
+
3. **Skip entries carrying no field block.** An entry with no `Ask:`/`Skills:`/`Pin:` fields predates the format and holds no distillable signal; it is not a defect and never a finding.
|
|
17
|
+
4. Read `docs/memory/` for cross-reference: a changelog discovery that also appears in memory is confirmed knowledge; a memory entry with no changelog trace is itself a promotion candidate.
|
|
18
|
+
|
|
19
|
+
## Distill
|
|
20
|
+
|
|
21
|
+
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
22
|
+
|
|
23
|
+
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
24
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the union of feature-doc `owns:` globs (glob `docs/features/`).
|
|
25
|
+
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
26
|
+
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
27
|
+
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
28
|
+
|
|
29
|
+
## Report & record
|
|
30
|
+
|
|
31
|
+
1. Report in chat, ≤2 pages: a four-line scoreboard (entries distilled · discoveries pinned vs unpinned · skill table: invoked/survived · dominant refinement class), then the punch list — each item `bucket · finding (one sentence) · evidence (entry refs) · proposed action (one sentence)`. More than 12 findings ⇒ keep the top 12 by recurrence and state the tail count.
|
|
32
|
+
2. Append the actionable items to `docs/history/backlog.md` as `- **[P0–P3]** {finding} — discovered by retro`, priority by severity, deduped against existing entries.
|
|
33
|
+
3. Update `docs/memory/retro.md` (create on first write). The file **always opens with a human-legible stamp**, refreshed on **every** run — including a nothing-to-distill run — so anyone browsing `docs/memory/` sees at a glance when retro last ran and how far it read:
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Last run: {YYYY-MM-DD} · {N} entries distilled (through {last entry filename}) · {M} findings → backlog
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Below the stamp: updated skill-efficacy tallies and findings the user declined (suppressed, not re-raised), as dated entries `## YYYY-MM-DD — {topic}`.
|
|
40
|
+
|
|
41
|
+
## Rules
|
|
42
|
+
|
|
43
|
+
- **Evidence or silence** — no finding without entry citations; a clean report is valid.
|
|
44
|
+
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or changelog entries; application runs through the normal documentation loop in the main session.
|
|
45
|
+
- **Committed entries are immutable input** — never rewrite, renumber, or "clean up" an entry, whatever its quality; a malformed entry is at most a finding against the committing procedure.
|
|
46
|
+
- **Respect suppressions** in `docs/memory/retro.md` — a declined finding is recorded once, never re-raised every run.
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name = "maintenance"
|
|
3
3
|
description = "The single docs steward. Default behavior is the docs-vs-code coherence audit — detects and fixes docs drifting from code (stale docs, broken ownership, unowned source paths, architecture/backlog drift). An additive **baseline mode** layers structural reconcile on top: when the repo's `harness-version` marker is missing or behind, it converges `docs/` to the installed harness shape (scaffold the standard tree, fold dissolved-shape artifacts forward, stamp the version, propose modules) before running the audit. Mode is auto-selected from the marker. Run weekly, after major changes, or to baseline/upgrade a repo. Cross-cutting contract analysis is the `boundary` skill (`check` for plans, `scan` for diffs) — it derives contracts dynamically from source; there are no persisted boundary docs to audit. Triggers on \"run maintenance\", \"docs health\", \"baseline this repo\", \"reconcile the harness\", \"upgrade the harness\", \"is this repo on the current harness\", \"/maintenance\"."
|
|
4
4
|
developer_instructions = '''
|
|
5
|
+
|
|
5
6
|
# Maintenance Agent
|
|
6
7
|
|
|
7
8
|
You are the **single docs steward**. You keep a repo's `docs/` coherent with its code, and — when the repo's structure is behind the installed harness — you reconcile that structure first.
|
|
@@ -134,13 +135,12 @@ docs/
|
|
|
134
135
|
│ └── {topic}-brainstorm/ # created by the `brainstorm` skill; NOT scaffolded empty; moves to history/brainstorms/ on a passed harvest
|
|
135
136
|
├── history/
|
|
136
137
|
│ ├── CHANGELOG.md # Master changelog index
|
|
137
|
-
│ ├── changelog/ # Individual entries
|
|
138
|
-
│ ├── ledger/ # Refinement Ledger — append-only per-commit refinement journal (YYYY-MM.md; written at commit time, NOT scaffolded empty)
|
|
138
|
+
│ ├── changelog/ # Individual entries (YYYY-MM-DD-{three-words}.md; written at commit time, NOT scaffolded empty)
|
|
139
139
|
│ ├── plans/ # Implementation plans (Status field required)
|
|
140
140
|
│ ├── brainstorms/ # Harvested brainstorm sessions ({topic}/) — user decides kept (committed) or deleted; Readme.md is the index
|
|
141
141
|
│ └── backlog.md # Tracked work items by priority (P0-P3)
|
|
142
142
|
├── memory/ # index.md, main.md, {agent}.md — project knowledge + per-agent strategy memory
|
|
143
|
-
└── tests/ #
|
|
143
|
+
└── tests/ # Behavioral test checklists ({feature}.md, step → **Assert**), derived at plan Completion via the `documentation` skill; author-maintained, present only when test docs exist
|
|
144
144
|
```
|
|
145
145
|
|
|
146
146
|
There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillars/`**, **no `docs/boundaries/`**. Code ownership lives in feature `owns:` frontmatter; a module is a `module:` label, not a folder; boundaries are diagnosed from source; brainstorm records live in `docs/research/` (active) and `docs/history/brainstorms/` (harvested).
|
|
@@ -149,7 +149,7 @@ There is **no `docs/routing.md`**, **no `docs/modules/{m}/`**, **no `docs/pillar
|
|
|
149
149
|
|
|
150
150
|
### Step B1 — Inventory and classify
|
|
151
151
|
|
|
152
|
-
Glob every markdown file. Classify each: Architecture, Features, Operations, Plans, Changelogs, Backlog, Brainstorm records (stay), Stale/Deprecated (delete), Root docs (stay). For each topic keep the most complete version as canonical; extract unique content from the rest before deleting. **No redirect stubs** — when you move a file, delete the original and fix every reference (cross-doc links, memory files). Anything already under `docs/research/{topic}-brainstorm/` (or legacy `-brainstorming/`) or `docs/history/brainstorms/{topic}/` is a **design record** — leave it in place untouched; never reclassify its contents as Architecture/Stale or relocate them.
|
|
152
|
+
Glob every markdown file. Classify each: Architecture, Features, Operations, Tests (behavioral checklists — stay), Plans, Changelogs, Backlog, Brainstorm records (stay), Stale/Deprecated (delete), Root docs (stay). For each topic keep the most complete version as canonical; extract unique content from the rest before deleting. **No redirect stubs** — when you move a file, delete the original and fix every reference (cross-doc links, memory files). Anything already under `docs/research/{topic}-brainstorm/` (or legacy `-brainstorming/`) or `docs/history/brainstorms/{topic}/` is a **design record** — leave it in place untouched; never reclassify its contents as Architecture/Stale or relocate them.
|
|
153
153
|
|
|
154
154
|
While reading each markdown doc to classify it, if the doc names a code symbol it asserts exists that **statically resolves to nothing**, note it as an observation for the Part A audit — **only** on stacks where static resolution is reliable (stay silent on codegen/reflection/DI/barrel stacks); scoped to docs already being read here, never a whole-repo prose sweep; **docs only**, never code-file comments.
|
|
155
155
|
|
|
@@ -198,7 +198,7 @@ Re-running you is safe — the structure work is idempotent, so a second pass is
|
|
|
198
198
|
## Rules
|
|
199
199
|
|
|
200
200
|
- **Never delete feature docs** — only update or flag for review.
|
|
201
|
-
- **Never modify `docs/history/plans
|
|
201
|
+
- **Never modify `docs/history/plans/` or `docs/history/changelog/`** (frozen records — changelog entries are written only at commit time, distilled only by the `retro` agent).
|
|
202
202
|
- **Preserve existing doc structure and formatting** when updating.
|
|
203
203
|
- **When in doubt, create a backlog item** rather than making a wrong update.
|
|
204
204
|
- **Be specific:** include file paths, line numbers, and what changed.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# dropped Claude tools: Read, Glob, Grep, Bash, Write, Edit
|
|
2
|
+
name = "retro"
|
|
3
|
+
description = "Session-distillation agent for the changelog. Reads the per-unit-of-work entries under `docs/history/changelog/` accumulated since its last run and distills the refinement delta — what user-driven iteration added that the one-shot build lacked — into a typed punch list of doc-content gaps, doc-structure moves (missing doc / mothership split / merge), skill-evolution findings backed by survived-vs-overridden counts, unpinned discoveries needing an enforced artifact (test, token, guardrail, schema), and cross-project harness rules. Proposes only — actionable items land in the backlog, never applied directly. Run on demand: before a brainstorm or LLD session, before starting a new project, or after a refinement arc. Triggers on \"run retro\", \"distill the changelog\", \"refinement retro\", \"/retro\"."
|
|
4
|
+
developer_instructions = '''
|
|
5
|
+
|
|
6
|
+
# Retro — changelog distillation
|
|
7
|
+
|
|
8
|
+
You distill refinement history into documentation and harness feedback. Your input is the changelog — the per-unit-of-work entries written at commit time under `docs/history/changelog/` (entry format and field rules: the `documentation` skill's `templates/changelog-entry.md`). Your output is a short, typed punch list; every finding cites the entries that evidence it. You propose — you never apply.
|
|
9
|
+
|
|
10
|
+
## Before starting
|
|
11
|
+
|
|
12
|
+
1. Read `docs/memory/retro.md` if it exists — its opening `Last run:` stamp is your last-distilled marker (run date + last entry seen); below it live prior skill-efficacy tallies and suppressed findings. No file ⇒ first run ⇒ distill everything. **An unparseable or unrecognised marker is not an error** — treat it as "distill from the start of the folder" and re-stamp in the current format.
|
|
13
|
+
2. Collect the input set: every entry file under `docs/history/changelog/` dated after the marker, in filename order (`YYYY-MM-DD-{three-words}.md` sorts chronologically). Empty set ⇒ report "nothing to distill since {date}" in one line, refresh the `Last run:` stamp, and stop — never manufacture findings.
|
|
14
|
+
3. **Skip entries carrying no field block.** An entry with no `Ask:`/`Skills:`/`Pin:` fields predates the format and holds no distillable signal; it is not a defect and never a finding.
|
|
15
|
+
4. Read `docs/memory/` for cross-reference: a changelog discovery that also appears in memory is confirmed knowledge; a memory entry with no changelog trace is itself a promotion candidate.
|
|
16
|
+
|
|
17
|
+
## Distill
|
|
18
|
+
|
|
19
|
+
Classify every finding into exactly one bucket. Work from the entries — recurrence and explicit fields, never vibes.
|
|
20
|
+
|
|
21
|
+
1. **Doc content** — a truth doc is missing what refinement had to rediscover or invent: a `Discovered:` fact with no documented home, or `ux`/`taste` entries absent from the owning feature doc. Name the doc, the missing content, the evidencing entries.
|
|
22
|
+
2. **Doc structure** — the doc *set* is wrong: a class of entries with no home doc (candidate new doc); one doc absorbing entries across unrelated surfaces (candidate split); docs that always co-change (candidate merge). Derive surface clustering from the entries' `surface` values against the union of feature-doc `owns:` globs (glob `docs/features/`).
|
|
23
|
+
3. **Skill evolution** — tally each skill's `Skills:` verdicts across the entries: invoked / survived / overridden, override reasons aggregated. A skill overridden in most of its invocations is a finding. A refinement class recurring ≥3 times with no skill invoked is a candidate new skill.
|
|
24
|
+
4. **Pin** — a `Pin: none — candidate:` entry that recurs, or any entry whose `Ask` carries a user taste quote or explicit approval with no enforced artifact guarding the behavior. Output the exact pin (test, token, guardrail, schema) and where it goes.
|
|
25
|
+
5. **Harness rule** — a discovery true across projects, not of this repo (tooling collisions, platform ceilings, auth toil). Route to the shared rule file it belongs in.
|
|
26
|
+
|
|
27
|
+
## Report & record
|
|
28
|
+
|
|
29
|
+
1. Report in chat, ≤2 pages: a four-line scoreboard (entries distilled · discoveries pinned vs unpinned · skill table: invoked/survived · dominant refinement class), then the punch list — each item `bucket · finding (one sentence) · evidence (entry refs) · proposed action (one sentence)`. More than 12 findings ⇒ keep the top 12 by recurrence and state the tail count.
|
|
30
|
+
2. Append the actionable items to `docs/history/backlog.md` as `- **[P0–P3]** {finding} — discovered by retro`, priority by severity, deduped against existing entries.
|
|
31
|
+
3. Update `docs/memory/retro.md` (create on first write). The file **always opens with a human-legible stamp**, refreshed on **every** run — including a nothing-to-distill run — so anyone browsing `docs/memory/` sees at a glance when retro last ran and how far it read:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Last run: {YYYY-MM-DD} · {N} entries distilled (through {last entry filename}) · {M} findings → backlog
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Below the stamp: updated skill-efficacy tallies and findings the user declined (suppressed, not re-raised), as dated entries `## YYYY-MM-DD — {topic}`.
|
|
38
|
+
|
|
39
|
+
## Rules
|
|
40
|
+
|
|
41
|
+
- **Evidence or silence** — no finding without entry citations; a clean report is valid.
|
|
42
|
+
- **Propose, never apply** — you never edit truth docs, skills, rules, code, or changelog entries; application runs through the normal documentation loop in the main session.
|
|
43
|
+
- **Committed entries are immutable input** — never rewrite, renumber, or "clean up" an entry, whatever its quality; a malformed entry is at most a finding against the committing procedure.
|
|
44
|
+
- **Respect suppressions** in `docs/memory/retro.md` — a declined finding is recorded once, never re-raised every run.
|
|
45
|
+
'''
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Every unit of work leaves one record: `docs/history/changelog/YYYY-MM-DD-{three-words}.md`. The three words name the work, not the commit. Format, field rules, and the closed exemption list are the `documentation` skill's `templates/changelog-entry.md`.
|
|
4
|
+
|
|
5
|
+
An entry is not a summary line. It carries the refinement context only the working session holds — the ask in the user's own words, what was rejected, which skills survived or were overridden, what running the thing taught, what now guards it.
|
|
6
|
+
|
|
7
|
+
## When an entry is owed
|
|
8
|
+
|
|
9
|
+
| Trigger | What to write |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| A plan reaches `Status: Complete` | A draft entry for that plan, linked to it — written now, while the session still holds the context |
|
|
12
|
+
| The user asks for a changelog | The entry for the work in hand. No commit required |
|
|
13
|
+
| A commit is made | Every non-exempt commit is covered by an entry — the commit skill writes or completes it |
|
|
14
|
+
|
|
15
|
+
**Exempt** (closed list): release and bot commits, harness installs and bumps, lockfile-only changes, pure renames and moves, and changelog housekeeping itself.
|
|
16
|
+
|
|
17
|
+
## The entry's life
|
|
18
|
+
|
|
19
|
+
| State | Meaning |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| **Draft** | Created before its commit exists. Mutable — fields filled as far as the session can |
|
|
22
|
+
| **Complete** | Missing fields filled in from the diff and the session |
|
|
23
|
+
| **Frozen** | The moment it rides in a commit. Never edited again |
|
|
24
|
+
|
|
25
|
+
**Immutability begins at commit, not at creation.** A draft in the working tree is meant to be edited — that is what lets a completed plan record its context before anything is committed. Once an entry is committed it is history: a correction is a new entry linking back, never an edit.
|
|
26
|
+
|
|
27
|
+
## Granularity
|
|
28
|
+
|
|
29
|
+
A commit is the smallest unit an entry may describe. Above that the mapping is judgment — four commits may be four entries or one, whichever reads better as history.
|
|
30
|
+
|
|
31
|
+
An entry spanning several commits rides in the **last** of them and names the earlier ones in `Commits:`. An entry can never carry its own commit's SHA, so that field lists predecessors only and is omitted when one entry maps to one commit.
|
|
32
|
+
|
|
33
|
+
When the work done exceeds what a draft describes, do not stretch the draft — write a second entry. The first stays an honest account of the plan; the second records the work beyond it.
|
|
34
|
+
|
|
35
|
+
## The index
|
|
36
|
+
|
|
37
|
+
Every entry appends one row to `docs/history/CHANGELOG.md` — date, link, one-line summary — in the same pass that writes the entry, so the table never trails the folder.
|
|
@@ -60,8 +60,7 @@ The two guarantees are complementary and both break on mixing: a reader holding
|
|
|
60
60
|
| Baseline / reconcile docs | `maintenance` agent (baseline mode) — it calls this skill per template |
|
|
61
61
|
| Document feature/module (LLD) | [`templates/feature.md`](templates/feature.md) |
|
|
62
62
|
| Document data flow / state / Redux | [`templates/feature.md`](templates/feature.md) — they are sections of the feature doc |
|
|
63
|
-
| Create/update changelog | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record) |
|
|
64
|
-
| Record per-commit refinement (ledger block) | [`templates/refinement-ledger.md`](templates/refinement-ledger.md) (record — written at commit time, distilled by the `retro` agent) |
|
|
63
|
+
| Create/update changelog entry | [`templates/changelog-entry.md`](templates/changelog-entry.md) (record — one per unit of work; carries the refinement fields, frozen inside its commit, distilled by the `retro` agent) |
|
|
65
64
|
| Create/update plan | [`templates/plan.md`](templates/plan.md) (record) |
|
|
66
65
|
| Record/revise architecture decision | [`templates/architecture-decision.md`](templates/architecture-decision.md) — one AD per subject; revisions update it in place |
|
|
67
66
|
| System at a glance | [`templates/system-overview.md`](templates/system-overview.md) |
|
|
@@ -1,62 +1,57 @@
|
|
|
1
|
-
# Changelog
|
|
1
|
+
# Changelog Entry
|
|
2
2
|
|
|
3
|
-
Record. Use for:
|
|
3
|
+
Record. Use for: the per-unit-of-work journal of what changed and how it was refined — one file per entry under `docs/history/changelog/YYYY-MM-DD-{three-words}.md`, written by whoever does the work and frozen inside the commit it describes. The three words name the work, not the commit. Trigger and lifecycle policy: the `changelog` rule; distillation is the `retro` agent.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
An entry is not a summary line. Its value concentrates in the fields a diff cannot reconstruct — the ask in the user's own words, what was rejected, which skills survived or were overridden, what running the thing taught.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
# YYYY-MM-DD - [Title]
|
|
9
|
-
|
|
10
|
-
## Summary
|
|
11
|
-
|
|
12
|
-
Brief description of what changed and why.
|
|
13
|
-
|
|
14
|
-
## Changes
|
|
7
|
+
## Entry format
|
|
15
8
|
|
|
16
|
-
|
|
17
|
-
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
9
|
+
```
|
|
10
|
+
# {YYYY-MM-DD} · {surface} — {one-line outcome}
|
|
11
|
+
|
|
12
|
+
**Plan:** [history/plans/YYYY-MM-DD-slug.md](../plans/YYYY-MM-DD-slug.md)
|
|
13
|
+
**Commits:** {sha}, {sha}
|
|
14
|
+
|
|
15
|
+
- **Ask:** {what the user asked, compressed — taste and preference statements quoted verbatim}
|
|
16
|
+
- **Iterations:** {N} · rejected: {what was rejected and why} | none
|
|
17
|
+
- **Skills:** {skill}@{version} — survived | partially survived | overridden ({why, briefly}) | none used
|
|
18
|
+
- **Change:** {added/changed X, which does Y, because Z — behavior first, mechanism second}
|
|
19
|
+
- **Discovered:** {non-obvious fact learned by running the product — environment quirk, platform ceiling, seam behavior, dependency constraint} | none
|
|
20
|
+
- **Class:** {one or more keywords — suggestive vocabulary, not a closed enum; see Field rules}
|
|
21
|
+
- **Pin:** {enforced artifact written in this entry's commit: test / token / guardrail / schema} | none — candidate: {what should hold it}
|
|
22
|
+
```
|
|
26
23
|
|
|
27
|
-
|
|
28
|
-
- `oldFunction()` from `path/to/file.js`
|
|
29
|
-
- Replaced by: `newFunction()`
|
|
24
|
+
`**Plan:**` appears only on plan-linked entries. `**Commits:**` appears only when one entry covers several commits, and lists the predecessors — an entry can never carry its own commit's SHA.
|
|
30
25
|
|
|
31
|
-
|
|
32
|
-
- `buggyFunction()` in `path/to/file.js`
|
|
33
|
-
- Bug: What was wrong, when it manifested
|
|
34
|
-
- Fix: What changed
|
|
26
|
+
## Lifecycle
|
|
35
27
|
|
|
36
|
-
|
|
28
|
+
| State | Meaning |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| **Draft** | Created before its commit exists — typically the moment a plan reaches `Status: Complete`. Mutable; fields filled as far as the session can |
|
|
31
|
+
| **Complete** | Missing fields filled in from the diff and the session |
|
|
32
|
+
| **Frozen** | The moment it rides in a commit. Never edited, renumbered, or reconciled |
|
|
37
33
|
|
|
38
|
-
|
|
34
|
+
**Immutability begins at commit, not at creation.** A draft in the working tree is meant to be edited; that is what lets a completed plan capture its context before anything is committed. A committed entry is history — a correction is a new entry that links back. Entries are exempt from doc-health passes by genre: they are history and can never be "wrong".
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
- Old: Previous behavior
|
|
42
|
-
- New: Current behavior
|
|
43
|
-
- Impact: What breaks
|
|
44
|
-
- Migration: How to fix
|
|
36
|
+
## Field rules
|
|
45
37
|
|
|
46
|
-
|
|
38
|
+
- **Every field present; "none" stated explicitly.** An absent field is a template violation. Sessions assert success by default — the required `rejected:` and `overridden` entries are the counterweight; an honestly empty failure field is information too.
|
|
39
|
+
- **`surface`** uses the repo's ownership vocabulary — the owning feature doc's topic or an `owns:` path stem — so entries are queryable per surface.
|
|
40
|
+
- **`Ask` quotes taste verbatim.** The user's preference wording is the one thing no skill can infer and no rebuild recovers; the entry is its durable home.
|
|
41
|
+
- **`Skills` records efficacy honestly** — survived / partially survived / overridden with a reason. These verdicts are the raw data the `retro` agent aggregates into skill-evolution findings; sanitizing them into success stories destroys the mechanism's value.
|
|
42
|
+
- **`Discovered` holds what only running the product teaches.** If it was learned in use, it is recorded the same day — this field feeds the pin candidates.
|
|
43
|
+
- **`Class` is a suggestive vocabulary, not a closed enum.** Tag with one or more keywords, preferring an existing term over a synonym so the `retro` agent can cluster; coin a new one when nothing fits — a recurring coinage is itself retro signal that the vocabulary (or the doc set) is missing a category. Suggested keywords: `ux` · `ui` · `visual` · `taste` · `layout` · `motion` · `interaction` · `copy` · `a11y` · `responsiveness` · `navigation` · `state` · `structure` · `architecture` · `seam` · `contract` · `schema` · `data` · `content` · `seed` · `performance` · `caching` · `resilience` · `error-handling` · `security` · `auth` · `observability` · `logging` · `testing` · `tooling` · `dependency` · `ops` · `deploy` · `env` · `ci` · `i18n` · `docs`.
|
|
44
|
+
- **`Pin` closes the loop:** the enforced artifact written in this commit, or the named candidate for the `retro` agent to flag. A taste-verified behavior with `Pin: none` and no candidate is a template smell.
|
|
45
|
+
- **Out-of-session entries** (the writing session did not do the work): fill what the diff and conversation evidence support; mark the rest `unknown — committed out-of-session`.
|
|
47
46
|
|
|
48
|
-
|
|
47
|
+
## Granularity
|
|
49
48
|
|
|
50
|
-
|
|
51
|
-
2. {Step}
|
|
49
|
+
A commit is the smallest unit an entry may describe. Above that the mapping is judgment — four commits may be four entries or one. When the work exceeds what a draft describes, write a **second** entry rather than stretching the first: the plan-linked entry stays an honest account of the plan.
|
|
52
50
|
|
|
53
|
-
##
|
|
51
|
+
## The index
|
|
54
52
|
|
|
55
|
-
|
|
56
|
-
- A future agent diagnosing a regression starts from this evidence
|
|
53
|
+
Every entry appends one row to `docs/history/CHANGELOG.md` — date, link, one-line summary — in the same pass that writes the entry.
|
|
57
54
|
|
|
58
|
-
##
|
|
55
|
+
## Exemptions (closed list)
|
|
59
56
|
|
|
60
|
-
-
|
|
61
|
-
- `src/path/file2.js` - Supporting updates
|
|
62
|
-
```
|
|
57
|
+
No entry for: release and bot commits, harness installs and bumps, lockfile-only changes, pure renames and moves, and changelog housekeeping itself. Everything else gets an entry, however short.
|
|
@@ -29,8 +29,7 @@ Each topic has one canonical location. Read from here, not from plans or changel
|
|
|
29
29
|
| Environment / config surface | `docs/operations/` | environment.md |
|
|
30
30
|
| Testing strategy | `docs/tests/` | strategy.md |
|
|
31
31
|
| Historical plans | `docs/history/plans/` | YYYY-MM-DD-name.md |
|
|
32
|
-
| Change records | `docs/history/changelog/` |
|
|
33
|
-
| Refinement Ledger | `docs/history/ledger/` | YYYY-MM.md (append-only, written at commit time) |
|
|
32
|
+
| Change records | `docs/history/changelog/` | `YYYY-MM-DD-{three-words}.md` — one per unit of work, written at commit time |
|
|
34
33
|
| Migration runbooks | `docs/history/migrations/` | YYYY-MM-DD-name.md |
|
|
35
34
|
| Deep-research artifacts | `docs/history/research/{topic}/` | README.md + findings.md + sources.md |
|
|
36
35
|
| Brainstorm design records | `docs/research/{topic}-brainstorm/` (active; legacy `-brainstorming/`) → `docs/history/brainstorms/{topic}/` (harvested; user deletes or commits) | thesis.md + forks.md + ledger.md + state.md |
|
|
@@ -51,8 +50,7 @@ Every doc is a **truth document** (states current absolutes, topic-named, update
|
|
|
51
50
|
- `docs/operations/`: How-to procedures for setup, development, and deployment, plus the environment registry. Update when workflows change. One-shot migrations do NOT live here — they are records (`docs/history/migrations/`).
|
|
52
51
|
- `docs/tests/`: Testing strategy and test docs. Present when the repo has a test posture worth documenting.
|
|
53
52
|
- `docs/history/plans/`: Records. Must have `Status:` field. Never modify after completion.
|
|
54
|
-
- `docs/history/changelog/`: Records.
|
|
55
|
-
- `docs/history/ledger/`: Records. The Refinement Ledger — an append-only per-commit refinement journal (monthly `YYYY-MM.md` files) written by the committing agent, each block staged inside the commit it describes; block format is the `documentation` skill's `templates/refinement-ledger.md`, distillation is the `retro` agent. Blocks are immutable — never edited, never reconciled; the folder is never scaffolded empty.
|
|
53
|
+
- `docs/history/changelog/`: Records. One entry per unit of work (`YYYY-MM-DD-{three-words}.md`), written by whoever does the work and frozen inside the commit it describes. Entries carry the refinement context a diff cannot show — the ask in the user's words, iterations and rejections, skill survived/overridden verdicts, discoveries, pins. Format is the `documentation` skill's `templates/changelog-entry.md`; trigger and lifecycle are the `changelog` rule; distillation is the `retro` agent. Immutability begins at commit — a draft in the working tree is mutable until then, never after. Every entry appends a row to `docs/history/CHANGELOG.md`.
|
|
56
54
|
- `docs/history/migrations/`: Records. One-shot migration/upgrade runbooks — authored before execution, outcome-stamped and frozen after.
|
|
57
55
|
- `docs/history/research/{topic}/`: Deep-research artifacts — the dumped output of a research pass, one folder per topic (conventionally `README.md` synthesis + `findings.md` verified claims & citations + `sources.md`). A point-in-time, cited record — **not** a living authority doc: it owns no code (no `owns:` frontmatter) and is never edited to "stay current." A spec/plan links to it for grounding; a new question gets a new topic folder.
|
|
58
56
|
- `docs/research/{topic}-brainstorm/` → `docs/history/brainstorms/{topic}/`: Brainstorm design records — the Brainstorming-Mode session for a topic (working surface `thesis.md` + `forks.md` + `ledger.md` + `state.md` + `basis/` + `fragments/`, plus an untracked `ops/` capture layer deleted at stop), written by the `brainstorm` skill and its twin agent. An active session lives under `docs/research/` (legacy folders carry the older `-brainstorming/` suffix); on a **passed harvest** it **moves** to `docs/history/brainstorms/` — the completion marker — and the **user decides whether the moved folder is deleted or committed** as provenance. Each of the two folders carries a `Readme.md` index (the skill reads it at start instead of scanning). Author-created (never scaffolded empty), one folder per design conversation. Owns no code (no `owns:` frontmatter); the harvest routes its conclusions into `architecture/`/`features/`/`history/`. (Distinct from `docs/history/research/{topic}/` above — that is a frozen deep-research record, not a brainstorm session.)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nurix/etna",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.26",
|
|
4
4
|
"description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
"homepage": "https://github.com/nurixlabs/etna/tree/dev/packages/cli",
|
|
32
32
|
"license": "UNLICENSED",
|
|
33
33
|
"publishConfig": {
|
|
34
|
-
"access": "
|
|
34
|
+
"access": "public"
|
|
35
35
|
},
|
|
36
36
|
"keywords": [
|
|
37
37
|
"claude",
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Refinement Ledger
|
|
2
|
-
|
|
3
|
-
Record. Use for: the append-only per-commit journal of session refinement — one block per non-mechanical commit, written by the committing agent at commit time and staged **inside the commit it describes**. Blocks are immutable once committed: never edited, renumbered, or reconciled; a correction is a new block referencing the old. The ledger is exempt from doc-health passes by genre — it is history and can never be "wrong".
|
|
4
|
-
|
|
5
|
-
Monthly files: `docs/history/ledger/YYYY-MM.md`, created on first block — the folder is never scaffolded empty. Distillation is the `retro` agent's job; this template owns only the capture format.
|
|
6
|
-
|
|
7
|
-
## Block format
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
### {YYYY-MM-DD} · {surface} — {one-line outcome}
|
|
11
|
-
- **Ask:** {what the user asked, compressed — taste and preference statements quoted verbatim}
|
|
12
|
-
- **Iterations:** {N} · rejected: {what was rejected and why} | none
|
|
13
|
-
- **Skills:** {skill}@{version} — survived | partially survived | overridden ({why, briefly}) | none used
|
|
14
|
-
- **Change:** {added/changed X, which does Y, because Z — behavior first, mechanism second}
|
|
15
|
-
- **Discovered:** {non-obvious fact learned by running the product — environment quirk, platform ceiling, seam behavior, dependency constraint} | none
|
|
16
|
-
- **Class:** {one or more keywords — suggestive vocabulary, not a closed enum; see Field rules}
|
|
17
|
-
- **Pin:** {enforced artifact written in this commit: test / token / guardrail / schema} | none — candidate: {what should hold it}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Field rules
|
|
21
|
-
|
|
22
|
-
- **Every field present; "none" stated explicitly.** An absent field is a template violation. Sessions assert success by default — the required `rejected:` and `overridden` entries are the counterweight; an honestly empty failure field is information too.
|
|
23
|
-
- **`surface`** uses the repo's ownership vocabulary — the owning feature doc's topic or an `owns:` path stem — so the ledger is queryable per surface.
|
|
24
|
-
- **`Ask` quotes taste verbatim.** The user's preference wording is the one thing no skill can infer and no rebuild recovers; the ledger is its durable home.
|
|
25
|
-
- **`Skills` records efficacy honestly** — survived / partially survived / overridden with a reason. These verdicts are the raw data the `retro` agent aggregates into skill-evolution findings; sanitizing them into success stories destroys the mechanism's value.
|
|
26
|
-
- **`Discovered` holds what only running the product teaches.** If it was learned in use, it is recorded here the same day — this field feeds the pin candidates.
|
|
27
|
-
- **`Class` is a suggestive vocabulary, not a closed enum.** Tag with one or more keywords, preferring an existing term over a synonym so the `retro` agent can cluster; coin a new one when nothing fits — a recurring coinage is itself retro signal that the vocabulary (or the doc set) is missing a category. Suggested keywords: `ux` · `ui` · `visual` · `taste` · `layout` · `motion` · `interaction` · `copy` · `a11y` · `responsiveness` · `navigation` · `state` · `structure` · `architecture` · `seam` · `contract` · `schema` · `data` · `content` · `seed` · `performance` · `caching` · `resilience` · `error-handling` · `security` · `auth` · `observability` · `logging` · `testing` · `tooling` · `dependency` · `ops` · `deploy` · `env` · `ci` · `i18n` · `docs`.
|
|
28
|
-
- **`Pin` closes the loop:** the enforced artifact written in this commit, or the named candidate for the `retro` agent to flag. A taste-verified behavior with `Pin: none` and no candidate is a template smell.
|
|
29
|
-
- **Out-of-session commits** (the committing session did not do the work): fill what the diff and conversation evidence support; mark the rest `unknown — committed out-of-session`.
|
|
30
|
-
|
|
31
|
-
## Exemptions (closed list)
|
|
32
|
-
|
|
33
|
-
No block for: release/bot commits, harness installs and bumps, lockfile-only changes, pure renames/moves, and ledger housekeeping itself. Everything else gets a block, however short.
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# Refinement Ledger
|
|
2
|
-
|
|
3
|
-
Record. Use for: the append-only per-commit journal of session refinement — one block per non-mechanical commit, written by the committing agent at commit time and staged **inside the commit it describes**. Blocks are immutable once committed: never edited, renumbered, or reconciled; a correction is a new block referencing the old. The ledger is exempt from doc-health passes by genre — it is history and can never be "wrong".
|
|
4
|
-
|
|
5
|
-
Monthly files: `docs/history/ledger/YYYY-MM.md`, created on first block — the folder is never scaffolded empty. Distillation is the `retro` agent's job; this template owns only the capture format.
|
|
6
|
-
|
|
7
|
-
## Block format
|
|
8
|
-
|
|
9
|
-
```
|
|
10
|
-
### {YYYY-MM-DD} · {surface} — {one-line outcome}
|
|
11
|
-
- **Ask:** {what the user asked, compressed — taste and preference statements quoted verbatim}
|
|
12
|
-
- **Iterations:** {N} · rejected: {what was rejected and why} | none
|
|
13
|
-
- **Skills:** {skill}@{version} — survived | partially survived | overridden ({why, briefly}) | none used
|
|
14
|
-
- **Change:** {added/changed X, which does Y, because Z — behavior first, mechanism second}
|
|
15
|
-
- **Discovered:** {non-obvious fact learned by running the product — environment quirk, platform ceiling, seam behavior, dependency constraint} | none
|
|
16
|
-
- **Class:** {one or more keywords — suggestive vocabulary, not a closed enum; see Field rules}
|
|
17
|
-
- **Pin:** {enforced artifact written in this commit: test / token / guardrail / schema} | none — candidate: {what should hold it}
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## Field rules
|
|
21
|
-
|
|
22
|
-
- **Every field present; "none" stated explicitly.** An absent field is a template violation. Sessions assert success by default — the required `rejected:` and `overridden` entries are the counterweight; an honestly empty failure field is information too.
|
|
23
|
-
- **`surface`** uses the repo's ownership vocabulary — the owning feature doc's topic or an `owns:` path stem — so the ledger is queryable per surface.
|
|
24
|
-
- **`Ask` quotes taste verbatim.** The user's preference wording is the one thing no skill can infer and no rebuild recovers; the ledger is its durable home.
|
|
25
|
-
- **`Skills` records efficacy honestly** — survived / partially survived / overridden with a reason. These verdicts are the raw data the `retro` agent aggregates into skill-evolution findings; sanitizing them into success stories destroys the mechanism's value.
|
|
26
|
-
- **`Discovered` holds what only running the product teaches.** If it was learned in use, it is recorded here the same day — this field feeds the pin candidates.
|
|
27
|
-
- **`Class` is a suggestive vocabulary, not a closed enum.** Tag with one or more keywords, preferring an existing term over a synonym so the `retro` agent can cluster; coin a new one when nothing fits — a recurring coinage is itself retro signal that the vocabulary (or the doc set) is missing a category. Suggested keywords: `ux` · `ui` · `visual` · `taste` · `layout` · `motion` · `interaction` · `copy` · `a11y` · `responsiveness` · `navigation` · `state` · `structure` · `architecture` · `seam` · `contract` · `schema` · `data` · `content` · `seed` · `performance` · `caching` · `resilience` · `error-handling` · `security` · `auth` · `observability` · `logging` · `testing` · `tooling` · `dependency` · `ops` · `deploy` · `env` · `ci` · `i18n` · `docs`.
|
|
28
|
-
- **`Pin` closes the loop:** the enforced artifact written in this commit, or the named candidate for the `retro` agent to flag. A taste-verified behavior with `Pin: none` and no candidate is a template smell.
|
|
29
|
-
- **Out-of-session commits** (the committing session did not do the work): fill what the diff and conversation evidence support; mark the rest `unknown — committed out-of-session`.
|
|
30
|
-
|
|
31
|
-
## Exemptions (closed list)
|
|
32
|
-
|
|
33
|
-
No block for: release/bot commits, harness installs and bumps, lockfile-only changes, pure renames/moves, and ledger housekeeping itself. Everything else gets a block, however short.
|