@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.
- package/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +8 -0
- package/CHANGELOG.md +32 -0
- package/LICENSE +21 -0
- package/README.md +78 -0
- package/bin/verify-staged.mjs +247 -0
- package/package.json +35 -0
- package/references/docs-workflow.md +417 -0
- package/references/engineering-loop.md +298 -0
- package/skills/docs-audit-feature/SKILL.md +88 -0
- package/skills/docs-audit-full/SKILL.md +54 -0
- package/skills/docs-backlog/SKILL.md +41 -0
- package/skills/docs-process/SKILL.md +146 -0
- package/skills/docs-status/SKILL.md +47 -0
- package/skills/docs-write/SKILL.md +43 -0
- package/skills/init/SKILL.md +163 -0
- package/skills/init/scripts/doctor.mjs +176 -0
- package/skills/spec-child/SKILL.md +149 -0
- package/skills/spec-ignite/SKILL.md +277 -0
- package/skills/spec-parent/SKILL.md +634 -0
- package/skills/spec-pipeline/SKILL.md +453 -0
- package/skills/spec-retro/SKILL.md +398 -0
- package/skills/spec-review/SKILL.md +266 -0
- package/skills/spec-seat/SKILL.md +512 -0
- package/skills/spec-witness/SKILL.md +222 -0
- package/templates/claude-md-stanza.md +13 -0
- package/templates/docs/_meta/doc-index.md +90 -0
- package/templates/docs/infrastructure/background-work.md +53 -0
- package/templates/docs/infrastructure/realtime-events.md +54 -0
- package/templates/docs/patterns/backend-patterns.md +96 -0
- package/templates/docs/patterns/codegen.md +69 -0
- package/templates/docs/patterns/frontend-patterns.md +92 -0
- package/templates/docs/patterns/state-management.md +73 -0
- package/templates/docs/patterns/testing.md +103 -0
- package/templates/docs/patterns/ui-style-guide.md +76 -0
- package/templates/docs/patterns/vertical-slice-anatomy.md +61 -0
- package/templates/docs/readme-archive.md +9 -0
- package/templates/docs/readme-features.md +7 -0
- package/templates/docs/readme-guides.md +7 -0
- package/templates/docs/readme-infrastructure.md +7 -0
- package/templates/docs/readme-patterns.md +9 -0
- package/templates/docs/readme-research.md +9 -0
- package/templates/docs/readme-working.md +9 -0
- package/templates/settings-pin.json +10 -0
|
@@ -0,0 +1,453 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-pipeline
|
|
3
|
+
description: Graduate a plan into a numbered spec pipeline in docs/research/{topic}/ — an umbrella plus one self-contained spec per planned seat. Use when a research idea is "really getting into it" and a plan has come through (a plan-approval mode, if your harness has one) and you want to commit it as specs instead of executing it directly, or run spec-pipeline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# spec-pipeline
|
|
7
|
+
|
|
8
|
+
Turn a *plan* into a durable, numbered **spec pipeline** in `docs/research/{topic}/`. This is phase 2 of
|
|
9
|
+
the two-phase backlog model: `docs-backlog` parks an idea; `spec-pipeline` graduates the plan behind it
|
|
10
|
+
into specs. **The plan is throwaway — the specs carry every crumb.** A future session reads ONE spec + the
|
|
11
|
+
umbrella and can build without the plan or the original conversation.
|
|
12
|
+
|
|
13
|
+
## The two-phase model
|
|
14
|
+
|
|
15
|
+
| Phase | When | Skill | Output |
|
|
16
|
+
|---|---|---|---|
|
|
17
|
+
| 1 — park the idea | a thought, no time to build | `docs-backlog` | a research doc in `research/` |
|
|
18
|
+
| 2 — graduate to specs | research exists, you're getting into it (a plan has come through) | **`spec-pipeline`** | numbered specs in `research/{topic}/`; **the plan is now ephemeral** |
|
|
19
|
+
| 3 — build | per spec | implement, then `docs-write` | working doc that `Source:`s its spec |
|
|
20
|
+
| 4 — compile | effort done | `docs-process` | living docs patched; specs + working docs archived together |
|
|
21
|
+
|
|
22
|
+
## What a pipeline folder contains
|
|
23
|
+
|
|
24
|
+
> **THIS FOLDER IS THE CREATE PAYLOAD.** Ignition does not compose a pipeline from memory or from a
|
|
25
|
+
> conversation — it DERIVES one from these files: the folder name is the topic, the umbrella's H1 is the
|
|
26
|
+
> title, `## The sequence` is the seat list, and the numbered specs are the seats. Author them knowing
|
|
27
|
+
> they will be read mechanically, and the ignition step becomes a verification rather than a
|
|
28
|
+
> transcription. The mapping is the table in `spec-ignite` § *the stage card is derived*; keep the two
|
|
29
|
+
> in step if either moves.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
docs/research/{topic}/
|
|
33
|
+
00-ignition-brief.md the coordinator's standing orders for THIS run (template below)
|
|
34
|
+
01-{topic}.md the umbrella: vision, the row table, settled decisions, hard constraints
|
|
35
|
+
02..NN-{slice}.md one self-contained spec per planned seat, in build order
|
|
36
|
+
project-status.md the living tracker — the coordinator's journal (template below)
|
|
37
|
+
live-checks.md the human's verification rows, accumulated as the run proceeds
|
|
38
|
+
sessions/ the CONVERSATION — see below. NOT authored here: the FIRST seat
|
|
39
|
+
brings it into existence when it files, so a fresh folder has none
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### `sessions/` — the conversation, and its durable record
|
|
43
|
+
|
|
44
|
+
**Nobody creates this folder as an act.** The FIRST seat brings it into existence by committing its two
|
|
45
|
+
files at close-out; every later seat writes into the folder that is already there. So: **do not author it
|
|
46
|
+
here, and never place a `.gitkeep` in it** — git tracks files, not directories, so a placeholder is the only
|
|
47
|
+
way to commit an empty one and there is nothing to commit. **A freshly authored pipeline folder has no
|
|
48
|
+
`sessions/`, and that is correct.**
|
|
49
|
+
|
|
50
|
+
It is a DESTINATION MAP, described here because four seats need to know where their artifact goes:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
sessions/ WHO PUTS IT THERE
|
|
54
|
+
{spec-slug}/plan.md each build seat, in its own close-out commit — the full plan, posted
|
|
55
|
+
once, corrected on pushback (PULL-only)
|
|
56
|
+
{spec-slug}/tldr.md each build seat, same commit — the two-voice CHAT: its TLDRs and
|
|
57
|
+
questions with the coordinator's rulings appended beneath them. Read
|
|
58
|
+
top-to-bottom it IS the session's whole conversation, in message order
|
|
59
|
+
code-review.md the review seat, in its own commit, if the run has a review row
|
|
60
|
+
parent-retrospective.md the coordinator, at the close
|
|
61
|
+
witness-ledger-*.md a human commit — the witness is zero-writes by contract (its ticket
|
|
62
|
+
cannot even carry the write scope), so its testimony reaches the repo
|
|
63
|
+
by someone else's hand
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
- **Per-seat artifacts go in a `{spec-slug}/` subfolder; effort-wide artifacts sit at the `sessions/`
|
|
67
|
+
root.** The first seat creates its subfolder and, incidentally, the parent folder; everything after
|
|
68
|
+
writes into what exists.
|
|
69
|
+
- **RE-COPY BOTH FILES ONCE, IMMEDIATELY BEFORE THE FINAL PUSH.** A seat's close-out receipt is written
|
|
70
|
+
AFTER the commit that carries its testimony, so a single copy always lands truncated — and a follow-up
|
|
71
|
+
commit only moves the truncation, because a receipt about THAT commit is also written after it. The
|
|
72
|
+
regress is infinite; the declared stopping point is one re-copy, leaving a residual of "I pushed X,
|
|
73
|
+
status clean" that git already records. `spec-seat` carries the rule; it is stated here because THIS
|
|
74
|
+
file is where the destination map lives.
|
|
75
|
+
- **Two files per build session — `plan.md` and `tldr.md`.** Questions ride the TLDR, so there is no
|
|
76
|
+
separate questions file, and there are no status snapshots: the tracker is committed live, so its git
|
|
77
|
+
history already carries the progression a snapshot would fake.
|
|
78
|
+
- **Append-only.** `tldr.md` grows; nobody rewrites it. The rev ladder is the history.
|
|
79
|
+
- **Who READS it:** the coordinator reads each TLDR and appends its rulings under `## PARENT RULING` · the
|
|
80
|
+
review seat reads every session's TLDR as testimony **and reads nothing else** · the retro greps it for
|
|
81
|
+
acceptance anchors and unanswered questions · the witness uses rev counts and mtimes as a zero-cost
|
|
82
|
+
heartbeat.
|
|
83
|
+
- **It archives with the effort**, and it is TESTIMONY: an archive pass repairs links elsewhere and
|
|
84
|
+
leaves `sessions/**` byte-untouched. Editing testimony to make it tidy is how a record stops being one.
|
|
85
|
+
|
|
86
|
+
## Steps
|
|
87
|
+
|
|
88
|
+
1. **Gather the inputs.** You need the *plan* (from a plan-approval mode, a conversation, or a written
|
|
89
|
+
one) and the *research doc(s)* behind it. Pick the `{topic}` folder name (kebab-case; reuse an existing
|
|
90
|
+
`research/{topic}/` if extending one).
|
|
91
|
+
|
|
92
|
+
2. **Decide the slices.** Each numbered spec is **one self-contained build seat**. Cut the plan along
|
|
93
|
+
session boundaries — a slice a single session can build *and* verify **before its context compacts**.
|
|
94
|
+
Put them in build order.
|
|
95
|
+
|
|
96
|
+
**Size each spec for ONE session, and let the count fall out of that.** A pipeline of one or two specs
|
|
97
|
+
is a pipeline; so is one of eight or ten. There is no target count — a plan stretched to fill a
|
|
98
|
+
"usual" number of rows produces thin specs that each cost a full session's ceremony, and a plan
|
|
99
|
+
compressed to hit a small number produces specs no session can finish before compaction. The test per
|
|
100
|
+
slice: recon + plan + build + suite + FINAL TLDR fits in one session with room for two rulings.
|
|
101
|
+
|
|
102
|
+
2b. **Decide the pipeline's SHAPE — ask the human both questions, with your recommendation.** The bookends
|
|
103
|
+
are rows in the row table like any other seat, which is why the decision belongs here: nothing
|
|
104
|
+
downstream needs a flag, and the coordinator learns the shape by reading its own sequence.
|
|
105
|
+
|
|
106
|
+
**"Do you want a REVIEW row?"** Recommend YES when the run ships a lot of code, touches security or
|
|
107
|
+
an authorization/identity path, spans many sessions whose seams nobody owns, or repairs the machinery
|
|
108
|
+
it runs on. Recommend NO for a docs-only effort or a single narrow slice. Say which and why — this is a
|
|
109
|
+
judgement about *this* code, so make the case and let the human rule.
|
|
110
|
+
|
|
111
|
+
**"Do you want DOCS-PROCESS as a row?"** In-pipeline gives you a zero-touch close: living docs patched
|
|
112
|
+
and the effort archived without a second sitting. **State the trade honestly:** `docs-process` is
|
|
113
|
+
designed as a fresh session over *merged* code, so in-pipeline it patches living docs against code that
|
|
114
|
+
is only **about to be** merged, and the `research/{topic}` to `archive/{topic}` rename rides the same
|
|
115
|
+
PR. If the PR is not merged, or is partly reverted, those docs describe something absent. **Say in the
|
|
116
|
+
brief that the living-doc patches are contingent on the merge.** Out-of-pipeline is equally valid and
|
|
117
|
+
cheap — every artifact is durable, so it runs cold, later, over several efforts at once.
|
|
118
|
+
|
|
119
|
+
**Each row's KIND is a real vocabulary, not a label** — `build` · `fixit` · `review` · `docs-process`
|
|
120
|
+
· `coordinator` · `retro` · `witness`. The kind decides which skills a seat is seeded with and which
|
|
121
|
+
verbs its credential admits, and a kind nobody has heard of composes NOTHING rather than something
|
|
122
|
+
plausible. Name rows in those words.
|
|
123
|
+
|
|
124
|
+
Then write the rows into the row table and the brief's sequence, in this order:
|
|
125
|
+
|
|
126
|
+
```
|
|
127
|
+
02..NN the build seats
|
|
128
|
+
{R} REVIEW — spec-review, if chosen. Runs on `git diff main...<branch>`; no PR yet
|
|
129
|
+
{F} FIXIT — MAY materialise, one maximum, only if the review classifies an (a)+(b)
|
|
130
|
+
finding AND the coordinator rules it in. Not authored up front; the
|
|
131
|
+
coordinator charters it from the review's named list
|
|
132
|
+
— the coordinator's retro + PR (its own close-out, not a row)
|
|
133
|
+
{P} DOCS-PROCESS — if chosen
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**The REVIEW row's seed carries NO coordinator beliefs** — no provenance list, no prior-shapes
|
|
137
|
+
bullets, no framing about what is already settled. Every other seat's prompt deliberately carries those;
|
|
138
|
+
this one must not, because the seat's whole value is the absence of the run's context. **Write that
|
|
139
|
+
instruction into the brief**, or it will be seeded helpfully and destroy what it is buying.
|
|
140
|
+
|
|
141
|
+
**The sequence you just decided lands in THREE documents, and they must agree**: the brief's
|
|
142
|
+
`## The sequence`, the umbrella's row table, and the tracker's `## Session status`. Write all three
|
|
143
|
+
in one pass, listing the same rows in the same order. **The coordinator re-checks this at ignition** —
|
|
144
|
+
an effort whose three documents disagree has one seat acting on a shape the others have stopped
|
|
145
|
+
describing.
|
|
146
|
+
|
|
147
|
+
3. **Write the specs**, using the spec-doc template in `docs/_meta/docs-workflow.md`. Each per-seat
|
|
148
|
+
spec opens with the spec-doc blockquote (`Builds on [prior]` + `Source: [umbrella / research]`) and the
|
|
149
|
+
`<!-- meta: type=spec; status=draft; verified={date}; lineage=N -->` line, so the set stays navigable.
|
|
150
|
+
|
|
151
|
+
**Six things every slice carries**, each earned by a session that did not have it:
|
|
152
|
+
|
|
153
|
+
- **AN ESCAPE HATCH — what a truthful PARTIAL looks like for THIS slice.** Name the smaller thing that
|
|
154
|
+
is still coherent and still shippable, and say what the builder must report when it stops there. This
|
|
155
|
+
is the highest-value sentence in a spec and one of the cheapest: a slice that has one lets a seat
|
|
156
|
+
stop cleanly on a measured number and say so; a slice without one leaves the cut to be improvised at
|
|
157
|
+
build time, under budget pressure, by the seat least able to judge it. **A spec with no partial
|
|
158
|
+
defined is a spec that can only succeed or lie.**
|
|
159
|
+
- **A size signal — even a wrong one.** Rough diff size, file count, session-fraction: anything. A
|
|
160
|
+
builder can correct an estimate at recon and will say so; it cannot correct silence, and a slice with
|
|
161
|
+
no signal reads as "however big it turns out to be."
|
|
162
|
+
- **The population, not an instance — and DERIVE it wherever you can.** *"Rename the verb at its 9 call
|
|
163
|
+
sites"* and *"rename the verb across its 433 occurrences in 86 files"* are different sessions. Count
|
|
164
|
+
the real population when you author the spec and write the number down; a census stated in instances
|
|
165
|
+
will be read as the whole job.
|
|
166
|
+
|
|
167
|
+
**A written count decays silently; a derived one cannot.** Prefer a spec that says *"derive the set
|
|
168
|
+
with this command and report what you got"* over one that hands over a number. A documented count
|
|
169
|
+
and a re-derived one have disagreed by a factor of two, and a correction has inherited the defect it
|
|
170
|
+
was correcting — because nobody re-ran the command.
|
|
171
|
+
|
|
172
|
+
**And say what produces the number you cite.** A count over rows measures only the paths that write
|
|
173
|
+
rows — a probe that logs failures and returns silently on success will read as *"never worked"* from
|
|
174
|
+
its row count when every silent run succeeded. **State the instrument before you state the figure.**
|
|
175
|
+
- **Verification stated as a PROPERTY, not a mechanical result.** Say what must be TRUE when the slice
|
|
176
|
+
is done, then offer commands as evidence for it. A prescribed result can be unsatisfiable by
|
|
177
|
+
construction — *"these three greps return zero"* cannot hold for a ban that must quote the thing it
|
|
178
|
+
bans, and the builder is then forced to choose between the letter and the point. State the property
|
|
179
|
+
and the letter can never contradict it.
|
|
180
|
+
- **A `last verified against` line — the date AND the sha the spec was checked against.** The
|
|
181
|
+
`meta: verified` stamp records authoring; this tells the BUILDER what the spec's facts are relative
|
|
182
|
+
to. **Recon's first act is to test whether the slice is already satisfied** — specs do get overtaken
|
|
183
|
+
between authoring and build, and a session that discovers this at recon closes in minutes while one
|
|
184
|
+
that assumes the work is pending rebuilds what already exists.
|
|
185
|
+
- **Cross-spec contracts written AS contracts.** When a slice produces something a later slice consumes
|
|
186
|
+
— a name, a shape, a column, an invariant — state it in both specs, in the same words, and mark it as
|
|
187
|
+
the contract. A dependency mentioned in prose in one spec and assumed in the other is not a contract;
|
|
188
|
+
it is two beliefs that happen to agree today.
|
|
189
|
+
|
|
190
|
+
**Cite symbols, not line numbers.** A spec outlives many commits, so name the symbol and use the line
|
|
191
|
+
as a hint. A line number is a comment, not an address: an anchor can drift several times inside a
|
|
192
|
+
single effort, invalidated each time by a seat documenting why the line mattered, and the only
|
|
193
|
+
citations that survive are symbol-named.
|
|
194
|
+
|
|
195
|
+
**When a slice REMOVES something, its census covers the copy that ADVERTISES it.** Not just the
|
|
196
|
+
plumbing — the system prompts, wake digests, tool catalogs, and doc counts that offer the thing to a
|
|
197
|
+
seat. A census that lists a tool's implementation and misses the two surfaces telling a seat the tool
|
|
198
|
+
exists has a blind spot. **A count pinned in a doc needs a named owning session**, or it rots: say
|
|
199
|
+
which spec moves it, and have the others leave it alone.
|
|
200
|
+
|
|
201
|
+
4. **Name the RESEARCH the effort came from, in the umbrella, by path.** The idea that fed this work
|
|
202
|
+
archives *with* it — that is how a topic folder ends up holding the whole arc from "thing we'd like to
|
|
203
|
+
do" to "done." When the research doc already lives at `research/{topic}/`, it travels for free. **When
|
|
204
|
+
it does not** — a standalone `research/{something}.md`, or several — the umbrella's `Source:` / Lineage
|
|
205
|
+
is the only record that it belongs to this effort.
|
|
206
|
+
|
|
207
|
+
**Say it plainly, because a later seat has to act on it:** whoever archives this gets handed that
|
|
208
|
+
list, and a research doc nobody named is one that stays behind in the running tab after its effort has
|
|
209
|
+
shipped. Two lines in the umbrella now saves a hunt through a shared folder later.
|
|
210
|
+
|
|
211
|
+
5. **Stop.** The specs stay in `research/{topic}/`. Do NOT implement, do NOT touch living docs, do NOT
|
|
212
|
+
archive — those are later phases. Output the new files only.
|
|
213
|
+
|
|
214
|
+
## The `00-ignition-brief.md` template
|
|
215
|
+
|
|
216
|
+
The coordinator's standing orders for this run, and **you write all of it here — every section, nothing
|
|
217
|
+
left blank.**
|
|
218
|
+
|
|
219
|
+
**Why here and not at ignition:** this is the hot session. You just placed the specs, counted the
|
|
220
|
+
populations, and read the code they cite, so you are the only seat that can state the baselines and the
|
|
221
|
+
platform state without guessing. **Ignition may be a cold session** — a different window, a different day —
|
|
222
|
+
whose job is to *verify* this brief against live HEAD and correct any drift, not to author it. Every
|
|
223
|
+
authoring act belongs to the session that has the context; every verifying act belongs to the one standing
|
|
224
|
+
next to the running system.
|
|
225
|
+
|
|
226
|
+
That includes the **kick text**: write the coordinator's task string here, ready to paste, so igniting
|
|
227
|
+
requires no authoring at all.
|
|
228
|
+
|
|
229
|
+
```markdown
|
|
230
|
+
# {Topic} — Ignition Brief (the coordinator's standing orders)
|
|
231
|
+
|
|
232
|
+
> You are the COORDINATOR of the {topic} pipeline. Read this, then the umbrella (01-*.md), then the
|
|
233
|
+
> tracker (project-status.md — yours), then EVERY numbered spec before arming the first seat.
|
|
234
|
+
<!-- meta: type=spec; status=draft; verified={date}; lineage=N -->
|
|
235
|
+
|
|
236
|
+
**Last verified against:** {date}, `{sha}`. Ignition re-verifies this brief against live HEAD and
|
|
237
|
+
corrects drift; it does not re-author it.
|
|
238
|
+
|
|
239
|
+
## Birth
|
|
240
|
+
Topic · spec path · receipt prefix · attended/unattended · branch `{the effort's branch}`.
|
|
241
|
+
|
|
242
|
+
## The sequence
|
|
243
|
+
| Seat | Spec | Kind | Why it sits here |
|
|
244
|
+
|
|
245
|
+
**THE `Kind` COLUMN IS THE VOCABULARY WORD, VERBATIM** — `build` · `fixit` · `review` ·
|
|
246
|
+
`docs-process` · `coordinator` · `retro` · `witness` — **not a prose role.** This table is READ, not
|
|
247
|
+
just read by people: ignition derives the create payload from it (`spec-ignite` § the stage card is
|
|
248
|
+
derived), and the create door validates the kind against a closed set and refuses an unknown by name.
|
|
249
|
+
A cell saying "the one that reviews" composes nothing.
|
|
250
|
+
|
|
251
|
+
**AND THE COORDINATOR IS A ROW.** It is a seat on the create payload like any other, it is not one
|
|
252
|
+
of the numbered specs, and a pipeline without exactly one is refused at start
|
|
253
|
+
(`pipeline-has-no-coordinator` / `-has-many-coordinators`). List it first, at stage 0, with the brief
|
|
254
|
+
as its spec.
|
|
255
|
+
|
|
256
|
+
Include the REVIEW and DOCS-PROCESS rows if the pipeline has them, and say which it does NOT have —
|
|
257
|
+
the coordinator needs to know whether a review precedes its retro. If there is a review row, add:
|
|
258
|
+
**its seed carries no coordinator beliefs, no provenance, no already-settled framing** · a FIXIT row
|
|
259
|
+
may follow it (one maximum, coordinator-ruled from the review's named candidates) · **the retro comes
|
|
260
|
+
after the review and after any fixit**, never before. If docs-process is a row, note that its
|
|
261
|
+
living-doc patches are contingent on the merge.
|
|
262
|
+
|
|
263
|
+
## The coordinator's beliefs, with provenance
|
|
264
|
+
Each load-bearing claim and which pipeline, row, or commit established it. A seat that finds a mismatch
|
|
265
|
+
has produced something worth more than a build hour. **Never head this section with a claim that
|
|
266
|
+
questioning it counts against the session** — that framing gets pointed at exactly the claims that
|
|
267
|
+
turn out to be wrong.
|
|
268
|
+
|
|
269
|
+
## Pipeline-specific law (beyond the prompt and the skills)
|
|
270
|
+
Only what OVERRIDES a default: the suite/coverage lane, spend fences, ordering constraints that are not
|
|
271
|
+
obvious from the specs, per-spec riders already ruled.
|
|
272
|
+
|
|
273
|
+
## Baselines
|
|
274
|
+
MEASURE these — run the suites and quote the real numbers. Ignition re-verifies; it cannot invent them.
|
|
275
|
+
Per lane: the result, **the exact invocation**, and **the environment it was measured in**. Three things
|
|
276
|
+
that each cost a live run:
|
|
277
|
+
- **A number without its invocation is not a receipt** — it invites the next reader to widen its scope.
|
|
278
|
+
Say which projects ran, not just a total.
|
|
279
|
+
- **State the environment.** A baseline measured with the stack down is a different number from one
|
|
280
|
+
measured with it up, and a seat that runs the wrong one sees a wall of red and suspects its own diff.
|
|
281
|
+
If a lane cannot run without infrastructure, say so and say what to do instead — do not invent a total.
|
|
282
|
+
- **A KNOWN-RED gets its own block, and it says "this is not your regression."** Quote the failure, name
|
|
283
|
+
why it fails, and say which count means fixed vs newly-broken. A seat meeting an undisclosed red will
|
|
284
|
+
reasonably suspect itself and burn a turn proving otherwise.
|
|
285
|
+
- **Name the LOAD ARTIFACTS and the tests that flake, individually.** A lane can be green in substance and
|
|
286
|
+
unstable under load — five failures that are all `Test timed out in 5000ms` with zero assertion failures
|
|
287
|
+
are a machine artifact, not a defect, and a runner that crashes outright on 1 of 2 runs is a third state
|
|
288
|
+
again. **List the flaky tests by name**, because "5 timeouts" is indistinguishable from a seat's own
|
|
289
|
+
breakage, and the ones nearest the session's subject are exactly where it will misattribute. Say what to
|
|
290
|
+
do: run the lane unloaded, never beside another suite, re-run once on a crash and stop on two.
|
|
291
|
+
|
|
292
|
+
## Platform state
|
|
293
|
+
What is known-broken or known-fixed in the machinery this pipeline stands on, and what a seat should do
|
|
294
|
+
when one of them misbehaves. VERIFY each claim against the code or a row; never write it from memory.
|
|
295
|
+
A brief that calls a fixed defect broken teaches the coordinator to work around nothing.
|
|
296
|
+
|
|
297
|
+
If this pipeline CHANGES the machinery it runs on — the ledger, the wake digest, the audit lane, the
|
|
298
|
+
sentinel, the gate — say so here, and tell the coordinator to expect to meet that defect while fixing it.
|
|
299
|
+
Meeting it is a first-hand receipt worth more than the spec's analysis: journal it and cite it in the fix.
|
|
300
|
+
|
|
301
|
+
## Close-out
|
|
302
|
+
Per-seat artifact filing · live-checks aggregation · what the PR must say · the receipt this pipeline
|
|
303
|
+
owes about itself.
|
|
304
|
+
|
|
305
|
+
**A HUMAN ROW OWES A RECEIPT, NOT A NARRATION.** If the pipeline has a human row, carry this rule
|
|
306
|
+
into the brief verbatim: the row is exempt from `plan.md` (there is no build to plan) and is **NOT**
|
|
307
|
+
exempt from an independent record. It files `sessions/{slug}/receipt.md` in the row's own commit —
|
|
308
|
+
each check id, what was run, the literal result, and who observed it. Every other row has TWO
|
|
309
|
+
voices, the seat's tldr and the coordinator's tracker, and the retro's ceremony audit is built on
|
|
310
|
+
cross-reading them; a human row recorded only by the coordinator has ONE, and the one voice is the
|
|
311
|
+
one whose errors nobody else catches.
|
|
312
|
+
|
|
313
|
+
## The kick — paste this verbatim as the coordinator's task
|
|
314
|
+
> You are the COORDINATOR of the {topic} pipeline. Invoke the `spec-parent` skill, then read
|
|
315
|
+
> `docs/research/{topic}/00-ignition-brief.md` and follow it. Your branch is `{the effort's branch}`.
|
|
316
|
+
|
|
317
|
+
Deltas true of THIS kick only (a concurrent pipeline, a model override, a one-off probe) go here as a
|
|
318
|
+
short list. Everything else is already in this brief — the task string is a POINTER, not a copy, and it
|
|
319
|
+
stays short because a task buried in a run row cannot be diffed or reviewed the way this file can.
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
**Do not restate the ceremony here.** The coordinator's procedure lives in `spec-parent` and its policy
|
|
323
|
+
rides the un-skippable policy suffix the control plane supplies; a brief that re-teaches them accretes
|
|
324
|
+
into prompt-law that breaks the coordinator it was meant to steer. The brief carries THIS RUN's
|
|
325
|
+
choreography and nothing else.
|
|
326
|
+
|
|
327
|
+
**The brief must be committed to the base branch before the run is kicked.** The coordinator reads it
|
|
328
|
+
from its worktree checkout, and the kick text points at it — so an uncommitted brief leaves it with almost
|
|
329
|
+
nothing. That makes it ignition's first gate, and it is the reason this file is worth authoring carefully.
|
|
330
|
+
|
|
331
|
+
## The `project-status.md` template
|
|
332
|
+
|
|
333
|
+
Not a spec — the **living tracker**, the coordinator's live journal. Ship it with its section
|
|
334
|
+
notes intact: they are where the tracker's own rules live, and they render invisibly in a markdown
|
|
335
|
+
viewer because they are instructions to the coordinator, not content for the human reading it.
|
|
336
|
+
|
|
337
|
+
```markdown
|
|
338
|
+
# {Topic} — Project Status
|
|
339
|
+
|
|
340
|
+
> The coordinator's ledger. Advanced at every session boundary, never reconstructed at close.
|
|
341
|
+
<!-- meta: type=working; status=wip; verified={date}; lineage=N -->
|
|
342
|
+
|
|
343
|
+
## What this is
|
|
344
|
+
{one paragraph}
|
|
345
|
+
|
|
346
|
+
## Session status
|
|
347
|
+
<!-- ready -> building -> SHIPPED {sha} / PARKED {sha}. One line each, no prose. -->
|
|
348
|
+
|
|
349
|
+
## Settled decisions
|
|
350
|
+
<!-- The don't-relitigate list, carried from the umbrella; append rulings that become standing. -->
|
|
351
|
+
|
|
352
|
+
## What's verified (trust basis)
|
|
353
|
+
<!-- What a build session may take on faith, and what it must re-check itself. -->
|
|
354
|
+
|
|
355
|
+
### Session {X} — spec {NN}
|
|
356
|
+
<!-- The journal, one prose section per session. The ruling AND its reasoning, recon corrections,
|
|
357
|
+
what the coordinator verified itself, mid-build directives, anything worth not forgetting.
|
|
358
|
+
Every entry stays independently readable by an ordinary offset/limit read — a section can be
|
|
359
|
+
paged and addressed by heading index; a table cell cannot be split by any reader that exists.
|
|
360
|
+
This is the raw material the retro is written FROM. -->
|
|
361
|
+
|
|
362
|
+
## Deferred findings log
|
|
363
|
+
<!-- THIS HEADING IS VERBATIM AND MUST NOT BE RENAMED. It is the destination every seat, review
|
|
364
|
+
and retro is pointed at by path + heading; a pipeline that renames it makes its own findings
|
|
365
|
+
unroutable to anyone who does not already know it — a review seat, whose entire value is having
|
|
366
|
+
none of the run's context, files to the name it was given and nowhere else.
|
|
367
|
+
|
|
368
|
+
{PREFIX}-n from ONE sequence for the whole pipeline, allocated by the coordinator only. One record per
|
|
369
|
+
finding; tag category INSIDE the record rather than opening a second log with its own numbering.
|
|
370
|
+
A SEAT OR REVIEW NEVER MINTS ITS OWN ID NAMESPACE — a second sequence beside the coordinator's
|
|
371
|
+
produces two findings under one id, and a reader who sees the id believes it handled.
|
|
372
|
+
Written at the moment of the finding, never batched at close.
|
|
373
|
+
|
|
374
|
+
Each record carries FIVE fields, and the fourth is what makes it a record rather than a note:
|
|
375
|
+
{PREFIX}-n · what is untrue or at risk · the receipt (file:line) · DESTINATION · status
|
|
376
|
+
A record with no DESTINATION is a note. The legal destinations are the closed set in
|
|
377
|
+
`spec-retro`'s findings disposition pass — this log is a HOLDING PEN, not an exit, and
|
|
378
|
+
"deferred log" is therefore never itself a destination.
|
|
379
|
+
|
|
380
|
+
THIS LOG IS DRAINED AT PIPELINE CLOSE by the retro's disposition pass: every entry leaves with a
|
|
381
|
+
destination or an explicit CLOSE, and the tally is published. Author the log knowing it must
|
|
382
|
+
drain — a log that is never drained outlives its pipeline and is read by nobody. -->
|
|
383
|
+
|
|
384
|
+
## Process incidents log
|
|
385
|
+
<!-- The moment behaviour is wrong — including the coordinator's own slips. -->
|
|
386
|
+
|
|
387
|
+
## Session-ID ledger
|
|
388
|
+
<!-- Seat -> the harness's session id -> window name. Written as each seat is armed. -->
|
|
389
|
+
|
|
390
|
+
## Working-doc manifest <- INCLUDE THIS SECTION ONLY IF THE PIPELINE HAS A P ROW
|
|
391
|
+
<!-- Row P is handed a LIST, never a directory: docs/working/ is a shared queue, and a seat that infers
|
|
392
|
+
membership from the folder can archive a neighbouring effort's docs — which it cannot undo.
|
|
393
|
+
DERIVE this as the pipeline runs; do NOT budget it at authoring. You cannot know the names up front
|
|
394
|
+
(each seat creates its working doc at close-out) and you cannot know the COUNT either — a
|
|
395
|
+
conditional fixit row adds one.
|
|
396
|
+
The coordinator writes each name at the reap that creates it, in the same pass as the SHIPPED row.
|
|
397
|
+
Rows that produce NO working doc — the review row — are recorded as such, not left blank. -->
|
|
398
|
+
|
|
399
|
+
| # | Working doc | Produced by | Status |
|
|
400
|
+
|---|---|---|---|
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
**Never generate a `## Checkpoint ledger` or a `## Parent decisions` section.** The session section
|
|
404
|
+
*is* the decision record; a parallel section splits one narrative across two places.
|
|
405
|
+
|
|
406
|
+
## `live-checks.md`
|
|
407
|
+
|
|
408
|
+
One file at the effort's root, created with the specs. Every parked demo and human-verification row lands
|
|
409
|
+
here — a seat's FINAL TLDR section (e) rows get transcribed into it **at close-out, in the same commit as
|
|
410
|
+
the work**. Rows scattered across five sessions' TLDRs and never aggregated is the most common thing to
|
|
411
|
+
fall through: name the file at authoring time so nobody invents a new one.
|
|
412
|
+
|
|
413
|
+
**The status vocabulary carries a PARTIAL, not just pass/fail:**
|
|
414
|
+
`owed` · `passed` · `failed` (a failure is a finding, not a retry) · `not exercised` (with the reason — an
|
|
415
|
+
honest and useful result) · **`partly` (with which half held and which did not)** · `superseded` (with
|
|
416
|
+
what replaced it).
|
|
417
|
+
|
|
418
|
+
**And a row whose subject decomposes into halves owned by different actors is authored as TWO rows.** A
|
|
419
|
+
single passed/failed cell over a check whose seed half was clean and whose platform half defeated it has
|
|
420
|
+
to invent a status to record the truth. **If you can name two owners while writing the row, write two
|
|
421
|
+
rows.**
|
|
422
|
+
|
|
423
|
+
**TWO WRITERS ON THIS FILE IS A DIVERGENCE WAITING TO HAPPEN — and it is the file the review grades
|
|
424
|
+
from.** The coordinator dictates rows into a seat's close-out call and the SEAT stages them; a seat never
|
|
425
|
+
writes it unprompted. Author the file knowing that, and do not write instructions telling the coordinator
|
|
426
|
+
to edit it directly.
|
|
427
|
+
|
|
428
|
+
## Notes
|
|
429
|
+
|
|
430
|
+
- **Cardinal rule — *spare no crumb*.** `spec-pipeline` is an **exploder**, not a condenser. Carry every
|
|
431
|
+
decision, every rejected alternative, every verified fact, every gotcha out of the plan and into the
|
|
432
|
+
specs. If a spec is *shorter* than the plan section it came from, it probably dropped a crumb.
|
|
433
|
+
- **Self-contained, like `docs-backlog`.** Assume the plan file (a scratch file under the harness's own
|
|
434
|
+
folder), the chat transcript, and any subagent reports vanish. Inline their load-bearing content; never
|
|
435
|
+
point at ephemeral state as the source of truth. Cross-links to *other durable docs* are fine.
|
|
436
|
+
- **Lifecycle.** Specs live in `research/{topic}/` through the build. When the effort ships, `docs-process`
|
|
437
|
+
archives the umbrella + every spec + the working docs together into `archive/{topic}/` — the spec set
|
|
438
|
+
*is* the design history.
|
|
439
|
+
- **Anti-fabrication.** A spec's `<!-- meta: verified -->` is the date it was *authored against the code it
|
|
440
|
+
cites*, not a promise the code stays unchanged. Only write facts you actually checked this run.
|
|
441
|
+
- **Author against the HEAD the run will start from — and know what that does not buy you.** Authoring close
|
|
442
|
+
to HEAD reduces drift; it does not substitute for a seat reading the code. Specs authored against the
|
|
443
|
+
exact HEAD they ran on have still had a load-bearing claim overturned at recon in every one. So write
|
|
444
|
+
specs as HYPOTHESES: state assumptions explicitly, because they are the first things recon tests, and
|
|
445
|
+
make them easy to correct.
|
|
446
|
+
- **Anchor-checking isn't design-checking.** A spec can ship with every anchor verified and a genuine
|
|
447
|
+
arithmetic bug. Work the DESIGN against real seeded state, not just the citations.
|
|
448
|
+
- **Leave one genuine fork OPEN per spec, with an embedded recommendation** (options a/b + "my
|
|
449
|
+
recommendation, confirm"). It guarantees the judging seat actually judges, and the builder's answer has
|
|
450
|
+
beaten both the spec's and the coordinator's designs.
|
|
451
|
+
- **Size for rider accretion.** Specs grow ~40% past authored size once riders land; cut slices with
|
|
452
|
+
headroom, and let overflow spin a `.5` fixit session rather than bloating a build session.
|
|
453
|
+
- Does NOT create working docs, patch living docs, or archive anything.
|