task-pipeline-skill 1.45.0 → 1.46.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/CHANGELOG.md +82 -0
- package/HOW-IT-WORKS.md +346 -0
- package/README.md +7 -0
- package/SKILL-CARD.md +1 -1
- package/package.json +2 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/skills/evidence-docs/SKILL.md +1 -1
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +8 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/acceptance.md +11 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +46 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +61 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/residue.md +219 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +45 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +7 -2
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,82 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v1.46.0 — what a run leaves running, what "done" costs to say, and what a check is for
|
|
4
|
+
|
|
5
|
+
Three rules this pipeline had been following by disposition rather than by doctrine,
|
|
6
|
+
and one it had not been following at all.
|
|
7
|
+
|
|
8
|
+
**`evidence-docs` can now be reached in Russian.** It shipped without Russian triggers
|
|
9
|
+
while `task-pipeline`, beside it in the same plugin, had carried them since v0.14.0 — a
|
|
10
|
+
navigator nobody can summon is a navigator nobody reads. Its description now opens with
|
|
11
|
+
`Use when …`, names twelve triggers on both sides, and keeps the `без доков` opt-out the
|
|
12
|
+
body always documented. `task-pipeline`'s own description is deliberately unchanged: the
|
|
13
|
+
house auditor requires every description to open with `Use when …`, this repository's
|
|
14
|
+
validator requires the opposite — capability first, trigger second — and fails the build
|
|
15
|
+
on anything else. Measured in both directions; which of the two rules is wrong is a
|
|
16
|
+
decision, not a fix to slip into a release.
|
|
17
|
+
|
|
18
|
+
**A run is not only a diff — it is also everything it left running.** A background
|
|
19
|
+
shell, a monitor polling an API, a scheduled loop, a coordination lease, a worktree,
|
|
20
|
+
a container, scratch files, a draft PR. `references/residue.md` names eight classes
|
|
21
|
+
and requires each to be enumerated **by class, never by one tool** — because the
|
|
22
|
+
measured case that produced this file was a task inventory reporting *"No tasks
|
|
23
|
+
found"* while `ps` showed the monitor alive and polling every thirty seconds. An
|
|
24
|
+
inventory that does not contain the thing that leaks is a green light with no lamp
|
|
25
|
+
behind it.
|
|
26
|
+
|
|
27
|
+
Every gate now prints `holds: N` beside its verdict, the run ledger gains a fifth
|
|
28
|
+
declared line shape, and stage 10 gains criterion 13: give the environment back.
|
|
29
|
+
The asymmetry is the point — **end what this run started, report what it did not**.
|
|
30
|
+
The inventory is machine-wide and the authority is not, so a stale-looking lease
|
|
31
|
+
belonging to another agent is named, never released.
|
|
32
|
+
|
|
33
|
+
The field is `holds:` rather than `residue:` because `gates.md` already prints
|
|
34
|
+
`unmarked residue: 0` for documentation items, and `residue: 0` is a substring of
|
|
35
|
+
it. A check written for the new field would have been answered by the old line — the
|
|
36
|
+
class this repository has now met nine times, caught here before it shipped.
|
|
37
|
+
|
|
38
|
+
**"Done" is a claim, and it names what makes it true.** Every disclosure in this
|
|
39
|
+
bundle asks *what does it print when it did not look?* — of checks. `progress.md`
|
|
40
|
+
now asks it of the run's own sentences, which reach the operator where the check
|
|
41
|
+
does not. Three shapes, each requiring no intent to mislead: the plan reported as
|
|
42
|
+
the outcome, the reply reported as the result, the part reported as the whole. And
|
|
43
|
+
the honest negative is a result: *"not done, the fixture needs a credential I do not
|
|
44
|
+
have"* is a complete report where *"done, with a small caveat"* is not.
|
|
45
|
+
|
|
46
|
+
**The result is the goal; the check is how you know.** Every other line in
|
|
47
|
+
`gates.md` pushes one way — prove more, assume less — and read alone it produces a
|
|
48
|
+
run that spends an afternoon proving a one-character change. Verification now scales
|
|
49
|
+
to what breaking costs, using the `sev × blast` the board already computes, with
|
|
50
|
+
four named signals that you have crossed over. This never licenses skipping a gate:
|
|
51
|
+
the floor is not proportionate to anything, and cutting it to go faster is the
|
|
52
|
+
failure the file exists to prevent, arriving on schedule.
|
|
53
|
+
|
|
54
|
+
**Publishing was half a loop.** `retrospective.md` closes it: an issue resolves when
|
|
55
|
+
the **behaviour** changed and its closing comment names the file, the line and the
|
|
56
|
+
guard; an issue nobody worked stays open rather than being triaged into silence;
|
|
57
|
+
nothing is deleted, because the number is what the CHANGELOG points at. The queue a
|
|
58
|
+
run pulls from when it finishes early is that pile, then the board, then the open
|
|
59
|
+
questions.
|
|
60
|
+
|
|
61
|
+
Guards: 275 → **291**, each still proven against a planted defect — including a
|
|
62
|
+
neighbour probe that caught a defect in one of this release's own guards on its
|
|
63
|
+
first use: the criterion-13 check scoped *to the next heading* rather than *to the
|
|
64
|
+
item*, so a needle parked in between answered for the rule.
|
|
65
|
+
|
|
66
|
+
## v1.45.1
|
|
67
|
+
|
|
68
|
+
### Fixed
|
|
69
|
+
|
|
70
|
+
- **The v1.45.0 entry had no `Guards: N → **M**` line**, so the negative
|
|
71
|
+
self-test that plants a stale count had nothing to plant into and failed with
|
|
72
|
+
`PLANT DID NOT LAND`. The count is a claim about *now* and every release
|
|
73
|
+
section is required to restate it — a release that omits it silently disarms
|
|
74
|
+
the check that keeps the number honest.
|
|
75
|
+
|
|
76
|
+
### Counts
|
|
77
|
+
|
|
78
|
+
- Guards: 275 → **275**.
|
|
79
|
+
|
|
3
80
|
## v1.45.0
|
|
4
81
|
|
|
5
82
|
### Changed
|
|
@@ -17,6 +94,11 @@
|
|
|
17
94
|
from the 2026-08-03 design, and refused two rewordings before accepting one
|
|
18
95
|
in text nothing had locked.
|
|
19
96
|
|
|
97
|
+
### Counts
|
|
98
|
+
|
|
99
|
+
- Guards: 275 → **275** — this release adds none; it removes duplication from
|
|
100
|
+
the body and touches no check.
|
|
101
|
+
|
|
20
102
|
### Known gap
|
|
21
103
|
|
|
22
104
|
- **The body is still 6088 tokens against a 5000 cap.** What remains is a
|
package/HOW-IT-WORKS.md
ADDED
|
@@ -0,0 +1,346 @@
|
|
|
1
|
+
# How task-pipeline works
|
|
2
|
+
|
|
3
|
+
**The living high-level view.** This file is rewritten with every release. It
|
|
4
|
+
explains the machine — what routes a request into it, what each stage refuses to
|
|
5
|
+
let past, and what makes any claim it prints believable. The README sells it and
|
|
6
|
+
tells you how to install it; this file tells you how it thinks.
|
|
7
|
+
|
|
8
|
+
> **Version 1.45.0.** The "What changed" section at the bottom carries the last
|
|
9
|
+
> few releases. Everything above it describes the pipeline as it is *now*, not as
|
|
10
|
+
> it was designed.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## The one-sentence version
|
|
15
|
+
|
|
16
|
+
A coding agent takes a substantial task, interrogates it into a complete brief,
|
|
17
|
+
then walks it through **ten gated stages** and refuses to advance until each
|
|
18
|
+
gate passes — closing by accounting for every requirement from a list rather than
|
|
19
|
+
from memory.
|
|
20
|
+
|
|
21
|
+
The reason it exists: agents write code well and judge *when to stop asking you
|
|
22
|
+
things* badly. Left alone, a substantial task becomes twenty interruptions, or a
|
|
23
|
+
confident build that skipped the tests and quietly delivered two thirds of what
|
|
24
|
+
you asked for.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. How a request finds the pipeline
|
|
29
|
+
|
|
30
|
+
An agent choosing skills sees exactly one thing: the `description` field in
|
|
31
|
+
`SKILL.md`. It is capped at **1024 characters** and currently uses **1008** — that
|
|
32
|
+
headroom is the budget every future addition pays from, which is why it is
|
|
33
|
+
tracked as a board row rather than left to be discovered.
|
|
34
|
+
|
|
35
|
+
It is written in three parts, and the middle one was learned the hard way:
|
|
36
|
+
|
|
37
|
+
- **Work that changes the repository** — a feature, fix, refactor, migration,
|
|
38
|
+
integration, rewrite, adoption or hardening, in English and Russian both.
|
|
39
|
+
- **Work whose *output* lands in the repository** — `audit`, `bug hunt`,
|
|
40
|
+
`production check`, `PR review`. Before this clause existed, agents facing
|
|
41
|
+
"проверь, нет ли ошибок" **quoted this skill's own exclusion line as their
|
|
42
|
+
reason to refuse**. The measurement is in `evals/routing/RESULTS.md`.
|
|
43
|
+
- **What it is not for** — answering a question, explaining code, a typo, a
|
|
44
|
+
one-line edit. The boundary runs in both directions on purpose: running ten
|
|
45
|
+
stages for one character is the fastest way to teach an agent to route around
|
|
46
|
+
the pipeline entirely.
|
|
47
|
+
|
|
48
|
+
Two modes need no task at all. `checkup` reports what has shipped without anyone
|
|
49
|
+
confirming it. `setup` audits the documentation a project already has.
|
|
50
|
+
|
|
51
|
+
**Honest limit:** this measures the *description's* discriminating power, not the
|
|
52
|
+
host's selection machinery. Three measured runs scored 7/10, 9/10 and 8/10 — and
|
|
53
|
+
one sample per query cannot separate an effect from noise, which the measurement
|
|
54
|
+
discovered about itself by being run twice.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
58
|
+
## 2. Preflight — two things settled once
|
|
59
|
+
|
|
60
|
+
**Model.** The most capable tier the environment offers, named as a *tier*, never
|
|
61
|
+
as a vendor id. A hardcoded model id in shipped doctrine is a validator failure,
|
|
62
|
+
because it rots the moment the vendor ships a new one.
|
|
63
|
+
|
|
64
|
+
**Companions.** `super-ux`, `copywriting`, `sheleg-design`, `graphify`, the wiki.
|
|
65
|
+
The detection block prints once. A missing companion states its fallback and
|
|
66
|
+
**does not block** — the single exception being the stage-3 UX track on
|
|
67
|
+
user-facing work, where shipping without it is a decision someone has to make out
|
|
68
|
+
loud.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## 3. Stage 0 — where the run is won or lost
|
|
73
|
+
|
|
74
|
+
This is the heaviest stage and that is deliberate. Everything downstream is an
|
|
75
|
+
attempt to execute a brief; a bad brief cannot be rescued by good execution.
|
|
76
|
+
|
|
77
|
+
### The harvest runs before the first question
|
|
78
|
+
|
|
79
|
+
Pull what the project already knows about *this task*:
|
|
80
|
+
|
|
81
|
+
| Source | What it uniquely answers |
|
|
82
|
+
|---|---|
|
|
83
|
+
| the code | what is there |
|
|
84
|
+
| **the code graph** (`graphify-out/graph.json`) | **reach** — what calls this, what breaks if it moves. `grep` cannot answer this |
|
|
85
|
+
| `CLAUDE.md`, ADRs, `docs/`, `docs/ux/` | what was decided and why |
|
|
86
|
+
| **the retro, read in full** | the standing instructions that *bind this run* |
|
|
87
|
+
| the knowledge wiki | what past runs distilled |
|
|
88
|
+
| the board and the verification ledger | what is open, and what shipped unverified |
|
|
89
|
+
|
|
90
|
+
The output is a **source ledger** — a row per source, or an explicit *none found*.
|
|
91
|
+
An absent source that is never named looks identical to a source that was read.
|
|
92
|
+
|
|
93
|
+
### Then the grill, and it is mandatory
|
|
94
|
+
|
|
95
|
+
One question per turn, each with a recommended answer, exploring the codebase
|
|
96
|
+
before asking, until every decision branch is resolved.
|
|
97
|
+
|
|
98
|
+
- **Every answer is validated against the harvested sources.** The operator
|
|
99
|
+
outranks any document — but only *out loud*, and a document the run proves stale
|
|
100
|
+
is logged for stage 9 rather than silently ignored.
|
|
101
|
+
- **The autonomy sweep** pre-resolves what would otherwise stop stages 1→10: test
|
|
102
|
+
and lint commands, branch and tracker policy, deploy target and authorization,
|
|
103
|
+
where the logs live. Every question asked here is an interruption that does not
|
|
104
|
+
happen later.
|
|
105
|
+
- **UI work adds the design surface** — Figma connected or text-only, and *which
|
|
106
|
+
file*, named before the first frame. A destination decided at drawing time is
|
|
107
|
+
how a project ends up with three design files and no way to tell which is real.
|
|
108
|
+
|
|
109
|
+
### The brief closes on the REQ table
|
|
110
|
+
|
|
111
|
+
The request as an **addressable list**, where every row names how it will be
|
|
112
|
+
verified. Frozen from here: adding is free, removing needs the operator. Anything
|
|
113
|
+
deferred enters the carry-over ledger the moment it is said, not at the end when
|
|
114
|
+
it has been forgotten.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 4. Stages 1→10
|
|
119
|
+
|
|
120
|
+
| | Stage | What must be true to leave it | Gate |
|
|
121
|
+
|---|---|---|---|
|
|
122
|
+
| 1 | Docs study | every contract the design will lock is grounded on **fetched** docs, not recall | auto |
|
|
123
|
+
| 2 | Brainstorm + decompose | design approved, every REQ answered by it. A platform is cut into modules, **walking skeleton first**, every REQ in exactly one module | manual |
|
|
124
|
+
| 3 | Spec | contracts locked. User-facing work runs three tracks — what it **does**, how it **sounds**, how it **looks**. A declined track is recorded, never silent | manual |
|
|
125
|
+
| 4 | Plan | the REQ set-comparison holds: brief REQs == union of `Implements:` | auto |
|
|
126
|
+
| 5 | Build | TDD per task, a review after each, findings fixed or parked **with a ruling** | auto |
|
|
127
|
+
| 6 | Tests | the **full** suite green; a web surface checked in a browser, not in the diff | auto |
|
|
128
|
+
| 7 | Lint + deploy | the authorization is specific, and the CI verdict is **read** before any tag | manual |
|
|
129
|
+
| 8 | Post-deploy | the verification trio, not one of three; a verification row per shipped REQ | auto |
|
|
130
|
+
| 9 | Docs + wiki | **three** artifacts — module docs, the wiki, and the code graph | auto |
|
|
131
|
+
| 10 | Acceptance | the ladder walk first, then the table, then the retrospective | manual |
|
|
132
|
+
|
|
133
|
+
### Why the manual gates are where they are
|
|
134
|
+
|
|
135
|
+
`auto` means the agent verifies the check itself and proceeds. `manual` means it
|
|
136
|
+
waits for an explicit go. The four manual gates sit at the four places where a
|
|
137
|
+
wrong turn is expensive and hard to reverse: **what we are building** (2), **the
|
|
138
|
+
contracts** (3), **the outside world** (7), and **whether it is done** (10).
|
|
139
|
+
Everywhere else, stopping to ask costs more than it saves.
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 5. The three rules that fire at any stage
|
|
144
|
+
|
|
145
|
+
**The loop guard.** If a pass starts undoing an earlier one — the same file edited
|
|
146
|
+
twice for the same reason, a closed finding returning, a third entry into one
|
|
147
|
+
stage — editing stops. Name both shapes, escalate to the layer that owns the
|
|
148
|
+
conflict, re-plan as an ordered list, then go item by item. "Cleanup" and "polish"
|
|
149
|
+
are explicitly *not* valid reasons for an edit; every change needs one traceable
|
|
150
|
+
cause.
|
|
151
|
+
|
|
152
|
+
**The audit's exit.** If a searching pass starts finding mostly what the previous
|
|
153
|
+
pass's own fixes broke, the axis is exhausted. **Rotate the axis — do not look
|
|
154
|
+
harder.**
|
|
155
|
+
|
|
156
|
+
**Evidence.** A green from a check nobody has watched fail against a planted
|
|
157
|
+
defect is not evidence. A finding class seen twice becomes a script, not a third
|
|
158
|
+
ledger row.
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 6. The loop — walking a queue without asking permission
|
|
163
|
+
|
|
164
|
+
Recorded in `pipeline.json` → `run.loop`:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
loop:
|
|
168
|
+
mode: off | interval | dynamic
|
|
169
|
+
queue: module-map | plan-tasks | none
|
|
170
|
+
arm: preflight | after-decomposition
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**A loop with no queue is a timer.** The queue belongs to stage 2 — the module map
|
|
174
|
+
or the plan's task list. Nothing third is invented. The loop arms at the *close of
|
|
175
|
+
stage 2*, when the mode is recorded and the queue holds more than one item.
|
|
176
|
+
Between items the goal is re-read, so tasks can be re-prioritised or moved to the
|
|
177
|
+
board as the run learns.
|
|
178
|
+
|
|
179
|
+
The rule that keeps this safe: **arming is the execution of a recorded decision,
|
|
180
|
+
not a fresh request. Where nothing is recorded, nothing arms.** Default off.
|
|
181
|
+
Silence arms nothing.
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 7. The hand-back — what a run says when it stops
|
|
186
|
+
|
|
187
|
+
Long iterations lose context. So at the end of every iteration, and at stage 10,
|
|
188
|
+
the run reports in a fixed shape:
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
TASK the request AS IT WAS GIVEN, quoted from the brief
|
|
192
|
+
PROGRESS where the run stands against that request
|
|
193
|
+
DONE what was solved, each with its evidence
|
|
194
|
+
SURFACED what came up that nobody asked for
|
|
195
|
+
DECISIONS WAITING <n> each as a question with options, asked HERE
|
|
196
|
+
AMBIGUITIES <n> computed from the registers, below
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Three details carry the weight:
|
|
200
|
+
|
|
201
|
+
- `TASK` is **quoted, not paraphrased** — the paraphrase is exactly what drifts.
|
|
202
|
+
- `DECISIONS WAITING` are asked **here**, not deferred. A missing decision, a
|
|
203
|
+
missing document or an ambiguity left standing is what turns into a large
|
|
204
|
+
consequence three stages later.
|
|
205
|
+
- `AMBIGUITIES` is **computed from four registers that already exist** — not a
|
|
206
|
+
fifth document nobody maintains.
|
|
207
|
+
|
|
208
|
+
It is traced by a `hand:` line in `.task-pipeline/run.md`, beside `stage:`,
|
|
209
|
+
`iter:`, `touch:` and `holds:`. That is what makes it a check rather than an intention.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## 8. Stage 10 — the close-out, in order
|
|
214
|
+
|
|
215
|
+
1. **The ladder walk, first.** The REQ table finds what was named and lost; it
|
|
216
|
+
**cannot** find what was never named, because a comparison needs two sides and
|
|
217
|
+
an absence has one. So every REQ is walked bottom-up — decision → spec section
|
|
218
|
+
→ contract *and its failure behaviour* → task → change → executed test →
|
|
219
|
+
surface and docs — checking the seam at each step. Findings are ordered **by
|
|
220
|
+
seam, not by file**. Every absence becomes a new REQ row *before* the table.
|
|
221
|
+
2. **The coverage table** — one row per REQ, each with evidence. Four statuses
|
|
222
|
+
only: verified, partial, deferred, dropped. `unknown` fails the gate.
|
|
223
|
+
3. **The ledgers close.** Every carry-over row still open leaves with a board id,
|
|
224
|
+
and priorities are re-derived. The counts print beside every gate verdict, so
|
|
225
|
+
*green* never reads as *verified*.
|
|
226
|
+
4. **Several repositories? The parent closes too.** A submodule can be committed,
|
|
227
|
+
pushed and green while a clone of the parent still gets the commit before it,
|
|
228
|
+
and neither repo looks wrong alone.
|
|
229
|
+
5. **The retrospective is the run's last act**, in this order: stamp the run →
|
|
230
|
+
prune every standing instruction against its retirement triggers (list held to
|
|
231
|
+
ten, every deletion logged) → write an entry **only if the run diverged**.
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## 9. Why you should believe anything it prints
|
|
236
|
+
|
|
237
|
+
This is the part most pipelines skip, and it is the reason this one is trustworthy
|
|
238
|
+
rather than merely tidy.
|
|
239
|
+
|
|
240
|
+
**Every guard is proven against a planted defect.** `npm run test:all` breaks the
|
|
241
|
+
thing each of the **291** checks is about, and requires that check to reject it. A
|
|
242
|
+
guard that has never been watched failing is not a guard; it is a comment.
|
|
243
|
+
|
|
244
|
+
**The neighbour probe.** A check has a *subject* — the rule it is about — and
|
|
245
|
+
*evidence* — the text it actually reads. When those differ, it goes green for
|
|
246
|
+
reasons unrelated to the rule and no ordinary probe can tell. So: break the
|
|
247
|
+
subject, plant the guard's **current** needle next door, and require it to still
|
|
248
|
+
fail. Six guards in one session were defeated this way — none of them by their own
|
|
249
|
+
probes, all of them by a reader.
|
|
250
|
+
|
|
251
|
+
**Disclosures are not ratchets.** Alongside every verdict the suite prints what it
|
|
252
|
+
*could not* look at — `unlooked: N`, listed by name; `abstained` where a check's
|
|
253
|
+
precondition was absent. No floor, no direction, **never a target**. A number that
|
|
254
|
+
becomes a target stops being a measurement.
|
|
255
|
+
|
|
256
|
+
**Corpora are discovered, not listed.** Three hand-written lists each missed a
|
|
257
|
+
shipped surface, and none of the misses was found by the guard holding the list. A
|
|
258
|
+
new surface joins a check by *existing*.
|
|
259
|
+
|
|
260
|
+
**The scaffold's own gate runs.** One guard executes `templates/docgate.sh` over a
|
|
261
|
+
scratch project seeded from the templates and requires exit `0`. A scaffold whose
|
|
262
|
+
gate rejects its own seeds teaches every new project that the gate is noise.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 10. The improvement iteration
|
|
267
|
+
|
|
268
|
+
The pipeline improves itself on a loop, and the loop is mechanical rather than
|
|
269
|
+
aspirational:
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
a run diverges → retro entry → retro.publish → upstream issue
|
|
273
|
+
↓
|
|
274
|
+
board row ← measured against the tree ← triaged next cycle
|
|
275
|
+
↓
|
|
276
|
+
doctrine change + a guard that proves it → release → the run reads it
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
- **`retro.publish`** turns a lesson that is bigger than one project into a GitHub
|
|
280
|
+
issue on the skill itself. Six such insights arrived in a single day.
|
|
281
|
+
- **Issues are resolved, never deleted.** Ones we have worked through are closed
|
|
282
|
+
with a comment naming what they changed. Ones we have not accumulate visibly and
|
|
283
|
+
are picked up in the next cycle. The pile is the queue, and a deleted issue takes
|
|
284
|
+
its number — the one the CHANGELOG points at — with it.
|
|
285
|
+
- **A finding closes when behaviour changes**, not when it is understood.
|
|
286
|
+
- **A board row is measured against the tree, not read.** Rows have been found
|
|
287
|
+
already closed for two days, and rows whose text was true while the thing they
|
|
288
|
+
described had moved.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## What changed, by version
|
|
293
|
+
|
|
294
|
+
### v1.45.0 — what a run leaves running, what "done" costs to say, what a check is for
|
|
295
|
+
Four rules the pipeline had been following by disposition rather than by doctrine.
|
|
296
|
+
**Residue**: eight classes of thing a run leaves running or leaves behind, enumerated
|
|
297
|
+
by class and never by one tool — the case that produced it was a task inventory
|
|
298
|
+
reporting *"No tasks found"* over a live, polling monitor. `holds: N` beside every
|
|
299
|
+
gate verdict, a fifth run-ledger line shape, and stage-10 criterion 13: end what this
|
|
300
|
+
run started, **report** what it did not. **Completion honesty**: *"done"* names what
|
|
301
|
+
makes it true, and the honest negative is a result. **Proportionate verification**:
|
|
302
|
+
the deliverable is the working result and the check is how you know — scaled to
|
|
303
|
+
`sev × blast`, never by cutting the floor. **The improvement iteration**: a published
|
|
304
|
+
issue resolves when behaviour changed and its close names the address; unworked ones
|
|
305
|
+
accumulate visibly rather than being triaged into silence. Guards: 275 → 291.
|
|
306
|
+
|
|
307
|
+
### v1.44.0 — six lessons from other projects, and the guards that hold them
|
|
308
|
+
Six issues published by runs in other repositories were worked into doctrine:
|
|
309
|
+
seam testing at stage 6, `verified by` names that must resolve, a probe's green
|
|
310
|
+
being evidence only when the mutation is known to have landed, what a test case
|
|
311
|
+
consumes and why a timeout is unclassified, `publish:` as a line in the verdict
|
|
312
|
+
rather than a silence, and a ratchet's matcher being itself a check. Twelve new
|
|
313
|
+
guards; the suite reached 275. An independent review found eight further defects
|
|
314
|
+
in the implementation, all closed before merge.
|
|
315
|
+
|
|
316
|
+
### v1.43.0 — the hand-back
|
|
317
|
+
Long iterations lose the original request. Stage 10 and every iteration boundary
|
|
318
|
+
now report TASK / PROGRESS / DONE / SURFACED with decisions and ambiguities
|
|
319
|
+
counted, traced by a `hand:` line in the run ledger.
|
|
320
|
+
|
|
321
|
+
### v1.42.0 — the neighbour probe
|
|
322
|
+
Four consecutive releases had guards defeated by independent readers 15, 6, 6 and
|
|
323
|
+
8 times, and the trend did not decline. The class: a check answered by text that
|
|
324
|
+
is not its subject. The mechanism, with its honest limit stated as a number.
|
|
325
|
+
|
|
326
|
+
### v1.40.0 — the loop got a queue
|
|
327
|
+
`run.loop` previously said *how often* without ever naming *what* the loop walks.
|
|
328
|
+
The queue is stage 2's, and the loop arms on it.
|
|
329
|
+
|
|
330
|
+
### v1.39.0 — findings-shaped work got an entry
|
|
331
|
+
Audits, bug hunts, production checks and PR reviews produce output that lands in
|
|
332
|
+
the repository, but the routing surface pointed away from them — agents quoted the
|
|
333
|
+
exclusion clause as their reason to refuse.
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## Where to read further
|
|
338
|
+
|
|
339
|
+
| You want | Read |
|
|
340
|
+
|---|---|
|
|
341
|
+
| install it, use it | [`README.md`](README.md) |
|
|
342
|
+
| change it | [`CONTRIBUTING.md`](CONTRIBUTING.md) — the invariants live there |
|
|
343
|
+
| why a release happened | [`CHANGELOG.md`](CHANGELOG.md) |
|
|
344
|
+
| the stage doctrine itself | `plugins/task-pipeline/skills/task-pipeline/references/` |
|
|
345
|
+
| what is open | [`docs/superpowers/backlog.md`](docs/superpowers/backlog.md) |
|
|
346
|
+
| what is genuinely unresolved | [`docs/OPEN_QUESTIONS.md`](docs/OPEN_QUESTIONS.md) |
|
package/README.md
CHANGED
|
@@ -20,6 +20,12 @@ Built for **Claude Code**, and installable into any agent that reads skills
|
|
|
20
20
|
no companion plugin, nothing to resolve, nothing that breaks when a dependency is
|
|
21
21
|
missing.
|
|
22
22
|
|
|
23
|
+
> **Want the machine rather than the pitch?**
|
|
24
|
+
> [**`HOW-IT-WORKS.md`**](HOW-IT-WORKS.md) is the living high-level view
|
|
25
|
+
> — what routes a request in, what each gate refuses to let past, why the manual
|
|
26
|
+
> gates sit where they do, and what makes any claim this pipeline prints
|
|
27
|
+
> believable. Rewritten every release.
|
|
28
|
+
|
|
23
29
|
---
|
|
24
30
|
|
|
25
31
|
## The flow
|
|
@@ -128,6 +134,7 @@ until it is installed.
|
|
|
128
134
|
| 10 Acceptance | [`acceptance.md`](plugins/task-pipeline/skills/task-pipeline/references/acceptance.md) — REQ coverage table, evidence rules, the closing question |
|
|
129
135
|
| 10 + any audit | [`audit.md`](plugins/task-pipeline/skills/task-pipeline/references/audit.md) — the L0→L7 ladder and its seams, axis rotation, ratchets, proven checks |
|
|
130
136
|
| any loop | [`loop-guard.md`](plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md) — churn detection, caps, the break protocol |
|
|
137
|
+
| every gate + stage 10 | [`residue.md`](plugins/task-pipeline/skills/task-pipeline/references/residue.md) — what the run leaves **running** and leaves **behind**: eight classes enumerated by class rather than by one tool, `holds: N` beside every verdict, and a teardown that ends what this run started and only reports what it did not |
|
|
131
138
|
| run-wide reporting | [`progress.md`](plugins/task-pipeline/skills/task-pipeline/references/progress.md) — the header block at task start and the one-line iteration close: the stage rail computed from the project's own `pipeline.json`, every number borrowed from the gate that measured it |
|
|
132
139
|
| run-wide pacing | [`continuity.md`](plugins/task-pipeline/skills/task-pipeline/references/continuity.md) — the loop mode (`run.loop`, default off, never collapses a manual gate) and the context budget (fires on a harness signal, never on an estimate) |
|
|
133
140
|
| the board between runs | [`backlog.md`](plugins/task-pipeline/skills/task-pipeline/references/backlog.md) — the work-list that outlives a run: seeded at stage 0 or picked up, priority **computed** from three stated inputs rather than assigned, and the seam where the carry-over ledger's `backlog` pointer finally resolves |
|
package/SKILL-CARD.md
CHANGED
|
@@ -12,7 +12,7 @@ harmless.
|
|
|
12
12
|
|---|---|
|
|
13
13
|
| **Purpose** | Runs a substantial task through ten gated delivery stages — intake grill, docs study, brainstorm, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs+registers, acceptance — refusing to advance until each gate passes |
|
|
14
14
|
| **Owner** | ssheleg ([github.com/ssheleg/task-pipeline](https://github.com/ssheleg/task-pipeline)) |
|
|
15
|
-
| **Version** | 1.
|
|
15
|
+
| **Version** | 1.46.0 |
|
|
16
16
|
| **Surface** | Claude Code (filesystem skill + plugin) and the vercel `skills` CLI. **Not** uploaded to the Skills API; custom Skills do not sync across surfaces |
|
|
17
17
|
| **Dependencies** | None required. Optional: `context7` (MCP), `figma` (MCP), super-ux, agent-sync, graphify, obsidian-wiki. Every stage's doctrine ships in-repo; the one conditional requirement is super-ux for the stage-3 UX track on a user-facing task |
|
|
18
18
|
| **Evaluation status** | Suite authored, 5 categories. One recorded run, **self-observed by the author**; **zero blind runs on zero of three models** — the split, and the numbers, live in [`evals/RESULTS.md`](evals/RESULTS.md) and are computed by `evals/run.py` |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "task-pipeline-skill",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.46.0",
|
|
4
4
|
"description": "Full-cycle delivery pipeline for coding agents: a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine ships inside the skill — no companion plugin required. This package is the installer CLI.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"task-pipeline": "bin/task-pipeline.js"
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
"cursor",
|
|
18
18
|
"evals",
|
|
19
19
|
"README.md",
|
|
20
|
+
"HOW-IT-WORKS.md",
|
|
20
21
|
"SKILL-CARD.md",
|
|
21
22
|
"LICENSE",
|
|
22
23
|
"CHANGELOG.md",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "task-pipeline",
|
|
3
3
|
"displayName": "Task Pipeline",
|
|
4
4
|
"description": "Runs a substantial task through a mandatory built-in intake grill, then 10 gated stages (docs, brainstorm+decompose, spec, plan, subagent build, tests, lint/deploy, post-deploy, docs/wiki, acceptance). Every stage's doctrine is built into the skill — no companion plugin required — with typed auto/manual gates, a frozen requirement spine that closes with evidence, a work board and a verification ledger that outlive a run, an exposure line naming what shipped unconfirmed, a progress rail computed from the project's own config, a loop guard whose review ceiling measures rather than stops, and stage-3 tracks for what a product does, how it sounds and how it looks. Two modes need no task: `checkup` (what is unverified) and `setup` (audit existing docs). Retro insights can publish upstream as issues, opt-in and redacted.",
|
|
5
|
-
"version": "1.
|
|
5
|
+
"version": "1.46.0",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "ssheleg",
|
|
8
8
|
"url": "https://x.com/sshlg93"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: evidence-docs
|
|
3
|
-
description:
|
|
3
|
+
description: "Use when writing or reviewing anything that will be read as true — a decision record, a README, an acceptance report, a runbook, a changelog entry, an audit finding, or any claim that something was verified. Applies the ten canons of evidence-backed documentation — what makes a claim documentation rather than an assertion — and routes to the doctrine that enforces each one. Also use when a project needs a documentation gate, a decision register, a propagation matrix, or a retrospective that outlives its author. Triggers - 'documentation gate', 'decision record', 'ADR', 'acceptance report', 'runbook', 'is this verified', 'доказательная документация', 'записать решение', 'отчёт о приёмке', 'раннбук', 'чем это подтверждено', 'доки в синхроне'. Not for: drafts, chat answers, commit messages or code comments — say 'без доков' to opt out."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Evidence-backed documentation
|
|
@@ -67,6 +67,7 @@ gate stops until it is installed.
|
|
|
67
67
|
| **first run · the entry audit** (offered once) | `references/setup.md` |
|
|
68
68
|
| **what travels with the bundle vs stays in a project** | `references/portability.md` |
|
|
69
69
|
| any repeating loop | `references/loop-guard.md` |
|
|
70
|
+
| run-wide · what the run **leaves running and leaves behind** — every gate, and stage 10 | `references/residue.md` |
|
|
70
71
|
| run-wide · what the run **prints about itself** — the rail, the iteration line | `references/progress.md` |
|
|
71
72
|
| run-wide · how a run keeps going (the loop mode + the context budget) | `references/continuity.md` |
|
|
72
73
|
| run-wide · the work-list **between** runs, and how its priority is computed | `references/backlog.md` |
|
|
@@ -248,7 +249,12 @@ Three things the grill does beyond clarifying the request:
|
|
|
248
249
|
owns the conflict, re-plan the check as an ordered list, then go through it one
|
|
249
250
|
item at a time; **when a pass is *searching* rather than editing and starts
|
|
250
251
|
finding mostly what the previous pass's own fixes broke, the axis is exhausted —
|
|
251
|
-
rotate it, don't look harder** (`references/audit.md`)
|
|
252
|
+
rotate it, don't look harder** (`references/audit.md`); **every gate
|
|
253
|
+
prints `holds: N` — what this run left running** across the eight classes
|
|
254
|
+
(background shells, monitors, scheduled loops, coordination leases, worktrees,
|
|
255
|
+
containers, scratch files, remote state), enumerated **by class and never by a
|
|
256
|
+
single tool**, and stage 10 does not close while this run's residue is live and
|
|
257
|
+
unaccounted (`references/residue.md`); and remember that a
|
|
252
258
|
green from a check nobody has watched fail is not evidence; task
|
|
253
259
|
tracker + conventional commits per host conventions; worktree isolation for the
|
|
254
260
|
build, integrated back per the brief's branch policy before stage 7; honest
|
|
@@ -277,7 +283,7 @@ capable available — see `references/model-tiering.md`).
|
|
|
277
283
|
| 7 | Lint + deploy | lint clean + suite green before deploy; deploy needs a go (or the brief's specific standing authorization) | manual |
|
|
278
284
|
| 8 | Post-deploy | clean boot or honest degradation report; **a deployed web target is opened, not curled** — a `200` proves the server answered and says nothing about a 404'd bundle or a console full of errors on load (`chrome-devtools`; absent → call it an HTTP response, which is its honest name) | auto |
|
|
279
285
|
| 9 | Docs + wiki | every stale row of the stage-0 source ledger updated; **the propagation matrix walked for every change type this run produced** — the ledger names what you read, the matrix names what you owe — every settled thing recorded with an id, every answered question resolved, and **the documentation gate green with its ratchet counts printed**; docs synced; wiki synced; **the code graph refreshed where one exists** and checked against the docs (a hub no doc names, a doc naming a node the graph lost); **every number computed rather than restated, every named command or file resolvable** ([`references/learned.md`](references/learned.md)); the carry-over count printed beside the verdict | auto |
|
|
280
|
-
| 10 | **Acceptance** | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); **the hand-back is written** — the request quoted as given, progress against it, what was solved, what surfaced unasked, waiting decisions asked here, and the ambiguity count computed ([`references/progress.md`](references/progress.md)); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **
|
|
286
|
+
| 10 | **Acceptance** | ladder walk ran, its absences became REQ rows; every REQ accounted for with evidence from a check seen failing once; ledger has no unresolved row; **axis rotation recorded** (new findings vs self-inflicted, rule 1 of [`references/learned.md`](references/learned.md)), **every closure verified against the artefact rather than the document describing it**, **each correction swept across its class**, **every deferral a printed ratchet rather than a TODO**; **in a multi-repository project, every repository is clean, pushed and pointed at** (below); **the hand-back is written** — the request quoted as given, progress against it, what was solved, what surfaced unasked, waiting decisions asked here, and the ambiguity count computed ([`references/progress.md`](references/progress.md)); **the environment is given back** — all eight classes enumerated, what this run started ended and verified by re-enumerating rather than by the teardown's reply, an earlier run of this project ended only when **provably spent**, anything this project does not own reported rather than ended, written as a `holds:` line (`references/residue.md`); operator signs off; **every check this close-out leans on — the documentation gate included — has been seen failing once against a planted defect, and its ratchet counts are printed beside the verdict**; **the retrospective written last, and in order — the run stamped with its commit FIRST (the cold-retirement trigger reads that stamp), then the prune with the list at or under its cap and every deletion logged, then the entry; every deletion and every entry carrying its commit, entries older than five stamps rotated into the archive, counts printed** ; **every disclosure printed beside the verdict** — `abstained` (what the run declined to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither with a floor, neither ever a target ([`references/gates.md`](references/gates.md) → *Disclosures*) | manual |
|
|
281
287
|
|
|
282
288
|
|
|
283
289
|
### Stage 10 in a project of several repositories
|
|
@@ -201,6 +201,7 @@ ledger's, so a list that quietly grew back is visible at the moment it happened:
|
|
|
201
201
|
GATE 10 acceptance: PASS — 14/14 REQ verified
|
|
202
202
|
carry-over: 0 unresolved · retro: 7 standing (was 9) · retired 3 · added 1
|
|
203
203
|
abstained: 2 (1 partial · 1 cannot-verify) · unlooked: 3 dormant
|
|
204
|
+
holds: 10 — none — enumerated 8/8 classes
|
|
204
205
|
```
|
|
205
206
|
|
|
206
207
|
## A `verified by` name is a claim until it resolves
|
|
@@ -280,7 +281,7 @@ All of:
|
|
|
280
281
|
ledger or here) and, for `deferred`, a tracker entry.
|
|
281
282
|
8. **No carry-over row is left `unresolved`** — every one has a home, and the
|
|
282
283
|
ledger's counts are printed with this verdict, not just filed.
|
|
283
|
-
7a. **
|
|
284
|
+
7a. **Every disclosure is printed** ([`gates.md`](gates.md) → *Disclosures*):
|
|
284
285
|
`abstained` — every REQ closing `partial`, every `unknown`, every ⚠️ *cannot verify
|
|
285
286
|
from diff* the controller could not resolve — and `unlooked`, every check that
|
|
286
287
|
reported `dormant` or `skip`. They are **not** ratchets: no floor, no direction, and
|
|
@@ -310,6 +311,15 @@ table substitute for that answer.
|
|
|
310
311
|
its four registers with their ids. A run that cannot say what happened has not
|
|
311
312
|
finished; it has stopped. This file is the one stage 10 opens, and it carried every
|
|
312
313
|
other criterion while omitting this one for a release.
|
|
314
|
+
13. **The run has given the environment back** ([`residue.md`](residue.md)) — all
|
|
315
|
+
eight classes enumerated **by class, never by one tool**, everything this run
|
|
316
|
+
started ended in dependency order, each teardown verified by **re-enumerating
|
|
317
|
+
rather than by the teardown's own reply**, and the result written as a `holds:`
|
|
318
|
+
line. `holds:` reaching zero is required here and **only** here. An item left
|
|
319
|
+
standing on purpose passes with its owner and reason named; an item **this project
|
|
320
|
+
does not own** is **reported, never ended** — the inventory is machine-wide and
|
|
321
|
+
the authority is not. An earlier run of *this* project is a third case, ended only
|
|
322
|
+
when provably spent ([`residue.md`](residue.md) → *Three owners*).
|
|
313
323
|
|
|
314
324
|
|
|
315
325
|
## When the answer is "something's missing"
|
|
@@ -35,6 +35,7 @@ elsewhere and is not restated here:
|
|
|
35
35
|
- A green probe is evidence only if the mutation is known to have landed
|
|
36
36
|
- The false-positive budget
|
|
37
37
|
- Ratchets
|
|
38
|
+
- The result is the goal; the check is how you know
|
|
38
39
|
- Disclosures — counted like a ratchet, and deliberately not monotone
|
|
39
40
|
- Where a gate runs
|
|
40
41
|
- Adding a check to an existing gate
|
|
@@ -451,6 +452,49 @@ GATE 9 docs: PASS — propagation backlog: 121 (was 162) · unmarked residue: 0
|
|
|
451
452
|
|
|
452
453
|
A ratchet nobody prints is a TODO with a better name.
|
|
453
454
|
|
|
455
|
+
## The result is the goal; the check is how you know
|
|
456
|
+
|
|
457
|
+
Everything else in this file pushes one way: prove more, assume less. Read alone it
|
|
458
|
+
has an obvious failure mode — a run that spends its afternoon proving a
|
|
459
|
+
one-character change and never ships the thing it was asked for. **The deliverable
|
|
460
|
+
is the working result, as described in the brief. A check is how the run knows it
|
|
461
|
+
has one. A check that is not buying that knowledge is not diligence; it is the run
|
|
462
|
+
optimising the wrong thing.**
|
|
463
|
+
|
|
464
|
+
**Scale the check to what breaking costs, and the project already computes that.**
|
|
465
|
+
The board ranks by `sev × blast` ([`backlog.md`](backlog.md)). The same two inputs
|
|
466
|
+
size the verification:
|
|
467
|
+
|
|
468
|
+
| What breaking costs | What the check has to be |
|
|
469
|
+
|---|---|
|
|
470
|
+
| an outward, irreversible or shared-state effect — deploy, publish, a lease, another agent's file | proven: watched failing against a planted defect, and re-read rather than trusted from the reply |
|
|
471
|
+
| a contract other code depends on | an executed test, named in the REQ row |
|
|
472
|
+
| behaviour a person will see | observed on the surface — a browser, the actual output — not inferred from a diff |
|
|
473
|
+
| a typo, a comment, a rename the compiler checks | the compiler, the suite already running, and nothing more |
|
|
474
|
+
|
|
475
|
+
**Four things that mean you have crossed over**, and each has cost this project a
|
|
476
|
+
run:
|
|
477
|
+
|
|
478
|
+
- **A third pass over the same axis finds mostly what the last pass's fixes broke.**
|
|
479
|
+
The axis is exhausted — rotate it or stop ([`audit.md`](audit.md)).
|
|
480
|
+
- **The check is being widened after it went green**, with no failure in hand. A
|
|
481
|
+
check widened by imagination is a check whose scope nobody has measured.
|
|
482
|
+
- **The evidence is being gathered for a claim nobody made.** If no REQ row and no
|
|
483
|
+
gate criterion asks for it, it is not evidence — it is browsing.
|
|
484
|
+
- **The run is on its second measurement of the same number.** One measurement plus
|
|
485
|
+
what it does not cover, stated, beats two measurements and no decision.
|
|
486
|
+
|
|
487
|
+
**This never licenses skipping a gate.** The gates are the floor, and the floor is
|
|
488
|
+
not proportionate to anything — a `manual` gate waits, `unknown` fails stage 10, and
|
|
489
|
+
a green nobody watched fail is not evidence at any blast radius. What is
|
|
490
|
+
proportionate is the work *above* the floor: how many axes, how many passes, how
|
|
491
|
+
much of the corpus. Cutting the floor to go faster is not speed; it is the failure
|
|
492
|
+
this whole file exists to prevent, arriving on schedule.
|
|
493
|
+
|
|
494
|
+
**Where it is recorded.** Stages 3 and 4 carry a `Cost:` line —
|
|
495
|
+
`<surfaces>/<guards>/<REQ> now, <…> at stage 2 — <proportionate | grown, and why>`.
|
|
496
|
+
*Grown, and why* is the honest answer often enough that it is written into the form.
|
|
497
|
+
|
|
454
498
|
## Disclosures — counted like a ratchet, and deliberately not monotone
|
|
455
499
|
|
|
456
500
|
A ratchet may only shrink. **Some numbers must not be**, and printing them under a
|
|
@@ -471,12 +515,13 @@ column and it reappears in the other, silently, because a wrong claim looks like
|
|
|
471
515
|
So a **disclosure** is printed beside the verdict like a ratchet and carries the opposite
|
|
472
516
|
rule: **no floor, no direction, and a movement in either direction wants one sentence.**
|
|
473
517
|
|
|
474
|
-
|
|
518
|
+
The disclosures below are kept separate because they are different facts — the list is the count:
|
|
475
519
|
|
|
476
520
|
| Disclosure | Counts | Reading it |
|
|
477
521
|
|---|---|---|
|
|
478
522
|
| `abstained: N` | claims the run **declined to make** — `partial`, `unknown`, `cannot verify from diff` | a *choice*. Rising can mean the work got harder or the run got honest; falling can mean either the reverse |
|
|
479
523
|
| `unlooked: N` | checks that **did not look** — `dormant`, `skip` | a *state of the corpus*, not a decision. It falls as the project grows the inputs those checks need |
|
|
524
|
+
| `holds: N` | what the run left **running or lying about** — the eight classes in `references/residue.md` | a *state of the environment*, not of the corpus or of the run's claims. A legitimate 2 during a build beats a manufactured 0; only stage 10 requires it to reach zero or name an owner per item |
|
|
480
525
|
|
|
481
526
|
Three are deliberately **not** counted, and saying which is part of the disclosure:
|
|
482
527
|
|
|
@@ -53,6 +53,7 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
53
53
|
| The ladder, seams, axis rotation, ratchets | `references/audit.md` |
|
|
54
54
|
| Loop detection and its caps | `references/loop-guard.md` |
|
|
55
55
|
| **What the run prints about itself** — the header block, the rail, the iteration line | `references/progress.md` |
|
|
56
|
+
| **What the run leaves running and leaves behind** — the eight classes, the `holds:` field, the teardown | `references/residue.md` |
|
|
56
57
|
| **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
|
|
57
58
|
| **The context budget** — the evidence rule and what a flush actually updates | `references/continuity.md` |
|
|
58
59
|
| **The board** — the work-list between runs, its computed priority, and the ledger seam it resolves | `references/backlog.md` |
|
|
@@ -26,8 +26,10 @@ maintains them and the next run reads them as current.
|
|
|
26
26
|
- The rail is computed, never eleven
|
|
27
27
|
- What each glyph means
|
|
28
28
|
- The hand-back — what the operator reads when you stop
|
|
29
|
+
- "Done" is a claim, and it names what makes it true
|
|
29
30
|
- Every number is borrowed
|
|
30
31
|
- Absent is a word, never a zero
|
|
32
|
+
- The `holds:` line — what the run is still holding
|
|
31
33
|
- The run ledger this reads from
|
|
32
34
|
- Rationalizations
|
|
33
35
|
|
|
@@ -215,6 +217,38 @@ nothing was unclear. Where a project keeps no open-questions register, that row
|
|
|
215
217
|
`— no register` rather than `0`: an absent register and an empty one are different facts,
|
|
216
218
|
and the second is the one worth acting on.
|
|
217
219
|
|
|
220
|
+
## "Done" is a claim, and it names what makes it true
|
|
221
|
+
|
|
222
|
+
Every disclosure in this bundle answers *what does it print when it did not look?*
|
|
223
|
+
That question is asked of **checks**. It has to be asked of the run's own sentences
|
|
224
|
+
too, because the sentence reaches the operator and the check does not.
|
|
225
|
+
|
|
226
|
+
**A completion claim names what makes it true, or it is not a completion claim.**
|
|
227
|
+
`done: the export writes UTF-8` is a claim. `done: the export writes UTF-8 —
|
|
228
|
+
`test_export_encoding` green at 5f21ac3` is a report. The difference is not
|
|
229
|
+
politeness; it is whether anyone can disagree with you.
|
|
230
|
+
|
|
231
|
+
Three ways a run reports something it did not do, none of them requiring an
|
|
232
|
+
intention to mislead:
|
|
233
|
+
|
|
234
|
+
| The shape | What was actually true | What to write instead |
|
|
235
|
+
|---|---|---|
|
|
236
|
+
| **The plan reported as the outcome** — "added the retry" after writing the code and before running anything | the edit landed | `done` names the executed test, or the item is not `done` |
|
|
237
|
+
| **The reply reported as the result** — a deploy, a teardown, a cancel, an API call that returned success | the call was accepted | re-read the state; the second look is the evidence, the reply is not |
|
|
238
|
+
| **The part reported as the whole** — "tests pass" after running the file you touched | that file's tests pass | say which suite, or run the full one |
|
|
239
|
+
|
|
240
|
+
**And the honest negative is a result.** *"Not done — the fixture needs a
|
|
241
|
+
credential I do not have"* is a complete, useful report. *"Done (with a small
|
|
242
|
+
caveat)"* for the same situation is not. A run that cannot finish something says
|
|
243
|
+
so at the boundary it reached, names what would unblock it, and moves to the next
|
|
244
|
+
item — `deferred` and `partial` exist as statuses precisely so that stopping does
|
|
245
|
+
not have to be dressed up as finishing.
|
|
246
|
+
|
|
247
|
+
**The status vocabulary is closed for the same reason.** Stage 10 takes
|
|
248
|
+
`verified`, `partial`, `deferred`, `dropped` — and `unknown` fails the gate
|
|
249
|
+
([`acceptance.md`](acceptance.md)). A fifth word invented at write-time is how a
|
|
250
|
+
run reports a state nobody agreed to read.
|
|
251
|
+
|
|
218
252
|
## Every number is borrowed
|
|
219
253
|
|
|
220
254
|
| Field | Its home |
|
|
@@ -250,6 +284,33 @@ is unconfirmed*, which is the opposite claim, and it is the same inversion
|
|
|
250
284
|
`carry-over 0 rows` **is** a real zero and prints as one: the ledger exists and holds
|
|
251
285
|
nothing.
|
|
252
286
|
|
|
287
|
+
## The `holds:` line — what the run is still holding
|
|
288
|
+
|
|
289
|
+
Beside every gate verdict the run prints `holds: N` — the environment it has not
|
|
290
|
+
given back. It lands in the ledger as a `holds:` line
|
|
291
|
+
([`../templates/run.md`](../templates/run.md)), one per gate that found anything,
|
|
292
|
+
and one at stage 10 whatever the count.
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
holds: 5 — 2 (worktree: build-csv-export, this run; container: pg-test, this run) — enumerated 8/8 classes
|
|
296
|
+
holds: 10 — none — enumerated 7/8 classes, unlooked: containers (no docker on this host)
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Three things make the line worth writing rather than a habit:
|
|
300
|
+
|
|
301
|
+
- **It names the class and the owner, not just a number.** *"2"* tells the next
|
|
302
|
+
run nothing; *"worktree, this run"* tells it what to end and what to leave.
|
|
303
|
+
- **It records how many classes were enumerated.** `8/8` and `7/8, unlooked:
|
|
304
|
+
containers` are different facts, and a run without container tooling must print
|
|
305
|
+
the second rather than a clean zero it did not earn.
|
|
306
|
+
- **It is a disclosure, never a ratchet.** No floor, no direction, no target. A
|
|
307
|
+
build stage legitimately holding a worktree and a database prints `2` and
|
|
308
|
+
passes; a run that tears its database down to make the number tidy and brings
|
|
309
|
+
it back up next stage has spent time making a measurement lie.
|
|
310
|
+
|
|
311
|
+
Doctrine, including the eight classes and what must **not** be torn down:
|
|
312
|
+
[`residue.md`](residue.md).
|
|
313
|
+
|
|
253
314
|
## The run ledger this reads from
|
|
254
315
|
|
|
255
316
|
`.task-pipeline/run.md`, seeded at stage 0 from
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
# Residue — what a run leaves running, and what it leaves behind
|
|
2
|
+
|
|
3
|
+
A run does not only produce a diff. It starts background processes, arms
|
|
4
|
+
monitors, schedules wake-ups, takes leases, creates worktrees, brings up
|
|
5
|
+
containers and writes scratch files. Every one of those outlives the stage that
|
|
6
|
+
created it unless something ends it.
|
|
7
|
+
|
|
8
|
+
**Two shapes, one class.** *Residue in flight* is what is still running while the
|
|
9
|
+
run continues — it corrupts the work, because a stale monitor fires into a run
|
|
10
|
+
that has moved on and a lease held by a finished stage blocks the next one.
|
|
11
|
+
*Residue at rest* is what is still there when the run ends — it corrupts the next
|
|
12
|
+
run, which inherits a dirty environment it did not create and cannot explain.
|
|
13
|
+
|
|
14
|
+
Both are checked the same way and this file covers both.
|
|
15
|
+
|
|
16
|
+
## Contents
|
|
17
|
+
|
|
18
|
+
- The measured reason this file exists
|
|
19
|
+
- The inventory — eight classes
|
|
20
|
+
- Where the check fires: every gate
|
|
21
|
+
- The teardown, at the end of the run
|
|
22
|
+
- What must **not** be torn down
|
|
23
|
+
- Three owners, not two — and the third is where cleanup actually happens
|
|
24
|
+
- Rationalizations
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## The measured reason this file exists
|
|
29
|
+
|
|
30
|
+
On 2026-08-11, mid-run, a monitor was armed to watch CI. One minute later the
|
|
31
|
+
harness task inventory was queried:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
TaskList → "No tasks found"
|
|
35
|
+
ps -eo pid,etime,cmd → 52693 03:12 /bin/zsh -c … gh pr checks …
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The monitor was **alive and polling**, and the inventory tool reported nothing.
|
|
39
|
+
|
|
40
|
+
This is the class this whole doctrine exists to catch: **a check answered by
|
|
41
|
+
something that is not its subject.** An inventory that does not enumerate the
|
|
42
|
+
thing that leaks is not an inventory — it is a green light with no lamp behind
|
|
43
|
+
it. A residue check that calls one tool and trusts its silence will report clean
|
|
44
|
+
over a process that is still making network calls.
|
|
45
|
+
|
|
46
|
+
**So: enumerate by class, never by tool.** Each class below names its own
|
|
47
|
+
enumeration. Silence from one tool is evidence about that tool, not about the
|
|
48
|
+
environment.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## The inventory — eight classes
|
|
53
|
+
|
|
54
|
+
Run the enumeration for every class that the run could have created. A class the
|
|
55
|
+
run provably never touched is skipped **by name**, not by omission.
|
|
56
|
+
|
|
57
|
+
| Class | What leaks | How to enumerate |
|
|
58
|
+
|---|---|---|
|
|
59
|
+
| **Background shells** | a task started detached and never exited | the harness's background-task list **and** `ps -eo pid,ppid,etime,command` filtered to this session's shell |
|
|
60
|
+
| **Monitors / watchers** | a poll loop still hitting a remote API | `ps` for the poll command; the harness list may not contain it — see above |
|
|
61
|
+
| **Scheduled wake-ups / loops** | a loop that fires into a finished run | the harness's schedule list; a dynamic loop ends by an explicit stop, never by falling silent |
|
|
62
|
+
| **Coordination leases** | a lease held on a shared register blocks every other agent | `agent-sync status` where `.claude/agent-sync.json` exists |
|
|
63
|
+
| **Worktrees / branches** | an isolated build workspace, and the branch under it | `git worktree list`, `git branch --merged` |
|
|
64
|
+
| **Containers / services** | a database or app brought up for a test | `docker ps`, `docker compose ls`, plus whatever the project's own runbook started |
|
|
65
|
+
| **Scratch files** | temp output, planted-defect copies, generated fixtures | `git status --porcelain` for the tree; the scratch directory for the rest |
|
|
66
|
+
| **Remote state** | a draft PR, a test tag, an uploaded artifact, a feature flag flipped for a check | the tracker and forge; the deploy target's own listing |
|
|
67
|
+
|
|
68
|
+
Two of these bite hardest and are worth naming separately.
|
|
69
|
+
|
|
70
|
+
**A lease is the one that blocks someone else.** Every other class costs this run
|
|
71
|
+
or the next one. A held lease costs a *different agent*, right now, and it looks
|
|
72
|
+
to them like the register is permanently unavailable rather than briefly held.
|
|
73
|
+
Release it at the stage that took it — not at the end.
|
|
74
|
+
|
|
75
|
+
**A container is the one that is invisible and expensive.** Nothing in the diff
|
|
76
|
+
mentions it, no test fails because of it, and it will still be running tomorrow.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Where the check fires: every gate
|
|
81
|
+
|
|
82
|
+
**The residue check is a criterion of every gate, not a stage of its own.** A
|
|
83
|
+
cleanup stage at the end is the design that fails, because the damage from
|
|
84
|
+
residue in flight has already happened by the time the end arrives.
|
|
85
|
+
|
|
86
|
+
Every gate verdict carries the count, in the same line as the rest:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
GATE 5 build: PASS — reviews 3 · findings 0 open · holds: 2 (worktree, container)
|
|
90
|
+
abstained: 0 · unlooked: 0
|
|
91
|
+
GATE 6 tests: PASS — suite green · holds: 1 (container: pg-test, this run)
|
|
92
|
+
abstained: 0 · unlooked: 0
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Read the line the way the other disclosures on it are read:
|
|
96
|
+
|
|
97
|
+
- **`holds: 0`** — every class enumerated, nothing found.
|
|
98
|
+
- **`holds: N (…)`** — N things are live, each named. This is a **disclosure,
|
|
99
|
+
not a failure**. A build stage that legitimately holds a worktree and a database
|
|
100
|
+
reports `holds: 2` and passes; the count exists so nobody has to remember.
|
|
101
|
+
- **`holds: unlooked (…)`** — a class could not be enumerated, named. A run
|
|
102
|
+
without container tooling says so rather than printing `0`.
|
|
103
|
+
|
|
104
|
+
**Why the field is `holds:` and not `residue:`.** `gates.md` already prints
|
|
105
|
+
`unmarked residue: 0` for a different thing — documentation items left unmarked
|
|
106
|
+
— and `residue: 0` is a substring of it. A check written for this field would
|
|
107
|
+
have been answered by that line. The word stays in the prose because it is the
|
|
108
|
+
right word; the **field** is `holds:`, which is free and joins `stage:`,
|
|
109
|
+
`iter:`, `hand:` and `touch:` in the run ledger.
|
|
110
|
+
|
|
111
|
+
**Its sibling, one file over.** `tdd.md`'s *The green from residue* is the same
|
|
112
|
+
class on the test axis — state left over from an earlier run making a case pass
|
|
113
|
+
that would fail fresh. That rule is about residue **faking a result**; this one
|
|
114
|
+
is about residue **outliving the run**. Neither overrides the other.
|
|
115
|
+
|
|
116
|
+
**`holds: 0` is never a target.** A run that tears down its database to make a
|
|
117
|
+
number look tidy, and then brings it back up next stage, has spent time to make a
|
|
118
|
+
measurement lie. The number describes; it does not instruct.
|
|
119
|
+
|
|
120
|
+
**Only stage 10 requires the count to reach zero** — or every remaining item to
|
|
121
|
+
carry a named owner and a reason, in writing.
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## The teardown, at the end of the run
|
|
126
|
+
|
|
127
|
+
Stage 10 does not close while this run's residue is live. Walk the inventory once
|
|
128
|
+
more, and for each item either end it or account for it:
|
|
129
|
+
|
|
130
|
+
1. **Enumerate every class.** Not the ones you remember using — all eight, because
|
|
131
|
+
the one you forgot is the one still running.
|
|
132
|
+
2. **End what this run started**, in dependency order: remote state first (a draft
|
|
133
|
+
PR or a flipped flag is visible to other people), then services, then
|
|
134
|
+
worktrees, then leases, then scratch files.
|
|
135
|
+
3. **Verify each teardown by re-reading, not by the reply.** A cancel, delete or
|
|
136
|
+
teardown call will happily accept an id that was never scheduled and return
|
|
137
|
+
success. Enumerate again after tearing down; the second enumeration is the
|
|
138
|
+
evidence, the first reply is not.
|
|
139
|
+
4. **Write what remains into the run ledger**, with its owner:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
holds: 10 — none — enumerated 8/8 classes
|
|
143
|
+
holds: 10 — 1 (container: pg-test, operator asked for it to stay) — enumerated 8/8 classes
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
An item left standing on purpose is fine. An item left standing silently is how
|
|
147
|
+
the next run starts against a database somebody else's test seeded.
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## What must **not** be torn down
|
|
152
|
+
|
|
153
|
+
**Tear down what this run started. Report what it did not.**
|
|
154
|
+
|
|
155
|
+
The inventory is machine-wide; the authority is not. Another session's monitor,
|
|
156
|
+
another agent's lease, a container that was up before this run began — killing
|
|
157
|
+
any of those is a run reaching outside its own boundary to make its own number
|
|
158
|
+
look better, and it will break work that is going fine.
|
|
159
|
+
|
|
160
|
+
- **If the run did not start it, it does not end it.** Name it in the ledger as
|
|
161
|
+
*foreign*, with whatever identifies its owner.
|
|
162
|
+
- **A lease held by another agent is never released by this run**, no matter how
|
|
163
|
+
stale it looks. Stale is a judgment; the holder is a fact.
|
|
164
|
+
- **Ambiguous ownership is reported, not resolved.** A worktree with no obvious
|
|
165
|
+
creator is `holds: 1 (worktree, owner unknown)` — which is honest — rather
|
|
166
|
+
than deleted, which is irreversible.
|
|
167
|
+
|
|
168
|
+
The asymmetry is deliberate: leaving something running costs a little, and killing
|
|
169
|
+
something someone else owns costs a lot.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Three owners, not two — and the third is where cleanup actually happens
|
|
174
|
+
|
|
175
|
+
The rule above splits the world in two: what this run started, and what it did not.
|
|
176
|
+
**Dry-running this doctrine on its own project found the state it has no slot for.**
|
|
177
|
+
|
|
178
|
+
Measured 2026-08-11, enumerating the eight classes on a live run:
|
|
179
|
+
|
|
180
|
+
```
|
|
181
|
+
worktrees/branches : 3 feature branches, all merged into main, from earlier runs
|
|
182
|
+
containers : 18 running, none started by this run, oldest 3 days,
|
|
183
|
+
across four unrelated projects
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The branches are not this run's, so *end what you started* does not reach them. They
|
|
187
|
+
are not foreign either — the project owns them, and reporting them every run forever
|
|
188
|
+
is how a report becomes wallpaper. So:
|
|
189
|
+
|
|
190
|
+
| Owner | What to do | Why |
|
|
191
|
+
|---|---|---|
|
|
192
|
+
| **this run** | end it, in dependency order | it exists because of work that is now finished |
|
|
193
|
+
| **an earlier run of this project** | end it **when it is provably spent**, and say you did — a branch merged into the default branch, a worktree with no diff, a scratch file from a completed run. Otherwise report it | this is the accumulation nobody is otherwise responsible for, and *provably spent* is a fact rather than a judgement |
|
|
194
|
+
| **anything else** | **report, never end** | see the section above; the asymmetry is not negotiable |
|
|
195
|
+
|
|
196
|
+
**"Provably spent" is the whole load-bearing phrase.** A branch merged into the
|
|
197
|
+
default branch is spent — `git merge-base --is-ancestor` says so, and nothing is lost
|
|
198
|
+
by removing it. A branch that merely *looks* abandoned is not spent, and the run that
|
|
199
|
+
deletes it is guessing about someone's work in progress. **If the proof needs a
|
|
200
|
+
judgement, the item is reported, not ended** — which puts it back under the rule
|
|
201
|
+
above rather than creating an exception to it.
|
|
202
|
+
|
|
203
|
+
**A foreign item never becomes spent.** The 18 containers above belong to other
|
|
204
|
+
projects; that they have been up for three days is information for whoever owns them,
|
|
205
|
+
not permission. The third owner state widens what a run may clean **inside its own
|
|
206
|
+
project** and widens nothing at all outside it.
|
|
207
|
+
|
|
208
|
+
## Rationalizations
|
|
209
|
+
|
|
210
|
+
| The excuse | What it actually means |
|
|
211
|
+
|---|---|
|
|
212
|
+
| "The task list is empty, so nothing is running." | The measured case above: the list was empty and the process was polling. Silence from one tool is evidence about that tool. |
|
|
213
|
+
| "It will exit on its own." | Some do. The ones that leak are exactly the ones that do not, and you cannot tell which is which without enumerating. |
|
|
214
|
+
| "I will clean up at the end." | Residue in flight has already corrupted the run by then. That is why this is a gate criterion, not a final stage. |
|
|
215
|
+
| "The container is tiny." | Its cost is not its size. It is invisible, it holds state, and it will still be there tomorrow. |
|
|
216
|
+
| "I did not start any background work this stage." | Then the enumeration takes ten seconds and prints `holds: 0`. The cheap case is not the reason to skip the check. |
|
|
217
|
+
| "The lease is obviously stale." | Stale is your judgment about someone else's work. Report it; do not release it. |
|
|
218
|
+
| "Tearing it down returned success." | So does tearing down an id that never existed. Verify by re-enumerating. |
|
|
219
|
+
| "`holds: 0` looks better in the ledger." | Then the number has become a target and has stopped being a measurement. A legitimate 2 is worth more than a manufactured 0. |
|
|
@@ -41,6 +41,7 @@ file exists to stop.
|
|
|
41
41
|
- The loop closes at stage 0
|
|
42
42
|
- Where a lesson goes when it is not about this project
|
|
43
43
|
- Publishing the insight — the skill learns from every project that runs it
|
|
44
|
+
- The improvement iteration — what happens to a published insight next
|
|
44
45
|
- What may leave the project — the redaction list
|
|
45
46
|
- Rationalizations
|
|
46
47
|
|
|
@@ -265,6 +266,7 @@ does ([`audit.md`](audit.md) → *What can't be fixed now becomes a ratchet, nev
|
|
|
265
266
|
GATE 10 acceptance: PASS — 14/14 REQ verified
|
|
266
267
|
carry-over: 0 unresolved · retro: 7 standing (was 9) · retired 3 · added 1
|
|
267
268
|
abstained: 2 · unlooked: 3
|
|
269
|
+
holds: 10 — none — enumerated 8/8 classes
|
|
268
270
|
```
|
|
269
271
|
|
|
270
272
|
A pruned list that nobody prints is a list that quietly grows back.
|
|
@@ -340,6 +342,49 @@ opening… → #24
|
|
|
340
342
|
opened, and carry the exact text in the carry-over ledger. That is the honest
|
|
341
343
|
degradation; a second transport is not.
|
|
342
344
|
|
|
345
|
+
## The improvement iteration — what happens to a published insight next
|
|
346
|
+
|
|
347
|
+
Publishing is half a loop. An issue that is opened and never triaged is a lesson
|
|
348
|
+
that cost a run and bought nothing, and a tracker full of those teaches everyone
|
|
349
|
+
that publishing is where findings go to be filed.
|
|
350
|
+
|
|
351
|
+
**The loop, and every arrow in it is somebody's obligation:**
|
|
352
|
+
|
|
353
|
+
```
|
|
354
|
+
a run diverges → a retro entry → retro.publish → an issue on the skill
|
|
355
|
+
↓
|
|
356
|
+
a board row ← measured against the tree ← triaged in a later cycle
|
|
357
|
+
↓
|
|
358
|
+
doctrine + the guard that proves it → a release → the next run reads it
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
**Resolve what you worked, let the rest accumulate — visibly.** At the close of a
|
|
362
|
+
cycle that consumed published issues:
|
|
363
|
+
|
|
364
|
+
- **An issue closes when the behaviour changed**, not when the lesson was
|
|
365
|
+
understood (that is R-006, and it applies to issues exactly as it applies to
|
|
366
|
+
findings). The closing comment names **where** it landed — a file and a line —
|
|
367
|
+
and the guard that now holds it. A close with no address is a close nobody can
|
|
368
|
+
audit.
|
|
369
|
+
- **An issue nobody worked stays open.** It is not triaged into silence, not
|
|
370
|
+
relabelled, not closed as stale. The pile is the queue, and its depth is the
|
|
371
|
+
honest measure of how far behind the doctrine is.
|
|
372
|
+
- **Nothing is deleted.** A closed issue keeps its number, and the number is what
|
|
373
|
+
the CHANGELOG and the retro entry point at. Deleting one severs both, and the
|
|
374
|
+
cost lands on whoever next asks *why is this rule here*.
|
|
375
|
+
|
|
376
|
+
**Where the queue comes from at the start of a cycle**, in this order: open issues
|
|
377
|
+
published by any project running this skill, then the board's open rows by computed
|
|
378
|
+
priority, then the open-questions register. A run that finishes its brief early
|
|
379
|
+
takes the top of that list rather than inventing work — and a run that *cannot*
|
|
380
|
+
take it says so, which is a fuller queue rather than a quiet one.
|
|
381
|
+
|
|
382
|
+
**The measurement that keeps this honest.** Print, at the close: issues consumed,
|
|
383
|
+
issues resolved with an address, issues left open. Three numbers, no floor, no
|
|
384
|
+
target, and the third one rising is information rather than a failure — it means
|
|
385
|
+
the projects running this skill are finding more than one cycle can absorb, which
|
|
386
|
+
is what you want them to do.
|
|
387
|
+
|
|
343
388
|
## What may leave the project — the redaction list
|
|
344
389
|
|
|
345
390
|
An issue is a **public artefact in someone else's repository**. What travels is the
|
|
@@ -430,7 +430,7 @@ never that the work was skipped quietly.
|
|
|
430
430
|
is covered; no `skip`/`xfail` smuggling a red suite past the gate. Never advance
|
|
431
431
|
to deploy on a red or partial run. **The carry-over count is printed beside this
|
|
432
432
|
verdict** — a ratchet nobody prints is a TODO with a better name
|
|
433
|
-
([`audit.md`](audit.md)) — **and so are the
|
|
433
|
+
([`audit.md`](audit.md)) — **and so are the disclosures**, `abstained` and
|
|
434
434
|
`unlooked` ([`gates.md`](gates.md) → *Disclosures*): what the run declined to claim,
|
|
435
435
|
and what a check never looked at. Neither has a floor and neither may be targeted; a
|
|
436
436
|
target on an abstention count is an instruction to guess.
|
|
@@ -656,7 +656,12 @@ never that the work was skipped quietly.
|
|
|
656
656
|
surfaced that nobody asked for, every decision still waiting **asked here with
|
|
657
657
|
options rather than listed**, and the ambiguity count computed from the four
|
|
658
658
|
registers with its ids ([`progress.md`](progress.md) → *The hand-back*) — a run
|
|
659
|
-
that cannot say what happened has not finished, it has stopped; **
|
|
659
|
+
that cannot say what happened has not finished, it has stopped; **the environment is
|
|
660
|
+
given back** — all eight classes enumerated, everything this run started ended and
|
|
661
|
+
verified by re-enumerating rather than by the teardown's reply, an earlier run of
|
|
662
|
+
this project ended only when **provably spent**, an item this project does not own
|
|
663
|
+
reported rather than ended, and the result written as a `holds:` line
|
|
664
|
+
([`residue.md`](residue.md)); **every disclosure printed beside the verdict** — `abstained` (what the run declined
|
|
660
665
|
to claim) and `unlooked` (what a check never looked at), neither a ratchet, neither
|
|
661
666
|
with a floor, neither ever a target ([`gates.md`](gates.md) → *Disclosures*); **the
|
|
662
667
|
retrospective is written — stamped first, then pruned, then the entry; the
|
|
@@ -20,6 +20,7 @@ stage: <id> <name> — gate <auto|manual> — verdict <pass|fail|skip> — <ISO-
|
|
|
20
20
|
iter: <N> — item <B-NNN or task id> — closed at gate <stage id>
|
|
21
21
|
touch: <file> — pass <N> (<stage|round|module>) — reason: <finding id / gate item>
|
|
22
22
|
hand: <N|10> — task "<quoted>" — done <n> — surfaced <n> — decisions <n> — amb <n> (<ids or "— no register">)
|
|
23
|
+
holds: <stage id> — <n> (<class: what, owner>; … or "none") — enumerated <n>/8 classes, <unlooked: classes not enumerable>
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
- **`stage:`** — written when a gate **returns**, not when the stage is entered. The
|
|
@@ -53,6 +54,8 @@ touch: src/export.ts — pass 1 (stage 5) — reason: TASK-3
|
|
|
53
54
|
touch: src/export.ts — pass 2 (stage 5) — reason: F-014
|
|
54
55
|
touch: src/export.ts — pass 3 (stage 5) — reason: F-014
|
|
55
56
|
hand: 3 — task "add CSV export to the orders table" — done 2 — surfaced 1 — decisions 1 — amb 2 (OQ-0007, ledger row 4)
|
|
57
|
+
holds: 5 — 2 (worktree: build-csv-export, this run; container: pg-test, this run) — enumerated 8/8 classes
|
|
58
|
+
holds: 10 — none — enumerated 7/8 classes, unlooked: containers (no docker on this host)
|
|
56
59
|
```
|
|
57
60
|
|
|
58
61
|
The last two lines are a **trip**: the same file, two consecutive passes, the same
|