task-pipeline-skill 1.32.0 → 1.37.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 +253 -0
- package/CONTRIBUTING.md +76 -1
- package/README.md +24 -0
- package/SKILL-CARD.md +1 -1
- package/cursor/rules/task-pipeline.mdc +34 -9
- package/package.json +1 -1
- package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
- package/plugins/task-pipeline/commands/task-pipeline.md +11 -0
- package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +133 -21
- package/plugins/task-pipeline/skills/task-pipeline/references/artifacts.md +12 -5
- package/plugins/task-pipeline/skills/task-pipeline/references/companion-skills.md +20 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/continuity.md +18 -1
- package/plugins/task-pipeline/skills/task-pipeline/references/exposure.md +110 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +52 -2
- package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +2 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/progress.md +190 -0
- package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +88 -3
- package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +109 -9
- package/plugins/task-pipeline/skills/task-pipeline/templates/README.md +1 -0
- package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +77 -0
|
@@ -4,18 +4,32 @@
|
|
|
4
4
|
"title": "task-pipeline config",
|
|
5
5
|
"description": "Generic contract for a pipeline config. An ordered list of stages; each stage is run by the host project's own skills/agents and guarded by a typed gate. The framework imposes no specific stages, skills, or gate assignments — those are entirely the host project's config. Copy pipeline.example.json and rewrite it to match your project.",
|
|
6
6
|
"type": "object",
|
|
7
|
-
"required": [
|
|
7
|
+
"required": [
|
|
8
|
+
"stages"
|
|
9
|
+
],
|
|
8
10
|
"additionalProperties": true,
|
|
9
11
|
"properties": {
|
|
10
|
-
"version": {
|
|
12
|
+
"version": {
|
|
13
|
+
"type": "integer",
|
|
14
|
+
"minimum": 1
|
|
15
|
+
},
|
|
11
16
|
"stages": {
|
|
12
17
|
"type": "array",
|
|
13
18
|
"minItems": 1,
|
|
14
19
|
"description": "The pipeline stages, in order. Any number, any names — your project's real stages.",
|
|
15
|
-
"items": {
|
|
20
|
+
"items": {
|
|
21
|
+
"$ref": "#/definitions/stage"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"release": {
|
|
25
|
+
"$ref": "#/definitions/release"
|
|
26
|
+
},
|
|
27
|
+
"run": {
|
|
28
|
+
"$ref": "#/definitions/run"
|
|
16
29
|
},
|
|
17
|
-
"
|
|
18
|
-
|
|
30
|
+
"retro": {
|
|
31
|
+
"$ref": "#/definitions/retro"
|
|
32
|
+
}
|
|
19
33
|
},
|
|
20
34
|
"definitions": {
|
|
21
35
|
"run": {
|
|
@@ -25,12 +39,17 @@
|
|
|
25
39
|
"properties": {
|
|
26
40
|
"loop": {
|
|
27
41
|
"type": "object",
|
|
28
|
-
"required": [
|
|
42
|
+
"required": [
|
|
43
|
+
"mode"
|
|
44
|
+
],
|
|
29
45
|
"additionalProperties": true,
|
|
30
46
|
"description": "Whether the run advances item by item without a discretionary check-in. It NEVER collapses a manual gate or an outward action — a generic flag is not a specific authorization.",
|
|
31
47
|
"properties": {
|
|
32
48
|
"mode": {
|
|
33
|
-
"enum": [
|
|
49
|
+
"enum": [
|
|
50
|
+
"off",
|
|
51
|
+
"interval"
|
|
52
|
+
],
|
|
34
53
|
"description": "off (the default when absent) = the run pauses between items as it always did. interval = the run is armed with the harness's own loop primitive and advances one item per fire, stopping only at a manual gate, an unresolvable block, a genuine ambiguity, or completion."
|
|
35
54
|
},
|
|
36
55
|
"interval": {
|
|
@@ -43,6 +62,18 @@
|
|
|
43
62
|
"description": "How this harness arms it, e.g. '/loop'. Harness-specific and therefore project-recorded rather than assumed: on a harness with no loop primitive, omit it — the mode then degrades to prose discipline plus the build ledger, and the run says so instead of implying it is armed."
|
|
44
63
|
}
|
|
45
64
|
}
|
|
65
|
+
},
|
|
66
|
+
"review": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"additionalProperties": true,
|
|
69
|
+
"description": "The review loop's ceiling. Absent, the default is 3 rounds per artifact. It is a DECISION POINT rather than a stop: at the cap the run prints new findings versus findings caused by its own fixes, per round, and either the pair ends the loop or the operator continues it out loud. A flat stop would be wrong — this repository's ten-round runs were still finding real defects on round nine. Doctrine: references/loop-guard.md.",
|
|
70
|
+
"properties": {
|
|
71
|
+
"maxRounds": {
|
|
72
|
+
"type": "integer",
|
|
73
|
+
"minimum": 1,
|
|
74
|
+
"description": "Rounds per artifact before the run stops reviewing and measures. Counted from the run ledger's `touch:` pass numbers, never from memory; a round that finds nothing ends the loop by definition and is not counted."
|
|
75
|
+
}
|
|
76
|
+
}
|
|
46
77
|
}
|
|
47
78
|
}
|
|
48
79
|
},
|
|
@@ -50,48 +81,129 @@
|
|
|
50
81
|
"type": "object",
|
|
51
82
|
"additionalProperties": true,
|
|
52
83
|
"description": "Optional release automation, entirely project-defined and INDIVIDUALLY TOGGLEABLE. Omit the whole object, or set enabled:false, to turn release automation off for this project. The framework ships an example workflow (.github/workflows/release.yml) whose job is gated on a repo variable so each project arms it on its own; this block is the declarative counterpart the orchestrator reads.",
|
|
53
|
-
"required": [
|
|
84
|
+
"required": [
|
|
85
|
+
"enabled"
|
|
86
|
+
],
|
|
54
87
|
"properties": {
|
|
55
|
-
"enabled": {
|
|
56
|
-
|
|
88
|
+
"enabled": {
|
|
89
|
+
"type": "boolean",
|
|
90
|
+
"description": "Master on/off toggle. false (or the object omitted) = no release automation for this project."
|
|
91
|
+
},
|
|
92
|
+
"trigger": {
|
|
93
|
+
"enum": [
|
|
94
|
+
"tag",
|
|
95
|
+
"manual",
|
|
96
|
+
"push",
|
|
97
|
+
"none"
|
|
98
|
+
],
|
|
99
|
+
"description": "What kicks off a release (e.g. a pushed vX.Y.Z tag, manual dispatch)."
|
|
100
|
+
},
|
|
57
101
|
"steps": {
|
|
58
102
|
"type": "array",
|
|
59
|
-
"items": {
|
|
103
|
+
"items": {
|
|
104
|
+
"type": "string",
|
|
105
|
+
"minLength": 1
|
|
106
|
+
},
|
|
60
107
|
"description": "Ordered release actions, in prose — project-specific (e.g. create a GitHub release, npm publish). Human-only steps (2FA publish) are named as such."
|
|
61
108
|
},
|
|
62
109
|
"verify": {
|
|
63
110
|
"type": "array",
|
|
64
|
-
"items": {
|
|
111
|
+
"items": {
|
|
112
|
+
"type": "string",
|
|
113
|
+
"minLength": 1
|
|
114
|
+
},
|
|
65
115
|
"description": "Post-release smoke checks that must pass after a release — this is the release's own post-deploy gate (stage 8 applied to shipping the package itself)."
|
|
66
116
|
}
|
|
67
117
|
}
|
|
68
118
|
},
|
|
69
119
|
"stage": {
|
|
70
120
|
"type": "object",
|
|
71
|
-
"required": [
|
|
121
|
+
"required": [
|
|
122
|
+
"state",
|
|
123
|
+
"skills",
|
|
124
|
+
"gate"
|
|
125
|
+
],
|
|
72
126
|
"additionalProperties": true,
|
|
73
127
|
"properties": {
|
|
74
|
-
"id": {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
128
|
+
"id": {
|
|
129
|
+
"type": "integer",
|
|
130
|
+
"description": "Optional ordinal."
|
|
131
|
+
},
|
|
132
|
+
"state": {
|
|
133
|
+
"type": "string",
|
|
134
|
+
"minLength": 1,
|
|
135
|
+
"description": "Unique stable key for the stage."
|
|
136
|
+
},
|
|
137
|
+
"name": {
|
|
138
|
+
"type": "string",
|
|
139
|
+
"description": "Optional human label."
|
|
140
|
+
},
|
|
141
|
+
"model": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"description": "Optional model for the stage. Prefer a provider-agnostic token over a vendor id, which goes stale as generations ship and may not exist on the operator's provider at all: 'default' = the model confirmed for this run (recommended: the most capable reasoning model the environment offers), 'inherit' = whatever the operator is currently on. A literal id is allowed but treated as an example, not a contract."
|
|
144
|
+
},
|
|
78
145
|
"skills": {
|
|
79
146
|
"type": "array",
|
|
80
147
|
"minItems": 1,
|
|
81
148
|
"description": "The skill(s)/agent(s) that execute this stage. Any names your environment resolves — this is where you plug in your OWN skills.",
|
|
82
|
-
"items": {
|
|
149
|
+
"items": {
|
|
150
|
+
"type": "string",
|
|
151
|
+
"minLength": 1
|
|
152
|
+
}
|
|
83
153
|
},
|
|
84
154
|
"gate": {
|
|
85
155
|
"type": "object",
|
|
86
|
-
"required": [
|
|
156
|
+
"required": [
|
|
157
|
+
"type",
|
|
158
|
+
"check"
|
|
159
|
+
],
|
|
87
160
|
"additionalProperties": true,
|
|
88
161
|
"description": "Condition that must pass before advancing to the next stage.",
|
|
89
162
|
"properties": {
|
|
90
163
|
"type": {
|
|
91
|
-
"enum": [
|
|
164
|
+
"enum": [
|
|
165
|
+
"auto",
|
|
166
|
+
"manual"
|
|
167
|
+
],
|
|
92
168
|
"description": "auto = the orchestrator verifies `check` itself (pass/fail); manual = wait for the operator's explicit go."
|
|
93
169
|
},
|
|
94
|
-
"check": {
|
|
170
|
+
"check": {
|
|
171
|
+
"type": "string",
|
|
172
|
+
"minLength": 1,
|
|
173
|
+
"description": "The gate condition, in prose."
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"retro": {
|
|
180
|
+
"type": "object",
|
|
181
|
+
"additionalProperties": true,
|
|
182
|
+
"description": "Optional. Governs what the retrospective does BEYOND writing to the project's own docs/superpowers/retro.md, which always happens. Omit it and nothing leaves the repository: silence arms nothing, exactly as it authorises no deploy.",
|
|
183
|
+
"properties": {
|
|
184
|
+
"publish": {
|
|
185
|
+
"type": "object",
|
|
186
|
+
"required": [
|
|
187
|
+
"repo"
|
|
188
|
+
],
|
|
189
|
+
"additionalProperties": true,
|
|
190
|
+
"description": "Publish skill-level insights as issues on the skill's own repository, so a defect in the pipeline is fixed once instead of rediscovered in every project. OFF unless this object is present — opening an issue in another repository is an outward act, and an outward act taken from a generic flag is one nobody authorized. The body is printed in full before it is sent, and the printed string and the sent string are the same string. Doctrine, including the five redaction rules: references/retrospective.md.",
|
|
191
|
+
"properties": {
|
|
192
|
+
"repo": {
|
|
193
|
+
"type": "string",
|
|
194
|
+
"pattern": "^[^/\\s]+/[^/\\s]+$",
|
|
195
|
+
"description": "owner/name of the SKILL's repository, never the host project's."
|
|
196
|
+
},
|
|
197
|
+
"label": {
|
|
198
|
+
"type": "string",
|
|
199
|
+
"description": "Applied to every issue opened this way, so the operator can read them as a stream rather than find them by accident."
|
|
200
|
+
},
|
|
201
|
+
"redact": {
|
|
202
|
+
"enum": [
|
|
203
|
+
"strict"
|
|
204
|
+
],
|
|
205
|
+
"description": "Only 'strict' exists, and it is not a level among others: the five rules are the contract. A field with one legal value is here so a reader asking 'what redaction applies?' finds the answer in the config rather than assuming none does."
|
|
206
|
+
}
|
|
95
207
|
}
|
|
96
208
|
}
|
|
97
209
|
}
|
|
@@ -59,9 +59,15 @@ at a glance.
|
|
|
59
59
|
> external skill**. A host project may relocate the root via its `CLAUDE.md`; keep
|
|
60
60
|
> the shape, keep the slugs.
|
|
61
61
|
|
|
62
|
-
|
|
63
|
-
stage
|
|
64
|
-
|
|
62
|
+
**Every** run keeps a **git-ignored** run ledger at `.task-pipeline/run.md`, seeded at
|
|
63
|
+
stage 0 from [`../templates/run.md`](../templates/run.md). Three line shapes: a
|
|
64
|
+
`stage:` verdict when a gate returns, an `iter:` line when an iteration closes, and a
|
|
65
|
+
`touch:` line per file per repeating pass. Two readers depend on it —
|
|
66
|
+
[`loop-guard.md`](loop-guard.md) detects churn from the `touch:` lines after a lost
|
|
67
|
+
context, and [`progress.md`](progress.md) derives the stage rail and the iteration
|
|
68
|
+
counter from the other two. It was described as loop-only until 2026-08-10 and, in
|
|
69
|
+
practice, written by no run at all: the guard that calls its own detection *mechanical*
|
|
70
|
+
had no input in any run to date.
|
|
65
71
|
|
|
66
72
|
Stage 5 also creates a **git-ignored** scratch workspace per plan at
|
|
67
73
|
`.task-pipeline/build/<plan-basename>/` — ledger, task briefs, implementer reports,
|
|
@@ -158,12 +164,13 @@ plugins/task-pipeline/
|
|
|
158
164
|
acceptance.md retrospective.md # stage 10 (close-out, then the retro)
|
|
159
165
|
audit.md # cross-cutting: the ladder + seams
|
|
160
166
|
loop-guard.md # cross-cutting: churn detection
|
|
167
|
+
progress.md # cross-cutting: what the run prints about itself
|
|
161
168
|
stages.md model-tiering.md # gates, model policy
|
|
162
169
|
conventions.md artifacts.md # host conventions, this layout
|
|
163
170
|
companion-skills.md # optional companions + preflight
|
|
164
171
|
templates/ # skeletons seeded into a host project
|
|
165
|
-
hygiene.sh
|
|
166
|
-
README.md
|
|
172
|
+
hygiene.sh docgate.sh # -> scripts/check-hygiene.sh, check-docs.sh
|
|
173
|
+
README.md # the index — and it is the list, not a copy of it
|
|
167
174
|
cursor/rules/task-pipeline.mdc # Cursor channel (self-contained rule)
|
|
168
175
|
bin/task-pipeline.js # npx installer (package task-pipeline-skill)
|
|
169
176
|
install.sh # POSIX installer
|
|
@@ -43,7 +43,8 @@ better, plus one that is required only for user-facing work.
|
|
|
43
43
|
|
|
44
44
|
| Skill / tool | Needed for | Required? | Install |
|
|
45
45
|
|---|---|---|---|
|
|
46
|
-
| **super-ux** (`ux-foundation`, `ux-flows`, `ux-scenarios`, `ux-audit`, `/ux`, `/ux-lint`) | stage 3 UX track | **Required for any user-facing task** | `/plugin marketplace add ssheleg/super-ux` → `/plugin install super-ux@super-ux` (or `npx skills add ssheleg/super-ux`) |
|
|
46
|
+
| **super-ux** (`ux-foundation`, `ux-flows`, `ux-scenarios`, `ux-audit`, `/ux`, `/ux-lint` — **and the copy half**: `copywriting`, `brand-voice`, `/brand-init`, `/copy`, `/brand-lint`, plus `/vision`) | stage 3 — the **UX track** *and* the **COPY track**. This row named six surfaces until 2026-08-10 while super-ux shipped eight skills and fifteen commands: the whole brand-and-copy half was invisible to this pipeline, so a run built scenarios and screens and then wrote the interface strings by taste | **Required for any user-facing task** | `/plugin marketplace add ssheleg/super-ux` → `/plugin install super-ux@super-ux` (or `npx skills add ssheleg/super-ux`) |
|
|
47
|
+
| **sheleg-design** (`/sheleg-design`) | stage 3 — the **VISUAL track**: tokens and themes, typography and rhythm, motion and how it degrades to rest, the visual language a brand is recognised by. It answers *how it looks*, which no other companion here answers — `super-ux` decides what the interface must do, `copywriting` how it sounds. Before 2026-08-10 this skill appeared once in the whole bundle, as a name in a list | **Recommended** on any task with a visual surface; never a gate. Absent → the run says the visual layer shipped **undesigned**, which is the honest name for picking values at the keyboard | `/plugin marketplace add ssheleg/sheleg-design` → `/plugin install sheleg-design@sheleg-design-skill` |
|
|
47
48
|
| **context7** (MCP — call tools fully qualified: `context7:resolve-library-id`, `context7:query-docs`) | stage 1 docs study | Recommended (web-search fallback) | connect the context7 MCP server |
|
|
48
49
|
| **Figma** (MCP) | stage 3 UX track, when the project designs visually — super-ux mirrors each `SCR-` screen/state into a frame | Optional, **UI + Figma-on only**. Absent → super-ux degrades to text-only *by itself and never blocks*, so shipping a UI feature with no mockups becomes a silent scope call — which is why the stage-0 sweep decides it | connect the Figma MCP server (`/mcp`, or your claude.ai connectors) |
|
|
49
50
|
| **[obsidian-wiki](https://github.com/ar9av/obsidian-wiki)** (`wiki-query`, `wiki-update`) | **stage 0 harvest** (query what's already known) **+ stage 9 sync** | **Recommended** — never a gate; absent → harvest runs on repo docs alone | `pip install obsidian-wiki` → `obsidian-wiki setup --vault /path/to/your/vault` |
|
|
@@ -77,9 +78,16 @@ exchange:
|
|
|
77
78
|
|
|
78
79
|
```
|
|
79
80
|
Pipeline companions (stage doctrine is built in — nothing to install for it):
|
|
80
|
-
✗ super-ux — this task looks user-facing; required for the UX track
|
|
81
|
+
✗ super-ux — this task looks user-facing; required for the UX track,
|
|
82
|
+
and it also owns the COPY track (copywriting, brand-voice):
|
|
81
83
|
/plugin marketplace add ssheleg/super-ux
|
|
82
84
|
/plugin install super-ux@super-ux
|
|
85
|
+
✗ sheleg-design — this task has a visual surface; it owns the VISUAL track:
|
|
86
|
+
tokens, themes, typography, rhythm, motion and its rest state:
|
|
87
|
+
/plugin marketplace add ssheleg/sheleg-design
|
|
88
|
+
/plugin install sheleg-design@sheleg-design-skill
|
|
89
|
+
(running without it — the visual layer ships undesigned,
|
|
90
|
+
and the close-out says so in those words)
|
|
83
91
|
✓ context7 — ready
|
|
84
92
|
✗ Figma MCP — this task is user-facing and the project designs in Figma
|
|
85
93
|
(docs/ux/foundation.md → Design tooling). Without it the
|
|
@@ -120,7 +128,16 @@ Install the ✗ items you want, answer the model line, then say "continue".
|
|
|
120
128
|
Rules:
|
|
121
129
|
|
|
122
130
|
- Only flag **super-ux** when the task implies a UI (the stage-0 grill decides;
|
|
123
|
-
when unsure, flag it — a false positive costs one install).
|
|
131
|
+
when unsure, flag it — a false positive costs one install). It arms **two** tracks,
|
|
132
|
+
not one: the UX chain and the copy layer.
|
|
133
|
+
- **sheleg-design**: flag it when the task has a **visual** surface — a page, a screen,
|
|
134
|
+
a themed component, a landing, a dashboard. Detect via a resolving `/sheleg-design`.
|
|
135
|
+
**A CLI, a library, a backend service or an internal script does not flag it**, and
|
|
136
|
+
neither does a purely structural change to an existing screen: choosing a palette for
|
|
137
|
+
a log parser is how a recommendation is taught to be noise, and this bundle already
|
|
138
|
+
spent a rule learning that about the browser. Absent → the run continues and says the
|
|
139
|
+
visual layer shipped **undesigned**; that is a weaker claim and the close-out records
|
|
140
|
+
it as one, exactly as it does for a surface verified by reading the diff.
|
|
124
141
|
- **obsidian-wiki**: detect via `~/.obsidian-wiki/config` or a resolving
|
|
125
142
|
`wiki-query`/`wiki-update`. Present → say `✓ ready` and use it in the harvest.
|
|
126
143
|
Absent → print the two install lines **once** and continue; never ask twice in a
|
|
@@ -129,9 +129,26 @@ works a stale board for as long as the loop runs. One command, at the top of the
|
|
|
129
129
|
iteration, recorded ([`knowledge-sources.md`](knowledge-sources.md) → *Carried-in
|
|
130
130
|
claims*; [`learned.md`](learned.md) rule 16).
|
|
131
131
|
|
|
132
|
+
**The work-list is `docs/superpowers/backlog.md`** ([`backlog.md`](backlog.md)), and the
|
|
133
|
+
other half of the same measurement is the exposure line ([`exposure.md`](exposure.md)).
|
|
134
|
+
Counted at the top of the iteration, re-derived at the bottom — `age` moves on its own,
|
|
135
|
+
so the re-derivation is the only moment the board stops being stale.
|
|
136
|
+
|
|
132
137
|
This is also where a loop's report goes wrong most quietly. *"Next up is X"* at the
|
|
133
138
|
end of an iteration is a claim about the board, and it is the one sentence in the
|
|
134
|
-
whole cycle that no gate reads. It cites the measurement or it is not written
|
|
139
|
+
whole cycle that no gate reads. It cites the measurement or it is not written — **a
|
|
140
|
+
`B-NNN`, not a description**: *"next up: B-014"* can be checked against the file,
|
|
141
|
+
*"next up: the export fix"* cannot.
|
|
142
|
+
|
|
143
|
+
**And it is printed, in one fixed shape** ([`progress.md`](progress.md)):
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
▶ <topic> · <module> (N/M) · <id> <stage> <gate> · iter <N> · gates <N/M> · next B-NNN
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
The iteration number is a count of `iter:` lines in `.task-pipeline/run.md`, not a
|
|
150
|
+
number the agent is carrying. After a compaction the agent's count is gone and the
|
|
151
|
+
file's is not — which is the argument the build ledger already won one stage down.
|
|
135
152
|
|
|
136
153
|
## Parked at a manual gate
|
|
137
154
|
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# Exposure — how much unverified work has piled up, and what to look at
|
|
2
|
+
|
|
3
|
+
**One job: turn the verification ledger into a number somebody can act on, without
|
|
4
|
+
pretending it is a probability.**
|
|
5
|
+
|
|
6
|
+
[`verification.md`](verification.md) records whether a person ever confirmed each shipped
|
|
7
|
+
REQ. This file turns that record into the line printed beside every verdict, and into the
|
|
8
|
+
list `/task-pipeline checkup` hands an operator.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Contents
|
|
13
|
+
|
|
14
|
+
- Why it is not a probability
|
|
15
|
+
- The components, each named
|
|
16
|
+
- The check-list, and how it is ordered
|
|
17
|
+
- `/task-pipeline checkup`
|
|
18
|
+
- What the loop does with it
|
|
19
|
+
- Rationalizations
|
|
20
|
+
|
|
21
|
+
## Why it is not a probability
|
|
22
|
+
|
|
23
|
+
The request that produced this file asked for *"the probability of an error"*. That is
|
|
24
|
+
not computable from these inputs, and a number presenting itself as `P(defect)` is the
|
|
25
|
+
false-success class this repository has spent its whole history removing: an estimate
|
|
26
|
+
wearing a measurement's clothes.
|
|
27
|
+
|
|
28
|
+
**So no percentage, ever** — the guard rejects a `%` on the exposure line. What ships is
|
|
29
|
+
a **vector with its components named**, and the reason is not fussiness: a single score
|
|
30
|
+
invites a threshold, and a threshold here is a target on `never`, which is the one thing
|
|
31
|
+
[`verification.md`](verification.md) says may never have one.
|
|
32
|
+
|
|
33
|
+
It could become a real probability later. `verification.md` is exactly the journal that
|
|
34
|
+
would make calibration possible after enough runs carry both a confirmation date and a
|
|
35
|
+
defect. Until then it is named honestly.
|
|
36
|
+
|
|
37
|
+
## The components, each named
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
exposure: N unverified · never checked · N releases carry one
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**The example carries no numbers, deliberately.** It said `99 unverified` and
|
|
44
|
+
`31 releases since the last human confirmation` until 2026-08-10 — one figure lifted
|
|
45
|
+
from this repository's live count, which drifts, and one wording the code has never
|
|
46
|
+
printed. A worked example that disagrees with its own output teaches the wrong format
|
|
47
|
+
to every reader who trusts the doctrine over the terminal, and this one disagreed in
|
|
48
|
+
both directions at once.
|
|
49
|
+
|
|
50
|
+
- **unverified** — rows whose `Human` reads `never`.
|
|
51
|
+
- **since** — days since the newest `Human` date. When **no** row has ever been
|
|
52
|
+
confirmed, this prints the literal **`never checked`**, not `0 days`: zero would read
|
|
53
|
+
as *checked today*, which is the opposite of the truth and exactly the kind of quiet
|
|
54
|
+
inversion this pipeline exists to prevent.
|
|
55
|
+
- **releases** — tags cut since that date, or since the first shipped row when there is
|
|
56
|
+
no date. It is the component an operator feels: *"how much has gone out on top of
|
|
57
|
+
something nobody looked at."*
|
|
58
|
+
|
|
59
|
+
Every component is derived from files in the repository. None is estimated.
|
|
60
|
+
|
|
61
|
+
## The check-list, and how it is ordered
|
|
62
|
+
|
|
63
|
+
The list is the deliverable — a number without it tells somebody they have a problem and
|
|
64
|
+
not where. Ordered by what the repository can defend:
|
|
65
|
+
|
|
66
|
+
1. **Oldest first**, by `Shipped in`. The longest-unconfirmed row is the one whose
|
|
67
|
+
context is most gone, and whose author is least likely to remember it.
|
|
68
|
+
2. **Tie-broken by blast radius** where the board carries a row for it, reusing
|
|
69
|
+
[`backlog.md`](backlog.md)'s own stated input rather than inventing a weight here.
|
|
70
|
+
|
|
71
|
+
No third factor. A ranking with an unstated input is the hand-assigned priority the board
|
|
72
|
+
already refuses.
|
|
73
|
+
|
|
74
|
+
## `/task-pipeline checkup`
|
|
75
|
+
|
|
76
|
+
A **mode of the command**, like `setup` — not a new command, because a second command
|
|
77
|
+
costs every surface a command touches and this repository has learned what that means.
|
|
78
|
+
|
|
79
|
+
**It runs with no task in flight, and that is the point.** Accumulated unverified work is
|
|
80
|
+
invisible *precisely because nobody is running a pipeline*; a check that only exists
|
|
81
|
+
inside a run can never say *"stop, fourteen things are unconfirmed."* So it takes no
|
|
82
|
+
brief, opens no grill, and writes nothing on its own.
|
|
83
|
+
|
|
84
|
+
It prints four sections, each read from a file this pipeline already keeps: the exposure
|
|
85
|
+
line and its check-list, the board's open rows by computed priority, the carry-over
|
|
86
|
+
ledgers' unresolved count, and the code graph's staleness where one exists.
|
|
87
|
+
|
|
88
|
+
**Where the operator asks it to file findings**, it appends board rows whose `Source`
|
|
89
|
+
names the checkup and its date — so a row a machine created is distinguishable from one a
|
|
90
|
+
run surfaced. It prints what it would add first. Never silently.
|
|
91
|
+
|
|
92
|
+
## What the loop does with it
|
|
93
|
+
|
|
94
|
+
[`continuity.md`](continuity.md) has always required each iteration to re-measure the
|
|
95
|
+
work-list, and said that *"next up is X"* is a claim about the board that no gate reads.
|
|
96
|
+
[`backlog.md`](backlog.md) is that board; the exposure line is the other half of the same
|
|
97
|
+
measurement, and both are read at the top of an iteration and re-derived at the bottom.
|
|
98
|
+
|
|
99
|
+
An iteration that reports what it will do next **cites the file**: `B-014`, not *"the
|
|
100
|
+
export fix"*.
|
|
101
|
+
|
|
102
|
+
## Rationalizations
|
|
103
|
+
|
|
104
|
+
| The excuse | What is actually true |
|
|
105
|
+
|---|---|
|
|
106
|
+
| "Give me one number, I'll decide the threshold" | The threshold would be a target on `never`, and the column would start lying within a week. The components are one line; read them. |
|
|
107
|
+
| "A percentage is easier to communicate" | It is easier to communicate because it says more than is known. That is the whole objection. |
|
|
108
|
+
| "The check-list is long, just show the top three" | Then the fourth is never checked and nobody knows it exists. Print it all; the operator can stop reading. |
|
|
109
|
+
| "Checkup duplicates stage 8" | Stage 8 verifies **this run's** deploy. Checkup asks what has accumulated across all of them, which no stage is ever in a position to ask. |
|
|
110
|
+
| "We'll run checkup when something breaks" | After a break you know where to look. The list exists for before. |
|
|
@@ -22,6 +22,7 @@ searches.
|
|
|
22
22
|
|
|
23
23
|
- Bookkeeping — the thing that makes detection mechanical
|
|
24
24
|
- Detection — any one of these trips the guard
|
|
25
|
+
- The review loop — a cap that measures rather than stops
|
|
25
26
|
- The break protocol
|
|
26
27
|
- When to stop and hand back
|
|
27
28
|
- Rationalizations
|
|
@@ -30,7 +31,8 @@ searches.
|
|
|
30
31
|
|
|
31
32
|
You cannot detect churn from memory, especially after compaction. Every repeating
|
|
32
33
|
pass appends one line to the run's ledger (`.task-pipeline/build/<plan>/progress.md`
|
|
33
|
-
for stage 5; `.task-pipeline/run.md` for stage-level and program-level loops
|
|
34
|
+
for stage 5; `.task-pipeline/run.md` for stage-level and program-level loops —
|
|
35
|
+
**seeded at stage 0** from [`../templates/run.md`](../templates/run.md)):
|
|
34
36
|
|
|
35
37
|
```
|
|
36
38
|
touch: <file> — pass <N> (<stage|round|module>) — reason: <finding id / gate item>
|
|
@@ -40,6 +42,12 @@ One line per file per pass. The reason must name **what forced the edit** — a
|
|
|
40
42
|
finding id, a failed gate item, an operator instruction. "Cleanup", "polish" and
|
|
41
43
|
"while I was there" are not reasons; they are churn with better manners.
|
|
42
44
|
|
|
45
|
+
**This ledger was required here from the day the file shipped and written by no run
|
|
46
|
+
until 2026-08-10.** The detection below calls itself mechanical; with no ledger it had
|
|
47
|
+
no input at all, so the guard sat on rung 1 while every reader took it for rung 3
|
|
48
|
+
([`gates.md`](gates.md) → *Axis B*). It is now seeded at stage 0 and named in that
|
|
49
|
+
stage's gate — which is the whole difference between a rule and a rule that runs.
|
|
50
|
+
|
|
43
51
|
## Detection — any one of these trips the guard
|
|
44
52
|
|
|
45
53
|
1. **Revert-oscillation.** An edit restores something an earlier pass in this run
|
|
@@ -59,7 +67,48 @@ finding id, a failed gate item, an operator instruction. "Cleanup", "polish" and
|
|
|
59
67
|
|
|
60
68
|
Caps that trip the guard by themselves: **5 fix rounds** per task
|
|
61
69
|
([`build.md`](build.md)), **2 re-entries** per stage per artifact, **3 passes** per
|
|
62
|
-
module in the program loop
|
|
70
|
+
module in the program loop, and **3 review rounds** per artifact — which is not a stop
|
|
71
|
+
but a measurement, below.
|
|
72
|
+
|
|
73
|
+
## The review loop — a cap that measures rather than stops
|
|
74
|
+
|
|
75
|
+
The caps above govern loops that **edit**. A review loop does both: the reader finds,
|
|
76
|
+
the run fixes, the reader reads again. It had no cap at all until 2026-08-10, and this
|
|
77
|
+
repository's own run stamps say what that cost — **ten rounds, ten, eight, four,
|
|
78
|
+
three** — against a stated ceiling of two re-entries per stage. Nothing tripped,
|
|
79
|
+
because a review round was named in no cap.
|
|
80
|
+
|
|
81
|
+
**A flat cap would have been the wrong fix.** Every one of those runs recorded *"none
|
|
82
|
+
from my probes"* beside its count: the reader was still finding real defects on round
|
|
83
|
+
nine. Stopping at two would have shipped them.
|
|
84
|
+
|
|
85
|
+
So the cap is a **decision point**. Default **3 rounds** per artifact, recorded in
|
|
86
|
+
`pipeline.json` → `run.review.maxRounds`. On reaching it, stop reviewing and print the
|
|
87
|
+
pair [`audit.md`](audit.md) already defines — new findings, and findings caused by this
|
|
88
|
+
run's own fixes — per round:
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
review cap reached — 3 rounds — artifact: test/validate.py
|
|
92
|
+
round 1: 12 new · 0 self-inflicted
|
|
93
|
+
round 2: 5 new · 1 self-inflicted
|
|
94
|
+
round 3: 1 new · 3 self-inflicted
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
- **Self-inflicted ≥ new** — the axis is exhausted ([`audit.md`](audit.md) → *Every
|
|
98
|
+
pass changes the axis*). Stop. Every remaining finding becomes a board row with its
|
|
99
|
+
evidence ([`backlog.md`](backlog.md)); none is dropped.
|
|
100
|
+
- **New > self-inflicted** — the reader is still paying. Continuing is then the
|
|
101
|
+
operator's call, made with the numbers in hand rather than out of fatigue.
|
|
102
|
+
|
|
103
|
+
**The pair is the whole point.** A round count alone says how tired everyone is; the
|
|
104
|
+
pair says whether the loop still produces anything. Measured on one file once, the
|
|
105
|
+
guard's shapes and the run's own prose disagreed — one still paying, one exhausted —
|
|
106
|
+
so a single number would have stopped the half that was working and continued the half
|
|
107
|
+
that was not.
|
|
108
|
+
|
|
109
|
+
**Rounds are counted from the ledger, never from memory**: distinct `pass N` values on
|
|
110
|
+
`touch:` lines at the review stage. A round that finds nothing ends the loop by
|
|
111
|
+
definition and needs no counting.
|
|
63
112
|
|
|
64
113
|
## The break protocol
|
|
65
114
|
|
|
@@ -109,6 +158,7 @@ far cheaper than a third round of the same argument.
|
|
|
109
158
|
| Excuse | Reality |
|
|
110
159
|
|---|---|
|
|
111
160
|
| "One more pass and it converges" | Two passes with the same reason already proved it doesn't. The disagreement is above the code. |
|
|
161
|
+
| "The reviewer is still finding things, so keep going" | Then say so with the pair: new versus self-inflicted, per round. If new still leads, that is an argument. Ten rounds with nobody counting is not. |
|
|
112
162
|
| "I'll just revert to what worked" | That is the oscillation, not the exit. Name A and B first. |
|
|
113
163
|
| "The reviewer keeps changing its mind" | Different findings on the same lines mean the requirement is ambiguous. That's a spec question. |
|
|
114
164
|
| "Tidying while I'm in the file" | Untracked edits are what make churn invisible. One reason per change, in the ledger. |
|
|
@@ -52,10 +52,12 @@ a row pointing outside the bundle is the defect this file exists to catch.
|
|
|
52
52
|
| The entry audit and what it inspects | `references/setup.md` |
|
|
53
53
|
| The ladder, seams, axis rotation, ratchets | `references/audit.md` |
|
|
54
54
|
| Loop detection and its caps | `references/loop-guard.md` |
|
|
55
|
+
| **What the run prints about itself** — the header block, the rail, the iteration line | `references/progress.md` |
|
|
55
56
|
| **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
|
|
56
57
|
| **The context budget** — the evidence rule and what a flush actually updates | `references/continuity.md` |
|
|
57
58
|
| **The board** — the work-list between runs, its computed priority, and the ledger seam it resolves | `references/backlog.md` |
|
|
58
59
|
| **The verification ledger** — what shipped, and whether a human ever confirmed it | `references/verification.md` |
|
|
60
|
+
| **Exposure** — the unconfirmed count as a named vector, never a probability, and the `checkup` mode | `references/exposure.md` |
|
|
59
61
|
| The retro: prune, cap, commits, archive | `references/retrospective.md` |
|
|
60
62
|
| Rules earned by failure | `references/learned.md` |
|
|
61
63
|
| **The routing default and its boundary** | `templates/routing-rule.md` |
|