@naswerks/engineering-loop 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/.claude-plugin/marketplace.json +15 -0
  2. package/.claude-plugin/plugin.json +8 -0
  3. package/CHANGELOG.md +32 -0
  4. package/LICENSE +21 -0
  5. package/README.md +78 -0
  6. package/bin/verify-staged.mjs +247 -0
  7. package/package.json +35 -0
  8. package/references/docs-workflow.md +417 -0
  9. package/references/engineering-loop.md +298 -0
  10. package/skills/docs-audit-feature/SKILL.md +88 -0
  11. package/skills/docs-audit-full/SKILL.md +54 -0
  12. package/skills/docs-backlog/SKILL.md +41 -0
  13. package/skills/docs-process/SKILL.md +146 -0
  14. package/skills/docs-status/SKILL.md +47 -0
  15. package/skills/docs-write/SKILL.md +43 -0
  16. package/skills/init/SKILL.md +163 -0
  17. package/skills/init/scripts/doctor.mjs +176 -0
  18. package/skills/spec-child/SKILL.md +149 -0
  19. package/skills/spec-ignite/SKILL.md +277 -0
  20. package/skills/spec-parent/SKILL.md +634 -0
  21. package/skills/spec-pipeline/SKILL.md +453 -0
  22. package/skills/spec-retro/SKILL.md +398 -0
  23. package/skills/spec-review/SKILL.md +266 -0
  24. package/skills/spec-seat/SKILL.md +512 -0
  25. package/skills/spec-witness/SKILL.md +222 -0
  26. package/templates/claude-md-stanza.md +13 -0
  27. package/templates/docs/_meta/doc-index.md +90 -0
  28. package/templates/docs/infrastructure/background-work.md +53 -0
  29. package/templates/docs/infrastructure/realtime-events.md +54 -0
  30. package/templates/docs/patterns/backend-patterns.md +96 -0
  31. package/templates/docs/patterns/codegen.md +69 -0
  32. package/templates/docs/patterns/frontend-patterns.md +92 -0
  33. package/templates/docs/patterns/state-management.md +73 -0
  34. package/templates/docs/patterns/testing.md +103 -0
  35. package/templates/docs/patterns/ui-style-guide.md +76 -0
  36. package/templates/docs/patterns/vertical-slice-anatomy.md +61 -0
  37. package/templates/docs/readme-archive.md +9 -0
  38. package/templates/docs/readme-features.md +7 -0
  39. package/templates/docs/readme-guides.md +7 -0
  40. package/templates/docs/readme-infrastructure.md +7 -0
  41. package/templates/docs/readme-patterns.md +9 -0
  42. package/templates/docs/readme-research.md +9 -0
  43. package/templates/docs/readme-working.md +9 -0
  44. package/templates/settings-pin.json +10 -0
@@ -0,0 +1,298 @@
1
+ <!-- naswerks-loop: version=0.1.0 -->
2
+ # The Engineering Loop — flow, seats, skills, and the ceremony
3
+
4
+ > The quick intro to how work gets built with this loop: the two loops (`docs-*` knowledge, `spec-*`
5
+ > execution), the seats (Human / Coordinator / Seat, plus the read-only Witness), the ceremony per
6
+ > session, and a bare-bones exchange showing the back-and-forth. Point newcomers at this plus
7
+ > [doc-index](doc-index.md) + [docs-workflow](docs-workflow.md). Operational templates live in the
8
+ > `spec-parent` skill; the seat contract in `spec-seat`.
9
+ <!-- meta: type=guide; status=current; verified={date}; lineage=1 -->
10
+
11
+ ---
12
+
13
+ ## The loop at a glance
14
+
15
+ **As states, which is what answers "where is this effort right now" — and the shape decides where
16
+ `processed` falls relative to the merge:**
17
+
18
+ ```
19
+ idea -> chartered -> building -> REVIEWED -> fixed? -> retro -> PR'd -> ?
20
+
21
+ with a P row -> processed -> merged <- HUMAN P runs on the BRANCH and rides the PR, so the
22
+ living docs and the archive land WITH the code —
23
+ and its patches are contingent on that merge
24
+
25
+ without one -> merged <- HUMAN -> processed a cold session later, on the base branch, over
26
+ one or several finished efforts at once
27
+ ```
28
+
29
+ **That fork is the whole of the P-row decision.** In-pipeline buys docs and code landing together;
30
+ out-of-pipeline buys a clean PR diff and no contingency. Nothing else about the sequence changes.
31
+
32
+ **As skills:**
33
+
34
+ ```
35
+ Idea -> docs-backlog -> research doc in docs/research/
36
+ Research matures -> a plan (a plan-approval mode, if the harness has one)
37
+ Plan graduates -> spec-pipeline -> docs/research/{topic}/: umbrella + one spec
38
+ per session + project-status.md (the plan is
39
+ now throwaway — the specs carry every crumb)
40
+ Same session — CHOOSE THE SEAT:
41
+ hand-cranked -> spec-parent -> this session becomes the COORDINATOR and cuts
42
+ Prompt #1 (you relay every message)
43
+ hosted -> spec-ignite -> this session becomes the IGNITION COPILOT:
44
+ verify the brief, derive the stage card, YOU
45
+ click Create, "kick it", a hosted coordinator
46
+ runs the whole pipeline; you own parks +
47
+ completes + the kill-switch
48
+ Per spec (new session) -> BUILD SEAT -> recon, PLAN TLDR, rulings, build,
49
+ FINAL TLDR, docs-write, commit (on call)
50
+ Builds done, if chosen -> spec-review -> the OUTSIDE look, before the retro and before the
51
+ (a pipeline row) PR: code + patterns + composition across seams +
52
+ the loop's own comms; sessions/code-review.md.
53
+ Classifies which findings earn a fixit
54
+ if it found one -> FIXIT row -> one per pipeline MAX, coordinator-ruled, only when
55
+ the pipeline would otherwise ship something untrue
56
+ Close (coordinator) -> spec-retro -> the INSIDE look: the ceremony audit, the ledger
57
+ reconciliation, the true economics; then
58
+ BUILD COMPLETE + the PR
59
+ Effort done -> docs-process -> living docs patched (consuming the working docs
60
+ (fresh session, or a AND code-review.md); specs + working docs
61
+ pipeline row if chosen) archived together to docs/archive/{topic}/
62
+ Then, and ONLY these -> the human MERGES the PR, and runs the live-checks rows <- THE TWO HUMAN GATES
63
+ Anytime / periodic -> docs-status, docs-audit-feature, docs-audit-full <- NEVER a pipeline row
64
+ Alongside, optional -> spec-witness — a session OUTSIDE the worktree, read-only, zero writes: a
65
+ window into a running pipeline so the human can take its pulse without the UI
66
+ ```
67
+
68
+ **Two things are the human's, permanently and by design:** the **merge** (a person in the merge path is
69
+ the point, not a gap) and the **live-checks** rows (a machine cannot hand-test a UI). Everything between
70
+ `idea` and `archived` a pipeline can do for itself.
71
+
72
+ **`docs-audit-*` is never a pipeline row.** It runs off-hours and scheduled, over the whole doc tree — not
73
+ inside an effort, and not at an effort's close. A stale living doc is not something a pipeline must stop for.
74
+
75
+ **The pipeline's SHAPE is decided at authoring, not by a runtime flag.** `spec-pipeline` asks whether the
76
+ effort wants a review row and a docs-process row, and writes them into the row table — so the coordinator
77
+ learns the shape by reading its own sequence, and nothing needs a toggle. A pipeline can be plain,
78
+ `+review`, `+review +process`, or `+process`.
79
+
80
+ ## Two loops — both hand-crankable
81
+
82
+ - **`docs-*` is the knowledge loop** and runs standalone, forever: small/everyday efforts are
83
+ just *plan, build, `docs-write`, `docs-process`* — no pipeline, no coordinator, a flat working
84
+ doc. This is the default and it never requires a control plane.
85
+ - **`spec-*` is the execution loop** for work that is more than one session: `spec-pipeline`
86
+ graduates the plan, `spec-parent` takes the seat, build seats build one spec each. **Each spec is sized
87
+ for ONE session** — recon, plan, build, suite and FINAL TLDR before the session's context compacts —
88
+ and the spec count falls out of that: a pipeline of two specs is a pipeline, and so is one of ten. It
89
+ hands off to the knowledge loop at both ends (research docs in, working docs out).
90
+ - **Either loop runs by hand or hosted.** The manual version is this document's ceremony with the human
91
+ relaying; the hosted version is the control plane running the same ceremony, machine-relayed. When they
92
+ drift, this doc + the `spec-parent` skill are the requirements; the control plane follows.
93
+
94
+ ## The seats
95
+
96
+ | Seat | Who | Holds | Never does |
97
+ |---|---|---|---|
98
+ | **Human** | you | final approvals (plan-approve click, hard questions, push/publish, hand-testing), the relay in manual mode | writes feature code mid-pipeline |
99
+ | **Coordinator** | one long-lived session per effort | the north star + full pipeline context; cuts each seat prompt from the previous session's *actual* results; judges PLAN/FINAL TLDRs; rules with rationale; verifies load-bearing claims itself; owns `project-status.md` | writes feature code; trusts self-reported "N green" |
100
+ | **Seat** | one fresh session per spec | exactly ONE spec; recons the real code first; builds; reports honestly | touches the tracker or memory; commits without the relayed call; runs `docs-write` unprompted |
101
+ | **Witness** *(optional, `spec-witness`)* | a read-only session with substrate access | testifies from rows/transcripts/git when claims conflict or a pipeline looks wedged; answers "whose turn is it" | writes anything; injects anything; rules on anything |
102
+
103
+ The seat, not the chat, is the product: `project-status.md` must stay current enough that a
104
+ fresh session can resume as coordinator losslessly (`spec-parent {topic}`).
105
+
106
+ ## The skills
107
+
108
+ | Skill | Loop | When | One line |
109
+ |---|---|---|---|
110
+ | `docs-backlog` | docs | an idea, no time to build | park it as a research doc |
111
+ | `docs-status` | docs | session start | orient: archived / in flight / waiting |
112
+ | `docs-write` | docs | end of any build session (in a pipeline: on the coordinator's call) | finalize the working doc into `docs/working/` |
113
+ | `docs-process` | docs | effort done, fresh session | patch living docs (verified vs code), archive |
114
+ | `docs-audit-feature` / `docs-audit-full` | docs | doc suspected stale / monthly | deep-audit docs against code |
115
+ | `spec-pipeline` | spec | a plan came through and you're committing to it | explode the plan into a numbered spec pipeline — *spare no crumb* |
116
+ | `spec-parent` | spec | right after `spec-pipeline` (same session) or fresh with the topic | assume the coordinator seat |
117
+ | `spec-seat` | spec | **every** seat the coordinator arms, invoked FIRST | **the CONTRACT, not a seat** — the shared half of every seat's procedure. `spec-parent` does NOT compose it: the coordinator writes rulings rather than receiving them |
118
+ | `spec-child` | spec | igniting a build or fixit seat — manual (`spec-child {role} {spec}`) or hosted | **the BUILD JOB only** — one spec, the role's adds, the pin taxonomy, the suite protocol, the fixit variant. Its ceremony comes from `spec-seat` |
119
+ | `spec-ignite` | spec | when an authored pipeline runs HOSTED (the `spec-parent` alternative) | the ignition copilot, and it can run COLD: gates, re-verify the brief's baselines + platform state against live HEAD, derive the stage card (human clicks Create), "kick it" with the brief's own kick text as the task; every UI gap a named finding |
120
+ | `spec-review` | spec | a pipeline's builds are done, if it has a review row | the OUTSIDE look, before the retro and before the PR: correctness/security/**composition across session seams** · the patterns, with every departure identified · the loop's own comms. Two independent passes, consolidated. Classifies which findings earn a fixit; **its value is having none of the pipeline's context** |
121
+ | `spec-retro` | spec | the coordinator's LAST act, after any review and any fixit | the INSIDE look: a substrate-verified grade, the ceremony audit (did the acts write rows?), the ledger reconciliation, the true economics, the blindnesses, the ranked fixit backlog — *a retrospective that cannot indict its own author is marketing* |
122
+ | `spec-witness` | spec | a pipeline looks wedged, or actors' claims conflict | the read-only fourth seat: substrate access, zero writes, zero rulings |
123
+ | `init` | — | a repository that has none of this yet | create the `docs/` shape, the method docs, first drafts of every doc the skills read; `init doctor` says what is missing |
124
+
125
+ ### Where a rule lives — policy, procedure, task
126
+
127
+ The thing that keeps prompts and skills from drifting apart:
128
+
129
+ | Kind | Home | Why there |
130
+ |---|---|---|
131
+ | **POLICY** | the un-skippable system-prompt suffix the control plane supplies at open | cannot be skipped, present on every turn |
132
+ | **PROCEDURE — shared** | `spec-seat` | the contract for ANY seat the coordinator arms: blackboard, question lane, parked-call discriminator, verdicts, BELIEFS sha, git shapes, six-section FINAL TLDR, close-out order |
133
+ | **PROCEDURE — per job** | `spec-child` · `spec-review` · `docs-process` | what THIS seat does. The job skill **refines** the seat contract and never contradicts it; a genuine conflict is a finding, not a fork |
134
+ | **TASK** | the seed prompt + the pipeline's `00-ignition-brief.md` | per-run; dies with the run |
135
+
136
+ A seed's first act is therefore to **invoke its skills** — `spec-seat`, then the job — not to restate them.
137
+ One copy per rule: where a prompt and a skill would say the same thing, the prompt points and the skill
138
+ holds it.
139
+
140
+ **Why the split exists.** A single base contract every seat kind shared, with the build job mixed in,
141
+ sends the REVIEW row into the umbrella its own charter excludes and offers the DOCS-PROCESS row a
142
+ `docs-write` from a build skill's close-out — the row that has just *emptied* `docs/working/`. One base
143
+ class, three wrong instructions, and none of it visible until the loop runs end to end.
144
+
145
+ Session boundaries: plan/spec authoring is one session; each spec is one build session;
146
+ `docs-process` is deliberately a *fresh* session; the pipeline's final spec audits the cumulative
147
+ diff.
148
+
149
+ ## The ceremony (one build session)
150
+
151
+ 1. **Coordinator cuts the seat prompt** from the PREVIOUS session's actual shipped shapes — never
152
+ from the spec's guesses alone. (Template: `spec-parent` skill.)
153
+ 2. **Seat recons, states its beliefs** (HEAD sha, dirty files, versions, baselines), then a
154
+ **PLAN TLDR as plain text** — before any plan-approval presentation — with **questions as
155
+ numbered options + an embedded recommendation, then STOP**. Never an interactive question tool.
156
+ 3. **Coordinator rules**: verdict (`accept` / `accept-with-riders` — fold in and go /
157
+ `blocking-precondition` / `read-full-plan`), one CAPS ruling per question, decision first
158
+ then the WHY. The coordinator diffs the seat's beliefs against the ledger before ruling.
159
+ 4. **Plan-approve = the freedom moment** (manual: approve + bypass-permissions; hosted: the gate
160
+ flips). The seat builds uninterrupted; mid-run questions repeat the relay loop.
161
+ 5. **Seat ends with the six-section FINAL TLDR** — shipped+verification, verbatim runner
162
+ summaries (with invocation commands), honest gaps, deferred findings, live checklist
163
+ entries, staging list + commit HELD + session cost.
164
+ 6. **Coordinator verifies one load-bearing claim itself** (receipts compared first; rerun only in
165
+ doubt), then the **close-out call**: optional fix/rerun, `docs-write` with an itemized
166
+ carry, COMMIT CALL with the seat's own staging list, push (human approves the push).
167
+ 7. **Coordinator flips the tracker row** to SHIPPED + hash and transcribes deferred findings — the
168
+ seat never writes the tracker. **The coordinator also commits the closing seat's post-push
169
+ close-out append, byte-untouched, as part of closing the row** — the append lands after the
170
+ seat's own commit, so left alone it hands the NEXT seat a dirty tree. Goto 1.
171
+
172
+ **Hard rules:** no commit/push without the relayed call; explicit staging, never `git add -A`, verified
173
+ with `verify-staged`; codegen only through the command `patterns/codegen.md` names; component files as
174
+ `patterns/frontend-patterns.md` states; additive-only, never amend pushed commits; parallel sessions only
175
+ when specs share no files — commits sequence regardless; seats run the pipeline's declared default model
176
+ (allowlist-exact, set at creation), and an investigation-heavy seat may warrant a reasoning-heavier one.
177
+
178
+ ## The exchange, bare bones (headers only — what a session looks like)
179
+
180
+ ```
181
+ COORDINATOR -> Prompt #N: docs preamble, ##PROMPT##, ONE spec + context docs + prior ACTUAL shapes
182
+ + CEREMONY block
183
+ SEAT -> PLAN TLDR (BELIEFS: head/dirty/versions/baselines · the plan, 5-10 lines ·
184
+ QUESTIONS 1..n, options + recommendation), STOP
185
+ COORDINATOR -> PARENT RESPONSE — PLAN {ACCEPTED / ACCEPTED-WITH-RIDERS / …} · rulings 1..n
186
+ (DECISION — why) · riders · "Go build."
187
+ SEAT -> (builds free; mid-run question: numbered text, STOP; COORDINATOR ruling; resume)
188
+ SEAT -> FINAL TLDR — (a) SHIPPED+VERIFICATION (b) VERBATIM RUNNER SUMMARIES (c) HONEST GAPS
189
+ (d) DEFERRED FINDINGS (e) LIVE CHECKLIST (f) STAGING + commit HELD + cost
190
+ COORDINATOR -> FINAL TLDR ACCEPTED (+ what the coordinator verified itself) · 1. docs-write, carry: …
191
+ · 2. COMMIT CALL — message: … · then push, report hash
192
+ SEAT -> books the working doc, commits, pushes, reports hash + post-push status
193
+ COORDINATOR -> tracker row SHIPPED {hash}; transcribes findings; cuts Prompt #N+1
194
+ ```
195
+
196
+ ## The blackboard — where the exchange lives
197
+
198
+ The exchange above is not just chat — it is a pair of FILES per build session:
199
+
200
+ - **`tldr.md` — the chat.** Append-only, two voices: the seat's PLAN TLDR + numbered
201
+ questions, the coordinator's ruling appended beneath them, optional mid-build updates +
202
+ `## PARENT NOTE`s, then the FINAL TLDR. Read top-to-bottom it IS the session's whole
203
+ conversation, greppable by anchor.
204
+ - **`plan.md` — the document.** The full plan, posted once, corrected on pushback. PULL-only:
205
+ the coordinator reads it on a `read-full-plan` verdict; it is never force-fed into a wake or chat.
206
+
207
+ **`sessions/` is the pipeline's conversation, and the whole effort's durable record.** One folder per
208
+ pipeline, **brought into existence by the FIRST seat's close-out commit** — never authored when the
209
+ pipeline is written, and never with a placeholder — then written into by every later seat, and archived
210
+ with the effort:
211
+
212
+ ```
213
+ docs/research/{topic}/sessions/ <- per-session work in {spec-slug}/, effort-wide at the root
214
+ {spec-slug}/plan.md each seat the full plan, posted once, corrected on pushback (PULL-only)
215
+ {spec-slug}/tldr.md each seat the two-voice chat — seat turns AND coordinator rulings interleaved
216
+ code-review.md the review the outside look, if the pipeline had a review row
217
+ parent-retrospective.md the coord. the close-out audit (the inside look)
218
+ witness-ledger-*.md a human the witness is zero-writes, so its ledger arrives by hand
219
+ ```
220
+
221
+ Two files per build session; questions ride the TLDR, and there are no status snapshots because the
222
+ tracker is committed live. **It is TESTIMONY** — an archive pass repairs links elsewhere and leaves
223
+ `sessions/**` byte-untouched, because editing a record to make it tidy is how it stops being one.
224
+
225
+ Where they live — **hand-cranked:** `docs/research/{topic}/sessions/{spec-slug}/` (ordinary
226
+ repo files, staged at close-out; the coordinator appends rulings with its own file tools; the
227
+ human's relay is a one-line nudge each way).
228
+
229
+ <!-- control-plane-specific -->
230
+ **Hosted — there is no folder tree the controller can read.** A seat **carries its bytes** to
231
+ `post_plan` / `post_tldr` (verbs under `acts:write`, so a witness ticket structurally cannot post), and
232
+ everything identifying is **server-derived** — pipeline and seat from the verified ticket, and **the rev**
233
+ (newest + 1). *A rev nobody can misstate cannot regress by accident.* The append-only guard is what
234
+ survives the transport: the ladder only climbs, a shorter file is refused, and the same rev with
235
+ different bytes is refused — so the mirror **cannot be clobbered or rewound by a caller that lies, even
236
+ though it can be fed.**
237
+
238
+ **The coordinator's voice is NOT in the seat's file on the hosted plane.** A coordinator answers with
239
+ `callout` (its sixth drive verb, machine-written, the only downward path), which persists on its own
240
+ artifact lane and closes the question in the **acts ledger**. So **the file says whether a question was
241
+ ASKED; the ledger says whether it was ANSWERED**, and a seat typing a parent-voice heading into its own
242
+ TLDR closes nothing. `callout` **refuses when the charge has no live session** — a coordinator must
243
+ `seat_spawn` before it can rule — and reports **"RULING RECORDED, NOT DELIVERED"** in those words if the
244
+ transport drops it.
245
+
246
+ The parent-voice block (machinery-written hosted; the hand-cranked coordinator writes it — hand-cranked
247
+ there is no rev counter, so the heading is `## PARENT RULING (plan — {verdict})`; the stable grep prefix
248
+ `## PARENT RULING` is the contract in both modes):
249
+
250
+ ```
251
+ ## PARENT RULING (plan rev N — {accept | accept-with-riders | blocking-precondition})
252
+
253
+ PARENT RESPONSE — PLAN TLDR {VERDICT}. {one sentence naming the best thing in the plan}
254
+ Answers:
255
+ 1. {RULING IN CAPS} — {decision first, then the why}.
256
+ ...
257
+ Go build. Fold the riders in — no re-approval round-trip.
258
+ ```
259
+
260
+ Callouts and nudges append as `## PARENT NOTE` (actor-suffixed when known, e.g. `(operator)`).
261
+
262
+ **The seat's own two anchors:**
263
+
264
+ ```
265
+ ## [child·{slug} · run {id}] CLOSE-OUT RECEIPT <- after the push
266
+ ## [child·{slug} · run {id}] HOLDING <- "I have pushed and I am waiting"
267
+ ```
268
+
269
+ **A question heading, a HOLDING and a close-out receipt are ALL non-staling** — the gates bind an
270
+ acceptance to the accepted CONTENT, not to the revision number, so appending your own *state* leaves it
271
+ intact. Only **new content** stales. A seat that has pushed and is waiting is otherwise indistinguishable
272
+ from a seat that has done nothing, and a coordinator reading a wake led by its own acceptance concludes
273
+ there is nothing to rule — the HOLDING anchor is what prevents that. The token is the literal `child·`
274
+ whatever seat you are — it is a protocol anchor, not a description of you.
275
+
276
+ ### Questions ride the same blackboard
277
+
278
+ **When you need a decision at any point after your plan:** append a `## MID-BUILD QUESTION` section
279
+ (during recon/plan time the heading is `## QUESTIONS` — two literal headings, one lane, both poke) —
280
+ **that literal heading, in every phase including close-out**, because the detector is heading-matched and a
281
+ synonym is a question no banner announces and no re-raise can reach — to your own `tldr.md`, post it, and
282
+ **end your turn**. The coordinator is woken with your question, and its ruling *is* the answer — so you
283
+ pick it up from your own file and resume. Your turn never stays open waiting, and asking costs the
284
+ pipeline nothing but the round-trip. Plan-time questions and mid-build questions are the same lane and the
285
+ same shape.
286
+
287
+ An unanswered question is re-raised to the coordinator on a cooldown until a ruling lands, so if the
288
+ coordinator cannot rule yet it appends a note saying so — one append ends the reminder.
289
+
290
+ <!-- control-plane-specific -->
291
+ **The human-touch receipt is the loop's own instrument.** Every hand-delivered message to a seat leaves an
292
+ `injected_by_human` row, so "how autonomous was this run" is a number, not a floor. The control plane
293
+ mints it on the one authenticated steering door, before the bytes move. The count's credibility rests on
294
+ the credential: **a receipt the audited party can mint is not a receipt** — which is why the steering
295
+ door takes the human's own token and never a seat's job ticket.
296
+
297
+ ## Lineage
298
+ - **Related** — [docs-workflow](docs-workflow.md) · [doc-index](doc-index.md) · the `spec-parent` and `spec-seat` skills (the operational templates and the seat contract)
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: docs-audit-feature
3
+ description: Deep-audit one or more living docs (features, infrastructure, or patterns) against the actual code — write an audit report per doc and correct the doc. Use right after touching an area, when a doc is suspected stale, or run docs-audit-feature <doc-path...> (a single doc, a list, or a whole folder).
4
+ ---
5
+
6
+ # docs-audit-feature
7
+
8
+ Verify living docs against the real implementation and correct them. Works on a single doc, a list of
9
+ docs, or a whole folder — in `docs/features/`, `docs/infrastructure/`, or `docs/patterns/`. This is
10
+ the one audit skill for "does this doc still match the code"; it produces both the **audit report**
11
+ and the **corrected living doc**.
12
+
13
+ > **The system:** `docs/_meta/doc-index.md` (the menu of living docs) + `docs/_meta/docs-workflow.md`
14
+ > (the loop, folders, templates) explain how the docs are organized. Skim them if you need to place a
15
+ > doc or find its siblings.
16
+
17
+ > **Audit direction depends on the doc type.** Descriptive docs (`infrastructure/`, `features/`) —
18
+ > **code is truth**: where they disagree, fix the doc. Prescriptive docs (`patterns/`, `guides/`) — the
19
+ > doc is the **decided rule**: audit whether the *code conforms to the doc*; a mismatch is usually a
20
+ > code problem to flag (or a convention to confirm), **not** a doc to rewrite — only edit the doc if the
21
+ > rule itself genuinely changed.
22
+
23
+ **One doc or many.** Pass a single doc, a group, or a folder — e.g.
24
+ `docs-audit-feature auth signalr postgres` or `docs-audit-feature docs/features/`. Apply the Steps
25
+ below to **each doc in turn** — one full read, verify, report, fix pass per doc, never batching the
26
+ writes across docs. End with a one-line-per-doc summary (stale-count / added-count / clean).
27
+
28
+ ## Steps (per doc)
29
+
30
+ 1. **Read the living doc** (`docs/features/{x}.md`, `docs/infrastructure/{x}.md`, or
31
+ `docs/patterns/{x}.md`).
32
+
33
+ 2. **Read the corresponding code** — the backend `Features/{Feature}/` slice and matching frontend
34
+ feature folder for feature docs; the relevant subsystem for infrastructure/pattern docs. Confirm
35
+ entities, endpoints, stores, routes, services, config, key files.
36
+
37
+ 3. **Check against conventions** — cross-check the doc's claims against `docs/patterns/` (and
38
+ `docs/infrastructure/` where relevant) so the doc matches how things are actually built.
39
+
40
+ 4. **Report findings** — write a short audit report to `docs/archive/audit/{group}/{doc-name}-audit.md`,
41
+ where `{group}` mirrors the living doc's folder (`guides/`, `patterns/`, `infrastructure/`, or
42
+ `features/`; create the subfolder if absent). Date in header: what was accurate, what was stale,
43
+ what's undocumented, and any **code risks / bugs / tech-debt** you noticed against the source.
44
+ (The master `health-report-*.md` from `docs-audit-full` stays at the `audit/` root — it's cross-cutting.)
45
+
46
+ 5. **Update the living doc** with the corrections and bump its "Last verified" date — **and refresh the
47
+ `<!-- meta: … -->` line in lockstep** (`verified` = today, update `status`, recompute `lineage=N`). This is
48
+ allowed here only because you just did the full doc-vs-code pass; the meta `verified` obeys the same
49
+ anti-fabrication rule as the blockquote date (the two always move together). **Verify the `## Lineage`
50
+ footer** — check every link resolves; flag any dead breadcrumb into `## Open Issues` (or the audit report)
51
+ and recompute `lineage=N` to match. **Soft-check `Spec` / `Built` symmetry** — for a spec-driven feature, a
52
+ `Built` session whose per-slice spec is absent from `Spec` (or vice-versa) is usually an under-scoped row;
53
+ note it and complete it *unless* the doc is deliberately scoped tighter than the effort (judgment, not a hard
54
+ fail — see the Lineage rules in `docs-workflow.md`). **Reconcile its `## Open Issues` section** — add any real, code-verified
55
+ risk/bug/tech-debt you found (dated, with `file:line`), and remove any listed issue the code now resolves.
56
+ (The archived report is the history; `## Open Issues` is the live signal `docs-status` reads.)
57
+
58
+ ## When auditing a whole folder (optional completeness pass)
59
+
60
+ If pointed at a folder rather than named docs, first **list it and diff against the code** so nothing
61
+ is missed:
62
+ - **In code, no doc**: a real feature/subsystem with no living doc. Create the doc (Steps 1-5 against
63
+ the code), or at minimum flag it in the summary.
64
+ - **Doc, no code**: the thing it documents is gone. Flag for archiving/deleting the doc.
65
+ - **Both exist**: run the per-doc audit above.
66
+
67
+ For `docs/features/`, the folder (one doc per feature) IS the inventory — there is no separate
68
+ catalog. Build the real list from `Features/` + the frontend feature folders/routes via actual
69
+ `ls`/`find` output in this run, then diff.
70
+
71
+ ## Anti-fabrication rule
72
+
73
+ - **Read the code before you write a word of the doc or report.** Steps 1-3 (read doc, read code,
74
+ check conventions) must complete and their output be visible before step 4/5 write anything. Never
75
+ batch the write with the reads.
76
+ - **Every claim traces to a file you opened in this run** — entity names, endpoints, routes, key
77
+ files, line references. No identifiers or dates from memory. When listing a folder, build the
78
+ feature/doc lists from real `ls`/`find` output, not memory.
79
+ - Only stamp **"Last verified: <today>"** on a doc you actually checked against code in this run.
80
+ Stamping a date you didn't verify is the exact failure this rule exists to prevent.
81
+ - The `<!-- meta: verified=… -->` date is bound by the **same** rule and always equals the blockquote's
82
+ `Last verified` — refresh `verified` / `status` / `lineage=N` only after the full doc-vs-code pass this run.
83
+
84
+ ## Notes
85
+ - **Descriptive docs (`infrastructure/`, `features/`):** code is truth — where doc and code disagree,
86
+ the code wins, fix the doc. **Prescriptive docs (`patterns/`, `guides/`):** the doc is the decided
87
+ rule — a mismatch usually means the *code* should change (flag it); only edit the doc if the rule
88
+ itself changed.
@@ -0,0 +1,54 @@
1
+ ---
2
+ name: docs-audit-full
3
+ description: Master health check across all docs — staleness/age scan, convention spot-checks, research that looks resolved — producing a prioritized re-verify plan. Use monthly, after an extended absence, or run docs-audit-full.
4
+ ---
5
+
6
+ # docs-audit-full
7
+
8
+ A deep-clean sweep. Does NOT re-audit every feature in depth — it produces the prioritized plan of
9
+ what to audit next.
10
+
11
+ ## Steps
12
+
13
+ 1. **Freshness scan** — read "Last verified" dates across all living docs (`guides/ patterns/
14
+ infrastructure/ features/`). Flag anything older than ~14 days; sort oldest-first.
15
+
16
+ 2. **Feature completeness** — quick `docs/features/` folder pass (per `docs-audit-feature`'s
17
+ folder mode): any features in code with no doc, or docs whose feature is gone.
18
+
19
+ 3. **Convention spot-check** — sample 2-3 source files per major convention against the
20
+ `docs/patterns/` docs; note drift.
21
+
22
+ 4. **Research scan** — scan `docs/research/`; flag ideas that look already-implemented (so they can be
23
+ graduated/removed) and ideas worth surfacing.
24
+
25
+ 5. **Working/archive sanity** — note any docs lingering in `docs/working/` that look done (should be
26
+ filed via `docs-write`), and confirm `archive/` topic folders are intact.
27
+
28
+ 6. **Read the previous report first.** Before writing anything, find the most recent
29
+ `docs/archive/audit/health-report-*.md` and read it in full. The new report continues from it:
30
+ note what was flagged last time and is now fixed, what's still outstanding, and anything that
31
+ regressed. If there is **no** prior report, say so — this run is the baseline.
32
+
33
+ 7. **Produce a health report** at `docs/archive/audit/health-report-{date}.md` with a prioritized,
34
+ actionable list (which `docs-audit-feature` runs, which docs to re-verify, which research to clear).
35
+ Open with a **"Since last report"** section that diffs against the report from step 6 (or marks this
36
+ as the baseline if none existed).
37
+
38
+ ## Anti-fabrication rule (read before writing the report)
39
+
40
+ The report is a **pure function of the scan output above it**. Fabricated dates, feature lists, and
41
+ counts are the main failure mode of this skill.
42
+
43
+ - **Gather first, write last.** Run ALL of steps 1-6 and SEE their output before you create the
44
+ report file. Never put the report `Write` in the same batch as the commands that feed it — they run
45
+ together, so the report would be written from memory, not data.
46
+ - **Every factual cell traces to a command in THIS run.** Dates, file names, feature names, counts —
47
+ if you can't point at the tool output that produced it, it does not go in the report.
48
+ - **No identifiers from memory.** Feature names, endpoint names, and dates must come from a fresh read
49
+ of the tree in this run, not from recollection of the codebase or earlier-session summaries.
50
+ - If a scan didn't run or its output is unclear, say "not verified" — never guess a plausible value.
51
+
52
+ ## Notes
53
+ - Output is a plan + report, not a mass edit. Run the recommended `docs-audit-feature` / `docs-process`
54
+ actions separately.
@@ -0,0 +1,41 @@
1
+ ---
2
+ name: docs-backlog
3
+ description: Capture an idea, improvement, or future-state design as a research doc in docs/research/. Use when the user has thoughts/ideas to park for later, wants to capture research, or runs docs-backlog.
4
+ ---
5
+
6
+ # docs-backlog
7
+
8
+ Capture ideas as research docs. `docs/research/` is the idea inbox — the folder itself is the queue.
9
+
10
+ ## Steps
11
+
12
+ 1. **Scan existing research titles** in `docs/research/` — quick check for an obvious duplicate or a
13
+ doc this should extend instead of duplicate.
14
+
15
+ 2. **For each idea, create a research doc** at `docs/research/{topic}.md` using the research-doc
16
+ template in `docs/_meta/docs-workflow.md`: Current State, Desired End State, Design Options /
17
+ Recommendation, Open Questions. Capture the idea while it's fresh — verify "Current State" against
18
+ code if quick, otherwise note it's unverified.
19
+
20
+ **The research doc must be self-contained.** It's the durable jump-off point; assume everything else
21
+ from this session disappears. Inline the substance — plans, code sketches, config, command output,
22
+ findings — directly into the doc. Do **not** point at ephemeral artifacts as the source of truth: a
23
+ scratch plan file (Claude Code: `~/.claude/plans/*`), a chat transcript, a subagent's report, a temp file, or
24
+ "see the plan above." Those vanish; the research doc stays. Cross-links to *other durable docs*
25
+ (living docs, sibling research docs) are fine — links to throwaway state are not. If the idea came
26
+ from a plan or long exploration, copy the load-bearing content in (an Appendix is fine) rather than
27
+ referencing where it lived.
28
+
29
+ 3. **Output**: new research doc(s) only.
30
+
31
+ ## Notes
32
+ - Does NOT create working docs, patch living docs, or archive anything. Research docs are the output.
33
+ - **Self-contained or it failed its job.** Before finishing, reread the doc and strip any reference that
34
+ makes it depend on something that won't survive the session (plan-file paths, "the plan I just made",
35
+ transcript/tool-output you didn't inline). If you mention an artifact, its content must already be in
36
+ the doc.
37
+ - When an idea is later picked up and built, link it via the session doc's **Source** field. The
38
+ research doc **stays in `research/` through the build** (it's the running tab, and a build may span
39
+ several sessions / working docs). When the effort finishes, `docs-process` archives the research doc
40
+ **alongside its working doc(s)** in the same `archive/{topic}/` folder — research and the work that
41
+ delivered it are filed together, not deleted.
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: docs-process
3
+ description: Patch the living docs from a session doc's "Living Docs to Update" checklist, verified against code. Use at the start of a session, when the user points at a working/archived session doc and asks to update the living docs, or run docs-process.
4
+ ---
5
+
6
+ # docs-process
7
+
8
+ The **second** half of the bookend. Take a finished session doc (in `docs/working/` or its topic
9
+ folder under `docs/archive/`) and bring the living docs up to current state.
10
+
11
+ ## Running as a pipeline row (`docs-process` seat)
12
+
13
+ Most of the time a human runs this cold, after a merge, and this section does not apply.
14
+
15
+ **When a pipeline arms you as its `docs-process` seat**, your contract is **`spec-seat`** — invoke it first if
16
+ you have not. It carries the blackboard, the question lane, the PLAN TLDR, the verdict vocabulary, the
17
+ six-section FINAL TLDR, and the close-out order. Two things are yours specifically:
18
+
19
+ - **You are handed a MANIFEST of this effort's working docs BY NAME. `docs/working/` is a SHARED QUEUE
20
+ — never infer membership from the folder.** A seat that archives a neighbouring effort's docs cannot
21
+ undo it. If your prompt did not name them, ask before you move anything.
22
+ - **Do NOT run `/docs-write`.** You are that skill's CONSUMER, never its caller — a working doc from you
23
+ would be an orphan in the queue you just emptied, for an effort you just archived. Your artifacts are
24
+ the patched living docs and the archive; go straight to the commit call.
25
+
26
+ **In-pipeline, your living-doc patches are contingent on the merge** — you verify against the pipeline's
27
+ branch, which is the truth for that PR, and you say so at close.
28
+
29
+ ## Steps
30
+
31
+ 1. **Read the session doc(s) for the effort** from `docs/working/` — that's where `docs-write` leaves
32
+ them (it does not archive). A folder's `README.md` is never a queue entry. One effort may be a **SEQUENCE of working docs** across sessions (each
33
+ `Builds on` the prior, all sharing one `Source:` research doc); treat the sequence as one unit. The
34
+ combined **Living Docs to Update** sections are your checklist; the `## Archive` line names the topic
35
+ folder you'll file everything into in the last step. Run this when the effort is done (it's the
36
+ finalizer) — mid-effort, just keep adding working docs and continue.
37
+
38
+ **`docs/working/` is a SHARED QUEUE — it may hold other efforts' docs.** Invoked by hand you scope
39
+ the effort yourself from the `Source:` / `Builds on` sequence. **Spawned as a pipeline seat you should have
40
+ been handed the effort's working docs BY NAME, plus its archive target and its research/spec folder —
41
+ if you were not, ask for the list rather than inferring membership from the folder.** Sweeping a
42
+ neighbouring effort's docs into this archive is the failure this guards, and it is not reversible by
43
+ the seat that does it.
44
+
45
+ **If the effort was a spec pipeline, you have a SECOND input: `sessions/code-review.md`** — the review
46
+ seat's outside look, filed beside `parent-retrospective.md`. Read both. **Every review finding gets a
47
+ disposition, and the disposition is TOTAL:** a living-doc patch here · an existing fixit seat · a
48
+ chartered follow-up · a new spec pipeline · or killed on record with the reason. **A finding with no named
49
+ home is dropped, not deferred** — and the review's own classification (fixit candidate / deferred /
50
+ documented / trivial) is its recommendation, not your ruling.
51
+
52
+ **When you run as a seat INSIDE the pipeline** (before the PR merges) your living-doc patches describe
53
+ code that is *about to* land. That is fine and deliberate — docs and code ride one PR instead of
54
+ drifting — but say so in your summary: **the patches are contingent on the merge.** Verify against the
55
+ pipeline branch's code, which is the truth for that PR.
56
+
57
+ 2. **For each listed living doc** (in `guides/`, `patterns/`, `infrastructure/`, `features/`):
58
+ - Read the living doc and the session doc's description of what changed.
59
+ - **Patch the stale sections** — don't rewrite. Preserve everything still accurate.
60
+ - **Verify against code** — open the actual source file for each claimed change. Code is truth.
61
+ - **Leave the "Last verified" date alone.** You verified the *specific* checklist changes against
62
+ code — but you did NOT re-read the whole doc against the whole codebase, and "Last verified" is a
63
+ *whole-doc* claim. Stamping it for a targeted patch (rename or substantive alike) overclaims and
64
+ hides real staleness in the untouched sections from the next `docs-status` scan. That date is
65
+ `docs-audit-feature`'s to set (it does the full doc-vs-code pass — see its anti-fabrication rule).
66
+ **Exception:** a doc you *create from scratch* here by reading the code is verified-today by
67
+ definition — set its date.
68
+ - **Update the Key Files table** if files were renamed, created, or deleted.
69
+ - **Write / update the meta-comment + `## Lineage`** (see "Doc metadata" in `docs-workflow.md`):
70
+ - *Creating a doc from scratch* here: emit the `<!-- meta: type=…; status=current; verified={today};
71
+ lineage=N -->` line (its `verified` = today, matching the blockquote you just set) **and** a
72
+ `## Lineage` footer. You already know the `Source:` research doc (the `Idea` row), any spec pipeline
73
+ (the `Spec` row), and the working-doc sequence / `## Archive` target (the `Built` row); derive `Related` from
74
+ existing peer links. Set `lineage=N` to the link count. **Keep `Spec` and `Built` symmetric** —
75
+ list **every per-slice spec that a `Built` session implemented** (the umbrella + `00-operating-frame`
76
+ go in `Idea`, not `Spec`); a `Built` session whose spec is missing from `Spec` is the smell (see the
77
+ Lineage rules in `docs-workflow.md`).
78
+ - *Patching an existing doc*: bump `status` if it changed and recompute `lineage=N`; append any new
79
+ `Built`/`Spec` rows for this effort. **Do NOT restamp `verified`** — same anti-fabrication rule as the
80
+ `Last verified` date above (a targeted patch is not a whole-doc re-verify).
81
+ - **Migrate `## Related Docs`.** If the doc still carries a `## Related Docs` section, fold its links into
82
+ the `## Lineage` `Related` row and remove the old section (the convention supersedes it).
83
+ - **Flag code risks you spot.** If you notice a genuine bug / risk / tech-debt *outside* what you're
84
+ documenting — while verifying against code, or as a still-unresolved item in the working doc's
85
+ **Watch-Outs** — add a dated one-line bullet (with `file:line`) to that doc's `## Open Issues`
86
+ section (create the section if absent). Only what you actually saw in the code this pass — never
87
+ speculation. A sizable design idea goes to `docs-backlog` (research/) instead. `docs-status`
88
+ surfaces these so they aren't lost.
89
+
90
+ 3. **New feature?** If the work added a feature, ensure it has a doc in `docs/features/` (one doc per
91
+ feature) and add it to the menu in `docs/_meta/doc-index.md`.
92
+
93
+ 4. **Closing grep** — if the session doc notes deletions or renames, grep all living
94
+ docs (`guides/ patterns/ infrastructure/ features/ _meta/`) for stale references and fix them. Do
95
+ NOT touch `archive/` — that's frozen history.
96
+
97
+ 5. **Archive the effort — research/spec docs AND working doc(s), together.** Now that the living docs are
98
+ patched and verified, file the whole effort into one **topic folder** under `docs/archive/{topic}/`
99
+ (use the `## Archive` line; reuse the folder if it exists, create it if new; descriptive names, **no
100
+ numeric prefixes on working docs** — `Builds on` is the ordering):
101
+
102
+ **FIRST, RECONCILE THE DESTINATIONS — `rg '^\s*`?docs/archive/' <every working doc in the effort>`.**
103
+ This step says *"one topic folder"* and *"use the `## Archive` line"* — a singular read over a PLURAL
104
+ source, so the set is checked before any move. **If the docs disagree, STOP and ask.** Do not pick the
105
+ majority, do not pick the first, and do not pick the one you happen to be reading. The failure is not
106
+ recoverable by you: one working doc naming a different, populated effort's folder is enough to sweep
107
+ this effort's docs into a neighbour's archive, and `archive/` is frozen history. No seat can see it
108
+ alone — each wrote one working doc and each line is individually plausible; the divergence exists only
109
+ in the SET, which is why the check belongs here and not upstream.
110
+ - Move **every working doc** in the effort from `docs/working/` into the topic folder.
111
+ - Move the **`Source:`** research/spec docs from `docs/research/` into the **same** topic folder — the
112
+ idea and the work that delivered it are filed together. Do NOT delete and do NOT leave in `research/`
113
+ (that's what kept shipped ideas cluttering the running tab).
114
+ - **Pick the folder shape** (see "Two topic-folder shapes" in `docs-workflow.md`):
115
+ - **Flat** (no spec pipeline — the default for small/single-session efforts): working doc(s) + any
116
+ research doc at the topic-folder root.
117
+ - **Split** (the effort used `spec-pipeline`, so a numbered spec set exists): `git mv` the numbered
118
+ specs + umbrella into **`specs/`**, the working docs into **`implementation/`**, and leave
119
+ **`project-status.md` at the topic-folder root** as the index, plus any `live-checks.md`; a
120
+ `sessions/` folder (**two files per session — the filed `plan.md` + `tldr.md`**; older archives may
121
+ also hold `questions.md` / `status-after-*.md`, which is historical record, not the convention)
122
+ moves wholesale alongside them. `git mv` STAGES immediately — in a shared working tree, another
123
+ session's commit can silently sweep your staged renames. Commit promptly after the moves, or
124
+ announce the staged state before yielding the tree.
125
+ - **Follow-on round** (the effort continues an already-archived family — e.g. a round-2 pipeline for
126
+ a shipped feature): its own **sibling** topic folder with the full split shape, named
127
+ `{family-prefix}-{subtopic}` — **never file into the frozen prior-round folder**. The family
128
+ index is the living feature doc's `## Lineage` (append this round's Idea/Spec/Built rows beside
129
+ the prior round's); the new round's back-links to the old archive stay as-is (historical
130
+ cross-effort links). See the section named `Follow-on pipelines` in `docs-workflow.md`.
131
+ - **Repair the intra-effort links the move breaks** (relative depths change). On a split, fix: each
132
+ working doc's `Source:` becomes `../specs/NN-*.md`; the spec / `project-status` links; and the **live feature
133
+ doc's `## Lineage`** rows (`Spec` to `…/specs/…`, `Built` to `…/implementation/…`). On a flat archive, a
134
+ working doc's `Source: ../research/{topic}/x.md` becomes the now-sibling `x.md`. **Leave pre-existing
135
+ cross-effort links** (to *other* topic folders / research folders) as historical record. Verify with a
136
+ link-resolution pass before finishing.
137
+ This clears both the `working/` queue and the research idea. After this the docs are frozen history.
138
+
139
+ 6. **Summary** — list which living docs were updated, what changed in each, which source files you read
140
+ to confirm accuracy, and where the session doc was filed.
141
+
142
+ ## Notes
143
+ - Skip doc updates for pure bug fixes that restored behavior the doc already described correctly.
144
+ - `docs-write` leaves the doc in `working/`; **this skill is what archives it** (step 5) — only after the
145
+ living docs are current. That keeps `working/` an honest queue of unprocessed sessions.
146
+ - No releases/changelog step — git history covers that.