task-pipeline-skill 1.10.2 → 1.11.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 CHANGED
@@ -1,5 +1,104 @@
1
1
  # Changelog
2
2
 
3
+ ## v1.11.0 — 2026-08-04
4
+
5
+ ### Added — run continuity: the pacing rules the operator was repeating by hand
6
+
7
+ Two rules that had to be said out loud at the start of every run. One of them was
8
+ already written down, which is the interesting half.
9
+
10
+ **The loop mode is now config, not a request.** `references/build.md` has carried
11
+ *"Continuous execution: don't check in between tasks"* since early on, and it did
12
+ not work — for two compounding reasons. It lived inside stage 5, so an agent
13
+ running any other stage never saw it; and on a harness where a turn ends, prose
14
+ cannot carry a run across the boundary at all. Only a scheduled re-invocation
15
+ can. So the decision moved to `pipeline.json` → `run.loop`, read at preflight in
16
+ the same block as the model: recorded means armed and never re-asked, absent means
17
+ **off**. `build.md`'s rule keeps its full force and gains one sentence naming its
18
+ scope, because the two govern different things and a reader was going to take one
19
+ for the other.
20
+
21
+ **The context rule fires on evidence or not at all.** The opposite failure was
22
+ live: runs announcing that context was nearly exhausted against a mostly-empty
23
+ window, because an estimate from transcript length was being presented as a
24
+ measurement. Nothing returns the remaining percentage, so the rule now admits
25
+ exactly two signals — the harness saying so, or the operator saying so — and
26
+ forbids the announcement without one. When it does fire: finish the item in
27
+ flight, start no new one, make the ledgers true, continue. Not stop.
28
+
29
+ There is deliberately **no config field** for the context half. The one number
30
+ anyone would put in it is the one that can never be honoured, and the schema's own
31
+ `description` says so — a blank space in a contract gets filled back in by the
32
+ next contributor as an oversight.
33
+
34
+ Both halves live in one new file, `references/continuity.md`, because they are one
35
+ mechanism: the loop is what makes the context rule necessary. Without a loop a run
36
+ stops at the turn boundary anyway; with one, it will start an item it cannot
37
+ finish.
38
+
39
+ ### Fixed — three templates whose links were broken everywhere they are read
40
+
41
+ `templates/adr.md`, `carryover.md` and `routing-rule.md` carried relative links
42
+ that resolved from `templates/` — where the files are stored — and from nowhere
43
+ they are ever actually seeded. `carryover.md` had shipped one since v1.1.0 and the
44
+ link checker was green the whole time, because it resolves from the file's home.
45
+ No run had seeded the template verbatim, so nobody hit it until one did.
46
+
47
+ The rule is now the one the Cursor rule already follows: a document that travels
48
+ is self-contained, and names files in code spans rather than linking to them.
49
+
50
+ ### Guards — 63 → 68
51
+
52
+ `run.loop.mode` must be set explicitly in the shipped example; five surfaces must
53
+ name `continuity.md`; the two load-bearing clauses in `continuity.md` must survive
54
+ an edit (matched after whitespace normalisation, since both wrap at 80 columns and
55
+ a line-oriented search would reject correct prose); and no seeded template may
56
+ carry a relative link. Four invariants added to `CONTRIBUTING.md`, each citing the
57
+ guard that enforces it.
58
+
59
+ `CLAUDE.md`'s claim of *sixteen* invariants — the list held twenty-four — was
60
+ deleted rather than corrected. A hand-written count drifts; that is what the rule
61
+ about computing numbers is for, and this file was breaking it.
62
+
63
+ ## v1.10.3 — 2026-08-03
64
+
65
+ ### Fixed — the cause behind five audits, rather than a sixth symptom
66
+
67
+ Five audit passes produced roughly thirty findings. Grouped by shape, **nine of them
68
+ were one missing row**: this repository ships a propagation matrix to every project it
69
+ touches and its own had no row for *adding a document*.
70
+
71
+ `adoption.md`, `setup.md`, `portability.md` and `learned.md` never reached the README
72
+ map · the manifest covered 14 of 26 references · the Cursor rule ran two releases
73
+ stale · `CONTRIBUTING.md` ran eight guards behind · `agent-sync` was doctrine in four
74
+ files and absent from the companion matrix · `templates/README.md` went stale. One
75
+ cause, nine symptoms, five audits — and **every check was green throughout**, because
76
+ a check can only walk the list it was given.
77
+
78
+ **The meta-row.** The most frequent change in any documented project is adding a
79
+ document, and it is the row nobody writes — so the matrix ends up unable to catch the
80
+ class it will meet most often. It is now:
81
+
82
+ - **step 0** of the matrix-building procedure in `references/documentation.md`, with
83
+ the measurement attached;
84
+ - a row in this repository's own `docs/DOCMAP.md`, first;
85
+ - a row in the seeded `templates/docmap.md`, guarded — a seeded matrix without it
86
+ fails the build;
87
+ - pass 4 of the entry audit in `references/setup.md`;
88
+ - a named step before the tag in `CONTRIBUTING.md` → *Releasing*, where the one cell
89
+ that is `review` — the Cursor rule — is called out, because no check can decide
90
+ whether a change alters how an agent behaves in a **foreign** project. That cell was
91
+ skipped twice, and the rule shipped two versions stale.
92
+
93
+ ### The two causes no row can fix, stated rather than left implied
94
+
95
+ **Guards are written after a finding.** The doctrine's own rule — a class seen twice
96
+ becomes a script — is by construction one instance late, and twice a fix was scoped to
97
+ its instance rather than its class.
98
+
99
+ **Author and reviewer are the same person**, which `SKILL-CARD.md` already discloses.
100
+ Five audits are what a review would have been.
101
+
3
102
  ## v1.10.2 — 2026-08-03
4
103
 
5
104
  ### Fixed — the list of invariants was eight guards behind, and now checks itself
package/CONTRIBUTING.md CHANGED
@@ -169,7 +169,34 @@ with the bundle instead of being hand-installed into an operator's config.
169
169
  reads those files, and a partial read shows whichever sections come first.
170
170
  *(guard: `needs the same partial-read protection references get`)*
171
171
 
172
- **24. Every invariant above names the guard that enforces it, and that guard exists.**
172
+ **24. Run-wide pacing is config, and the example demonstrates its default.** The
173
+ `run` block in `pipeline.schema.json` carries the loop mode; the shipped example
174
+ sets `run.loop.mode` explicitly rather than omitting it, because the example is
175
+ what gets copied and an absent field reads as an oversight instead of a decision.
176
+ *(guard: `no explicit run.loop.mode`)*
177
+
178
+ **25. The run-wide mode is named by every stage that could be misled by it.**
179
+ `SKILL.md`, `references/grill.md`, `references/build.md`, `references/stages.md`
180
+ and `templates/brief.md` each name `continuity.md`. The continuous-execution rule
181
+ sat inside `build.md` for nine releases and did not work, because an agent running
182
+ one stage never re-reads the orchestrator to discover a run-wide rule exists.
183
+ *(guard: `a run-wide rule no stage has heard of`)*
184
+
185
+ **26. `references/continuity.md` keeps its two load-bearing clauses.** One forbids
186
+ announcing that context is nearly spent without a harness signal; the other names
187
+ the harness limit on the loop primitive. Both are one edit away from softening into
188
+ nothing. The guard normalises whitespace first — the clauses wrap at 80 columns,
189
+ and a line-oriented search would reject correctly formatted prose.
190
+ *(guard: `missing the contractual clause`)*
191
+
192
+ **27. A seeded template carries no relative markdown links.** A template is copied
193
+ somewhere else by definition, so a link that resolves from `templates/` is broken
194
+ everywhere the file is actually read. `carryover.md` shipped one for nine minor
195
+ releases and the link checker stayed green throughout, because it resolves from the
196
+ file's home. Name the file in a code span instead — the same rule the Cursor rule
197
+ follows, for the same reason. *(guard: `resolves only from`)*
198
+
199
+ **28. Every invariant above names the guard that enforces it, and that guard exists.**
173
200
  This list claims to be *what the validator enforces*; it was eight guards behind when
174
201
  an audit measured it. A claim of enforcement is now checked like any other claim.
175
202
  *(guard: `whose message does not appear in`)* — and a cited literal must lie inside
@@ -206,6 +233,14 @@ quote straddling a line-continuation is a citation nothing can find.
206
233
 
207
234
  ## Releasing (maintainers)
208
235
 
236
+ **Before the tag, walk `docs/DOCMAP.md`'s propagation matrix — starting at its first
237
+ row.** The guards cover most of it; the one cell that is `review` is
238
+ `cursor/rules/task-pipeline.mdc`, because no check can decide whether a change alters
239
+ how an agent behaves in a *foreign* project. That cell was skipped for two releases
240
+ and the rule shipped two versions stale. If the change would make an agent act
241
+ differently somewhere else, the Cursor rule is part of the change.
242
+
243
+
209
244
  1. Bump the version in **all four** places (see invariant 1) and write the
210
245
  `CHANGELOG.md` section — what changed and *why it mattered*, not a diff summary.
211
246
  2. `npm test` green, commit, push.
package/README.md CHANGED
@@ -127,6 +127,7 @@ until it is installed.
127
127
  | 10 Acceptance | [`acceptance.md`](plugins/task-pipeline/skills/task-pipeline/references/acceptance.md) — REQ coverage table, evidence rules, the closing question |
128
128
  | 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 |
129
129
  | any loop | [`loop-guard.md`](plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md) — churn detection, caps, the break protocol |
130
+ | 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) |
130
131
  | 0 + 9 + any settled decision | [`documentation.md`](plugins/task-pipeline/skills/task-pipeline/references/documentation.md) — the inventory, registers and ids, SSOT, the Doc Loop, supersede semantics, the propagation matrix, intent vs as-built |
131
132
  | 6–10 + any check you write | [`gates.md`](plugins/task-pipeline/skills/task-pipeline/references/gates.md) — the two axes, the promotion ladder, gate anatomy, the probe recipe, ratchet floors |
132
133
  | any agent-time enforcement | [`hooks.md`](plugins/task-pipeline/skills/task-pipeline/references/hooks.md) — the `PreToolUse` contract, the fail-open hazard, the Claude-Code-only limit |
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.10.2 |
15
+ | **Version** | 1.11.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 (15 evals, 5 categories). **Never executed** — see [`evals/RESULTS.md`](evals/RESULTS.md) |
@@ -38,7 +38,7 @@ apply.
38
38
  instruction surface, and every one is linked directly from `SKILL.md`.
39
39
  2. Read `templates/docgate.sh` before seeding it; it is the only shipped script a
40
40
  host project will run on its own repository.
41
- 3. Run `npm run test:all` — 62 guards, each with a negative self-test that plants a
41
+ 3. Run `npm run test:all` — 68 guards, each with a negative self-test that plants a
42
42
  defect and requires rejection.
43
43
  4. Run `python3 evals/run.py` for the behavioural protocol, and read
44
44
  `evals/RESULTS.md` for what has actually been observed.
@@ -54,7 +54,7 @@ apply.
54
54
  - **Versions are pinned by git tag** and mirrored into `sshlg-skills`'s catalogue.
55
55
  Rollback is `git checkout v<previous>` or pinning the previous plugin version;
56
56
  the previous version is never deleted.
57
- - **Behavioural evidence is missing, not merely thin.** 62 structural guards prove
57
+ - **Behavioural evidence is missing, not merely thin.** 68 structural guards prove
58
58
  the skill is well-formed. Until `evals/RESULTS.md` carries a dated run, nothing in
59
59
  this repository proves it *behaves* — triggers correctly, stays quiet on a
60
60
  question, or performs the steps it documents.
@@ -24,6 +24,47 @@ you recommend and what they're on, let them confirm or override (per-stage
24
24
  overrides welcome), record the answer — then **stop asking at every stage**. If the
25
25
  recommended tier isn't available, say which one you're using and continue.
26
26
 
27
+ ## Pacing — the run mode, and the context budget
28
+
29
+ Two rules about how a run keeps going. Settle the first at stage 0, in the same
30
+ block as the model; the second is unconditional and needs no setting.
31
+
32
+ **The run mode.** On, the run advances one item per iteration and does not ask
33
+ between items — the plan's tasks, the boundary between stages whose gate is
34
+ automatic, the per-module loop, the acceptance tail. It stops for exactly four
35
+ things: a manual gate, a block it can't resolve, a genuine ambiguity, completion.
36
+
37
+ - **Off unless recorded.** Read the project's pipeline config → `run.loop`. A
38
+ recorded mode is the answer and is never re-asked; absent, the mode is **off**.
39
+ Silence arms nothing, the same floor deploy authorization uses.
40
+ - **It buys pacing, never authorization.** It never collapses a manual gate, and
41
+ never a deploy, publish, PR or shared-design-file write. A generic flag is not a
42
+ specific authorization.
43
+ - **Prose does not survive a turn boundary.** Where the harness offers a loop
44
+ primitive, arm it and say the interval, the job id and how to cancel; where it
45
+ does not, the mode degrades to discipline plus the build ledger — and you say
46
+ which of the two you are actually running rather than implying the stronger one.
47
+ - **Pick an interval longer than a typical item**, and one that divides its unit
48
+ cleanly. If the job auto-expires, say when: a loop that quietly stops is worse
49
+ than one never armed.
50
+ - **Parked at a manual gate, cancel the loop** and print the re-arm command beside
51
+ the gate. A loop firing into a gate every few minutes is a nag, and a nagged
52
+ operator stops reading.
53
+
54
+ **The context budget.** Near the end of the window: finish the item in flight,
55
+ **start no new one**, make the ledgers true, then continue. Compaction is a normal
56
+ event, not the end of the run — what loses work is crossing it mid-item.
57
+
58
+ - **It fires on evidence only:** a harness signal (a compaction warning, a
59
+ pre-compaction hook) or the user saying so. Nothing returns the remaining
60
+ percentage, so an estimate from transcript length is a guess — and announcing
61
+ that context is nearly spent without a signal is presenting a guess as a
62
+ measurement. A run that keeps volunteering it against a mostly-empty window
63
+ trains the user to disregard the one time it is true.
64
+ - **Flushing updates what already exists** — the build ledger, the carry-over
65
+ ledger, requirement statuses, the task list. Not a summary written for the
66
+ compactor: that is a fourth copy of the truth that nobody maintains.
67
+
27
68
  ## Stage 0 — intake grill (MANDATORY, do this FIRST)
28
69
 
29
70
  Never skipped, and nothing to install — the grill is part of this rule. No "the
@@ -465,3 +506,17 @@ contradict it.
465
506
  decision about what this project decided belongs in the project. The test for a rule
466
507
  you are about to write down: does it name a path, a command or a person? If not, it is
467
508
  the pipeline's, and leaving it in one repository is a fork nobody named.
509
+
510
+ ## Writing a propagation matrix — start with the row nobody writes
511
+
512
+ The most frequent change in any documented project is **adding a document**, and that
513
+ is the row people leave out — so the matrix ends up unable to catch the class it will
514
+ meet most often. Write it first, before the change types you can think of:
515
+
516
+ > **A new document or rule** → every surface that must *learn it exists*: the index a
517
+ > reader opens, the map, any manifest, the agent-facing rules file. Checked by:
518
+ > whatever check can resolve those, or `review` with the reason none can.
519
+
520
+ Measured on the project this pipeline comes from: nine findings across five audits
521
+ were that one missing row, with every check green throughout — a check only walks the
522
+ list it was given.
package/evals/RESULTS.md CHANGED
@@ -37,9 +37,9 @@ or it belongs in a check.
37
37
  | Dated runs recorded | **0** | 2026-08-03 |
38
38
 
39
39
  The bottom two numbers are the honest state of this skill's behavioural evidence.
40
- Everything else in this repository is proven by 62 structural guards that check the
40
+ Everything else in this repository is proven by 68 structural guards that check the
41
41
  *form*; these are the only checks that would speak to the *behaviour*, and they have
42
- not been run yet. Printed here so "62 of 62 green" is never read as "the skill is
42
+ not been run yet. Printed here so "63 of 63 green" is never read as "the skill is
43
43
  known to work".
44
44
 
45
45
  ## Runs
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "task-pipeline-skill",
3
- "version": "1.10.2",
3
+ "version": "1.11.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"
@@ -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 must close with evidence, a loop guard that breaks churn, one provider-agnostic model confirmed up front, and an optional super-ux UX track for user-facing work.",
5
- "version": "1.10.2",
5
+ "version": "1.11.0",
6
6
  "author": {
7
7
  "name": "ssheleg",
8
8
  "url": "https://x.com/sshlg93"
@@ -65,6 +65,7 @@ gate stops until it is installed.
65
65
  | **first run · the entry audit** (offered once) | [`references/setup.md`](references/setup.md) |
66
66
  | **what travels with the bundle vs stays in a project** | [`references/portability.md`](references/portability.md) |
67
67
  | any repeating loop | [`references/loop-guard.md`](references/loop-guard.md) |
68
+ | run-wide · how a run keeps going (the loop mode + the context budget) | [`references/continuity.md`](references/continuity.md) |
68
69
 
69
70
  **Optional bridge.** If the operator already runs an equivalent skill set (e.g.
70
71
  `superpowers:brainstorming` / `writing-plans` / `subagent-driven-development` /
@@ -181,7 +182,12 @@ Three things the grill does beyond clarifying the request:
181
182
  tasks, context7, wiki-update, graphify) and emits ONE block covering them
182
183
  **and the model decision** (`references/model-tiering.md`): recommend
183
184
  the most capable model available, let the operator confirm or override, record
184
- it. Ask once, here.
185
+ it. Ask once, here. **The same block carries the run mode**
186
+ (`references/continuity.md`): read `pipeline.json` → `run.loop`; where it is
187
+ recorded, arm it and print the job id and the cancel command — the config is
188
+ the authorization, so re-asking rebuilds the habit it exists to retire. Where
189
+ it is **absent, the mode is off**; recommend it in one line and move on.
190
+ Silence arms nothing, and the mode never collapses a `manual` gate.
185
191
  2. **Run stage 0 — always, no exceptions.** It opens with the **knowledge harvest**
186
192
  (`references/knowledge-sources.md`): query the project's own sources — repo docs,
187
193
  ADRs, `docs/ux/`, past briefs, the wiki if installed, any doc repo the project
@@ -341,6 +347,10 @@ automation is on — `pipeline.schema.json` is the only contract.
341
347
  inside the bundle, and the boundary against a project's own answers
342
348
  - `references/adoption.md` — the first run in a project: greenfield seeding, and the
343
349
  brownfield walkthrough whose third step baselines the ratchets at today
350
+ - `references/continuity.md` — run-wide pacing: the loop mode (`run.loop`, default
351
+ off, and it never collapses a manual gate), how it is armed on Claude Code and
352
+ what that costs, and the context budget — which fires on a harness signal, never
353
+ on an estimate
344
354
  - `references/conventions.md` — how stages 6–10 read the host project's CLAUDE.md
345
355
  - `references/companion-skills.md` — companion skills, install lines, preflight recommendation
346
356
  - `references/artifacts.md` — the canonical document/artifact layout per stage
@@ -170,6 +170,10 @@
170
170
  }
171
171
  }
172
172
  ],
173
+ "_run_note": "Run-wide pacing. Shipped explicitly OFF so this example DEMONSTRATES the default rather than relying on its absence — see references/continuity.md. Set mode to 'interval' and a project stops being asked whether to run item-by-item; it still stops at every manual gate. There is no context-budget field here on purpose: the threshold is not measurable, so it is unconditional doctrine, not config.",
174
+ "run": {
175
+ "loop": { "mode": "off", "interval": "5m", "command": "/loop" }
176
+ },
173
177
  "release": {
174
178
  "enabled": true,
175
179
  "trigger": "tag",
@@ -14,9 +14,38 @@
14
14
  "description": "The pipeline stages, in order. Any number, any names — your project's real stages.",
15
15
  "items": { "$ref": "#/definitions/stage" }
16
16
  },
17
- "release": { "$ref": "#/definitions/release" }
17
+ "release": { "$ref": "#/definitions/release" },
18
+ "run": { "$ref": "#/definitions/run" }
18
19
  },
19
20
  "definitions": {
21
+ "run": {
22
+ "type": "object",
23
+ "additionalProperties": true,
24
+ "description": "Optional run-wide pacing. Omit the object and every field defaults OFF: silence arms nothing and authorises nothing — the same floor deploy authorization uses. There is deliberately NO context-budget field: the remaining context is not measurable from inside a run, so a field accepting a percentage would validate a number that can never be honoured. That rule is unconditional doctrine in references/continuity.md instead.",
25
+ "properties": {
26
+ "loop": {
27
+ "type": "object",
28
+ "required": ["mode"],
29
+ "additionalProperties": true,
30
+ "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
+ "properties": {
32
+ "mode": {
33
+ "enum": ["off", "interval"],
34
+ "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
+ },
36
+ "interval": {
37
+ "type": "string",
38
+ "pattern": "^[0-9]+[smhd]$",
39
+ "description": "Required when mode is 'interval'. Must divide its unit cleanly (5m, 10m, 2h — not 7m or 90m); a value that does not is rounded to the nearest that does, and the rounding is stated out loud. Pick the shortest interval that is longer than a typical item."
40
+ },
41
+ "command": {
42
+ "type": "string",
43
+ "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
+ }
45
+ }
46
+ }
47
+ }
48
+ },
20
49
  "release": {
21
50
  "type": "object",
22
51
  "additionalProperties": true,
@@ -18,6 +18,15 @@ session's history, so it stays focused; your context stays free for coordination
18
18
  plan to be executed — execute it. Stop only for BLOCKED you can't resolve, a
19
19
  genuine ambiguity, or completion. "Should I continue?" between tasks is noise.
20
20
 
21
+ **Scope, so this is not mistaken for the run-wide mode:** the rule above governs
22
+ the *inside* of this stage and is unconditional — it holds whether or not a loop
23
+ is armed. What it cannot do is reach the other nine stages, or survive the
24
+ boundary between one agent turn and the next; on a harness where prose does not
25
+ carry across that boundary, only a scheduled re-invocation does.
26
+ [`continuity.md`](continuity.md) owns that half, is recorded in `pipeline.json` →
27
+ `run.loop`, and is **off unless recorded**. The two never disagree: one is a
28
+ stage's internal discipline, the other is the run's pacing.
29
+
21
30
  **Narration:** at most one short line between tool calls. The ledger and the tool
22
31
  results are the record.
23
32
 
@@ -0,0 +1,214 @@
1
+ # Continuity — how a run keeps going
2
+
3
+ Two rules about pacing, in one file because they are two halves of one mechanism.
4
+ The loop is what lets a run walk a task list without asking permission between
5
+ items. The context budget is what stops that loop from starting an item it cannot
6
+ finish. **Neither is useful without the other**, and a run that has the first
7
+ without the second fails in a specific, expensive way: it begins task nine with
8
+ almost no window left, loses the middle of it, and re-derives what it already did.
9
+
10
+ ## Contents
11
+
12
+ - The limit, before the capability
13
+ - Part 1 — the loop
14
+ - Arming it on Claude Code
15
+ - Other harnesses, and honest degradation
16
+ - What one iteration means
17
+ - Parked at a manual gate
18
+ - Part 2 — the context budget
19
+ - The evidence rule
20
+ - What happens at the signal
21
+ - The flush is not a new document
22
+ - Rationalizations
23
+
24
+ ## The limit, before the capability
25
+
26
+ **The loop mode collapses discretionary check-ins. It collapses nothing else.**
27
+
28
+ - A `manual` gate still waits for an explicit operator go. Always.
29
+ - An outward or irreversible act — deploy, publish, opening a PR, creating or
30
+ editing a shared design file — still needs its own authorization. A recorded
31
+ loop mode is a **generic** flag, and a generic flag is not a specific
32
+ authorization; that floor is set in [`grill.md`](grill.md) and this file does
33
+ not lower it.
34
+ - **Default off.** Absent config and absent instruction, the mode is off. Silence
35
+ arms nothing, exactly as silence authorizes no deploy.
36
+
37
+ The mode's whole content is the removal of *"should I continue?"* between items
38
+ the operator already asked for. Anything beyond that is a different decision,
39
+ taken separately.
40
+
41
+ ## Part 1 — the loop
42
+
43
+ **On, the run advances one item per iteration and does not ask between items.**
44
+ This spans the whole run, not one stage:
45
+
46
+ - the plan's tasks at stage 5;
47
+ - the boundary between stages whose gate is `auto`;
48
+ - the per-module program loop when the brief was a platform;
49
+ - the acceptance → retro tail, which is where runs most often stall one step from
50
+ finished.
51
+
52
+ It stops for exactly four things: a `manual` gate, a block it cannot resolve, a
53
+ genuine ambiguity the brief does not answer, and completion.
54
+
55
+ **This extends [`build.md`](build.md); it does not replace it.** That file's
56
+ *Continuous execution* rule governs the inside of a stage-5 execution — do not
57
+ check in between the tasks of a plan you were told to execute. It is unconditional
58
+ and stays that way. What it cannot do is reach the other nine stages, or survive
59
+ the boundary between one agent turn and the next. This file is that reach.
60
+
61
+ **Where it is recorded:** `pipeline.json` → `run.loop`. A project sets it once and
62
+ is never asked again — which is the entire point. A mode that has to be requested
63
+ every run is not a mode, it is a habit the operator maintains by hand.
64
+
65
+ ## Arming it on Claude Code
66
+
67
+ ```
68
+ /loop <interval> <the invocation that continues the run>
69
+ ```
70
+
71
+ The interval **must divide its unit cleanly** — `5m`, `10m`, `2h` are fine; `7m`
72
+ gives uneven gaps and `90m` cannot be expressed at all. A value that does not
73
+ divide cleanly is rounded to the nearest one that does, **and the rounding is said
74
+ out loud** before it is used.
75
+
76
+ Pick **the shortest interval that is longer than a typical item.** Shorter buys
77
+ nothing: the scheduler cannot deliver faster than the item finishes.
78
+
79
+ Two properties of the armed job must be stated when arming it, because both are
80
+ silent failures otherwise:
81
+
82
+ - **The job is session-only.** It is not written to disk and it dies with the
83
+ session.
84
+ - **It auto-expires after seven days**, firing one last time. A loop that quietly
85
+ stops on day eight is worse than one that was never armed, because the operator
86
+ believes work is still moving.
87
+
88
+ Where `run.loop.mode` is `interval`, the **preflight arms it** and prints the job
89
+ id and the cancel command. Arming is not a new decision at that point — the config
90
+ is the recorded authorization, and re-asking would rebuild the habit the config
91
+ exists to retire.
92
+
93
+ ## Other harnesses, and honest degradation
94
+
95
+ `/loop` is **Claude Code only**, in the same way the `PreToolUse` contract in
96
+ [`hooks.md`](hooks.md) is. This file names the limit rather than pretending the
97
+ mechanism is universal.
98
+
99
+ On a harness with no loop primitive, the mode degrades to what prose can do: the
100
+ discipline in [`build.md`](build.md) plus the build ledger, which is genuinely
101
+ useful and genuinely weaker. **Say which one you are running.** A run that reports
102
+ itself as looping while nothing is scheduled is claiming a capability it does not
103
+ have, and the operator finds out by discovering that nothing happened.
104
+
105
+ ## What one iteration means
106
+
107
+ One item, taken to its gate.
108
+
109
+ **A fixed interval cannot interrupt an unfinished item.** The scheduler enqueues
110
+ only while the harness is idle — never mid-query. This is the reason the interval
111
+ form is safe, and it is worth stating precisely, because the plausible-sounding
112
+ alternative explanation is wrong.
113
+
114
+ **The build ledger is the second line, not the first.** It covers a different
115
+ case: a fire that lands after a context loss, where the controller no longer
116
+ remembers what it finished. There, `Task <N>: complete` in
117
+ `.task-pipeline/build/<plan>/progress.md` is the only DONE marker that counts, and
118
+ a task carrying one is never re-dispatched ([`build.md`](build.md)).
119
+
120
+ Do not write, and do not believe, that the ledger is what makes the interval safe.
121
+ Someone will eventually remove the ledger on the strength of that sentence, and
122
+ the protection they think they are keeping is in the scheduler.
123
+
124
+ ## Parked at a manual gate
125
+
126
+ A fixed interval firing into a `manual` gate is a nag. Five minutes later it fires
127
+ again, and again, and the operator — who is reading the thing the gate asked them
128
+ to read — learns to ignore the loop. That is the same failure as a rule nobody
129
+ reads to the end: everyone believes it is covered.
130
+
131
+ **So the run cancels its own loop job when it parks**, and prints the re-arm
132
+ command beside the gate. The go and the re-arm are then one act. This is also the
133
+ honest accounting: while the run waits for a person, nothing is looping, and the
134
+ job list should agree with that.
135
+
136
+ **Verify the cancel by listing the jobs, never by the cancel's own reply.** A
137
+ teardown call will happily accept an id that was never scheduled and report
138
+ success, which leaves the real job running while the transcript says it stopped.
139
+ List afterwards and read the list. This is the same law the rest of this pipeline
140
+ applies to every gate — a green nobody watched is not evidence — and a loop is
141
+ exactly where breaking it goes unnoticed, because the symptom is a message
142
+ arriving on time.
143
+
144
+ ## Part 2 — the context budget
145
+
146
+ Near the end of the context window, the run does **not** stop and it does not
147
+ start anything new:
148
+
149
+ 1. **Finish the item in flight.** A half-finished item is the expensive state.
150
+ 2. **Start no new item.** An item begun in this window loses its own middle.
151
+ 3. **Make the ledgers true** (below).
152
+ 4. **Continue.** Compaction is a normal event, not the end of the run.
153
+
154
+ The failure this prevents is not running out of room — that is survivable. It is
155
+ crossing the boundary *in the middle of something*, so the work either vanishes or
156
+ gets done twice.
157
+
158
+ ## The evidence rule
159
+
160
+ **The rule fires only on evidence**, and there are exactly two admissible kinds:
161
+
162
+ - **A signal from the harness** — a warning that compaction is near, a `PreCompact`
163
+ hook firing, an explicit low-context notice.
164
+ - **The operator saying so.**
165
+
166
+ Absent both, the threshold has not been observed, and you **never announce that
167
+ the context is nearly spent without one of those signals**. No tool returns the
168
+ remaining percentage. An estimate from transcript length or how much has been read
169
+ is a guess, and presenting a guess as a measurement is precisely the failure
170
+ [`learned.md`](learned.md) names — compute, never restate.
171
+
172
+ This cuts both ways, and the second direction is the one that actually goes wrong:
173
+ a run that keeps volunteering *"context is nearly exhausted, start a new session"*
174
+ against a mostly-empty window trains the operator to disregard the one time it is
175
+ true.
176
+
177
+ ## What happens at the signal
178
+
179
+ The four acts above, in order, and one prohibition: **do not begin an item you
180
+ cannot finish inside what is left.** When the next item is plainly too large,
181
+ say so and take the smaller thing that fits — closing a ledger, writing a decision
182
+ that is already settled, updating a REQ status.
183
+
184
+ If the project has recorded that it must not cross a compaction mid-stage, stop at
185
+ the stage boundary instead and hand off. That is a project answer, not a default:
186
+ the default is to continue.
187
+
188
+ ## The flush is not a new document
189
+
190
+ Flushing means **making the artifacts that already exist true**:
191
+
192
+ - the build ledger — every completed task carrying its `complete` line;
193
+ - the carry-over ledger — everything deferred, dropped or half-done;
194
+ - the brief's REQ statuses;
195
+ - the task list.
196
+
197
+ It does **not** mean writing a summary for the compactor. A summary is a fourth
198
+ copy of the truth, it is written once, nobody updates it, and the next run reads
199
+ it as current. The artifacts above are read by later stages anyway; making them
200
+ right costs nothing extra and pays twice.
201
+
202
+ ## Rationalizations
203
+
204
+ | Excuse | Reality |
205
+ |---|---|
206
+ | "The operator obviously wants it to keep going, I'll just loop" | Default off. Silence arms nothing — the same floor deploy authorization uses. Ask once at preflight, or read `run.loop`. |
207
+ | "The mode is on, so I can push the deploy through" | The mode collapses check-ins, never gates or outward acts. A generic flag is not a specific authorization. |
208
+ | "I'll tell it to keep going and it will" | On Claude Code, prose does not survive the turn boundary. Either a job is scheduled or the run stops; say which. |
209
+ | "A one-minute interval is closest to no pause" | The interval must be longer than a typical item, or every fire lands on work already in progress and buys nothing. |
210
+ | "The ledger protects me from mid-task fires" | The scheduler not firing mid-query protects you. The ledger covers context loss. Confusing them is how the real protection gets deleted. |
211
+ | "It's still looping while we wait for approval" | A loop firing into a manual gate is a nag, and a nagged operator stops reading. Cancel on parking, re-arm with the go. |
212
+ | "Context feels tight, I should warn them" | Feels is not evidence. Without a harness signal or the operator's word, the warning is a guess wearing the clothes of a measurement. |
213
+ | "I'll write a handoff summary before compaction" | Update the ledgers instead. A summary is a copy of the truth that nobody maintains. |
214
+ | "One more task will fit" | If it does not fit, its middle is what you lose — and half a task is the most expensive state there is. |
@@ -195,6 +195,14 @@ nobody read is exactly the document nobody updated.
195
195
 
196
196
  **Build it in five steps** (stage 0; extend it whenever a new doc class appears):
197
197
 
198
+ 0. **Write the meta-row first: *a new document or rule*.** The most frequent change
199
+ in any documented project is adding a document, and it is the row nobody writes —
200
+ so the matrix ends up unable to catch the class it will meet most often. Its
201
+ *Update these* column is every surface that must **learn the thing exists**: the
202
+ index a reader opens, the map, any manifest, the agent-facing rules file.
203
+ Measured on the project this practice comes from: **nine findings across five
204
+ audits were that one missing row**, and the checks were green throughout, because
205
+ a check can only walk the list it was given.
198
206
  1. List the project's doc classes — one line each: what is this the home of?
199
207
  2. For each **change type** the project can undergo, name every document that must
200
208
  move.
@@ -140,6 +140,7 @@ explicit "stop and ask me here":
140
140
  | Stage | What to settle up front |
141
141
  |---|---|
142
142
  | run-wide | the model decision ([`model-tiering.md`](model-tiering.md)); what to decide autonomously vs escalate |
143
+ | run-wide Pacing | the **run mode** ([`continuity.md`](continuity.md)): does the run advance item-by-item with no check-in between items, and on what interval? Read `pipeline.json` → `run.loop` first — a recorded mode is the answer and is not re-asked. **Absent, it is off**: recommend it, take the answer, record it. It never collapses a `manual` gate or an outward act, so this row buys pacing, not authorization |
143
144
  | 0 Harvest | doc sources beyond this repo — other repos, hosted doc systems, the knowledge wiki, **the code graph** ([`knowledge-graph.md`](knowledge-graph.md): built / installed-not-built / absent) — and whether stage 9 may write to them (another repo is outward: propose + PR, never a direct push) |
144
145
  | 0 Setup audit | doc map absent or stale: run the entry audit over the existing documentation before building on it ([`setup.md`](setup.md))? Asked once; a refusal is recorded and never re-asked |
145
146
  | run-wide Escalation | cost of being wrong: decide alone while it stays inside the repository and reversible; escalate price, legal posture, promise, money, reputation, irreversible outward acts. Project exceptions? |
@@ -51,6 +51,8 @@ a row pointing outside the bundle is the defect this file exists to catch.
51
51
  | The entry audit and what it inspects | `references/setup.md` |
52
52
  | The ladder, seams, axis rotation, ratchets | `references/audit.md` |
53
53
  | Loop detection and its caps | `references/loop-guard.md` |
54
+ | **The run mode** — item-by-item pacing, default off, what it never collapses | `references/continuity.md` |
55
+ | **The context budget** — the evidence rule and what a flush actually updates | `references/continuity.md` |
54
56
  | The retro: prune, cap, commits, archive | `references/retrospective.md` |
55
57
  | Rules earned by failure | `references/learned.md` |
56
58
  | **The routing default and its boundary** | `templates/routing-rule.md` |
@@ -43,7 +43,9 @@ Seven passes, cheapest first. Each either reports `ok`, a finding, or **`skipped
43
43
  3. **Propagation.** Every document named in an entry's `Consequences / affects:` line
44
44
  cites that entry — ratcheted, so history is a printed number and not a wall of
45
45
  failures ([`adoption.md`](adoption.md) → *Baseline the ratchets*).
46
- 4. **The matrix.** Every row has a *Checked by* cell a check, or `review` **with the
46
+ 4. **The matrix.** It contains the **meta-row** *a new document or rule* without
47
+ which it cannot catch the change type the project makes most often. Every row has
48
+ a *Checked by* cell — a check, or `review` **with the
47
49
  reason no check can decide it**. An empty cell is a finding, not a blank.
48
50
  5. **Terms.** Every term the doc map declares resolves to exactly one definition, and
49
51
  the definition's home actually contains it. **Only declared terms are checked** —
@@ -131,6 +131,13 @@ never that the work was skipped quietly.
131
131
  calls) and the **autonomy sweep** that pre-resolves every stage-1→10 blocker.
132
132
  Deploy authorization has a hard floor there: a standing go counts only when it
133
133
  names the target and the preconditions.
134
+ - **The run mode is settled here too** ([`continuity.md`](continuity.md)): does
135
+ the run advance item-by-item with no check-in between items, and on what
136
+ interval? Read `pipeline.json` → `run.loop` first — a recorded mode is the
137
+ answer and is not re-asked; **absent, it is off**. It buys pacing, never
138
+ authorization: no loop mode collapses a `manual` gate or an outward act. The
139
+ same file carries the other half of pacing — the context budget, which fires
140
+ only on a harness signal or the operator's word, never on an estimate.
134
141
  - **UI early-detect:** one branch of the grill is always "does this touch a
135
142
  user-facing surface (web/mobile/CLI/TUI)?". If yes → surface **super-ux**
136
143
  now (use it if installed; otherwise give the install line — see SKILL.md
@@ -21,7 +21,7 @@ decision was made and *why* — not filling out sections.
21
21
  ## When this directory IS the register
22
22
 
23
23
  An ADR set and `docs/DECISIONS.md` are **two shapes of one decision home**, and a
24
- project has exactly one ([`../references/documentation.md`](../references/documentation.md)).
24
+ project has exactly one (the skill's own `references/documentation.md`).
25
25
  If `docs/adr/` already holds an `NNNN-*.md`, that is the register — record it in
26
26
  `docs/DOCMAP.md` and never seed a second home beside it.
27
27
 
@@ -117,6 +117,7 @@ is not neutral — it is a scheduled interruption.
117
117
  | run-wide | Model for this run | … (most capable available unless overridden; per-stage overrides here) |
118
118
  | run-wide Escalation | … | cost of being wrong: decide alone while it stays inside the repository and reversible; escalate price, legal posture, promise, money, reputation, irreversible outward acts. Project exceptions? |
119
119
  | run-wide | Decide autonomously vs escalate to me | … |
120
+ | run-wide Pacing | Run mode: item-by-item with no check-in between items, and on what interval? (the skill's `references/continuity.md`; read `pipeline.json` → `run.loop` first) | … (**absent ⇒ off**; it never collapses a manual gate or an outward act) |
120
121
  | 0 Harvest | Doc sources beyond this repo — other repos, hosted docs, the knowledge wiki, the code graph; and may stage 9 write to them? | … (another repo is outward: propose + PR, never a direct push; graph built / not built) |
121
122
  | 0 Setup audit | … (yes / no — recorded either way) | doc map absent or stale: run the entry audit over the existing documentation before building on it (the skill's `references/setup.md`)? Asked once; a refusal is recorded and never re-asked |
122
123
  | 0 Docs regime | Where settled things live (register or ADR set — one home, never both); who may write it; lease mechanism present, or is this run `ungated`? Gate command + ratchet floors; may this run raise a floor? | … |
@@ -47,7 +47,7 @@ is the true statement.
47
47
  - **The set may only shrink.** If it grew, the run log gets one sentence saying why.
48
48
  A ratchet that grows silently is a TODO with a better name.
49
49
  - **A finding class that appears twice stops belonging here** and becomes a check in
50
- the host's lint or CI ([`audit.md`](../references/audit.md) → *A class that
50
+ the host's lint or CI (the skill's own `references/audit.md` → *A class that
51
51
  repeats twice becomes a gate*). This ledger is for what cannot be automated, not
52
52
  for what nobody automated.
53
53
 
@@ -62,6 +62,7 @@ column is a finding, not a blank.
62
62
 
63
63
  | Change type | Update these | Checked by |
64
64
  |---|---|---|
65
+ | **A new document or rule** — start with this row | every surface that must *learn* it exists: the index a reader opens, the map, any manifest, the agent-facing rules file | `<the check, or `review` with its reason>` |
65
66
  | New/changed **decision** | `docs/DECISIONS.md` + every doc in its `Consequences / affects:` line | gate §5 propagation |
66
67
  | Question **resolved** | `docs/OPEN_QUESTIONS.md` → `Resolved→DEC-####`, the owning topic doc | gate §2 ids · gate §8 status vocabulary |
67
68
  | **Scope** change | `<roadmap>`, `<mvp>`, the register | review — scope is a judgement, not a shape |
@@ -69,6 +70,9 @@ column is a finding, not a blank.
69
70
  | `<user-facing behaviour>` | `<scenarios>` + `<flows>` + `<screens>`, same change | `<ux linter>` |
70
71
  | `<fill me>` | … | … |
71
72
 
73
+
74
+ **Start with the row above.** The most frequent change in any documented project is *adding a document*, and it is the row nobody writes — so the matrix ends up unable to catch the class it will meet most. On the project this practice comes from, nine findings across five audits were that one missing row.
75
+
72
76
  ## Gates
73
77
 
74
78
  | Gate | Command | When | Blocking? |
@@ -8,7 +8,7 @@ operator's configuration silently.
8
8
  raises the odds the model selects it and cannot make selection mandatory — the choice
9
9
  stays with the model, case by case. Only an instruction makes routing binding. That
10
10
  instruction therefore has to be *installed*, which is exactly how a workflow decision
11
- ends up living outside the bundle ([`../references/portability.md`](../references/portability.md)).
11
+ ends up living outside the bundle (the skill's own `references/portability.md`).
12
12
  Shipping it as a template is what lets it travel.
13
13
 
14
14
  **Keep the exclusions identical** to the skill's `description` and to the