task-pipeline-skill 1.93.2 → 1.94.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/CHANGELOG.md +151 -1
  2. package/README.md +42 -9
  3. package/SKILL-CARD.md +1 -1
  4. package/bin/task-pipeline.js +64 -33
  5. package/cursor/rules/task-pipeline.mdc +10 -5
  6. package/evals/RESULTS.md +1 -1
  7. package/evals/task-pipeline.evals.json +16 -0
  8. package/package.json +3 -3
  9. package/plugins/task-pipeline/.claude-plugin/plugin.json +1 -1
  10. package/plugins/task-pipeline/agents/verifier.md +4 -1
  11. package/plugins/task-pipeline/commands/task-pipeline.md +22 -8
  12. package/plugins/task-pipeline/hooks/memory-nudge.sh +45 -3
  13. package/plugins/task-pipeline/skills/evidence-docs/references/gates.md +6 -3
  14. package/plugins/task-pipeline/skills/evidence-docs/references/hooks.md +2 -1
  15. package/plugins/task-pipeline/skills/evidence-docs/references/retrospective.md +26 -1
  16. package/plugins/task-pipeline/skills/task-pipeline/SKILL.md +13 -11
  17. package/plugins/task-pipeline/skills/task-pipeline/graph.schema.json +89 -4
  18. package/plugins/task-pipeline/skills/task-pipeline/pipeline.schema.json +7 -0
  19. package/plugins/task-pipeline/skills/task-pipeline/references/backlog.md +25 -0
  20. package/plugins/task-pipeline/skills/task-pipeline/references/certification.md +45 -1
  21. package/plugins/task-pipeline/skills/task-pipeline/references/continuity.md +95 -26
  22. package/plugins/task-pipeline/skills/task-pipeline/references/deploy-targets.md +30 -4
  23. package/plugins/task-pipeline/skills/task-pipeline/references/doctrine-map.md +1 -0
  24. package/plugins/task-pipeline/skills/task-pipeline/references/gates.md +6 -3
  25. package/plugins/task-pipeline/skills/task-pipeline/references/grill.md +1 -1
  26. package/plugins/task-pipeline/skills/task-pipeline/references/hooks.md +2 -1
  27. package/plugins/task-pipeline/skills/task-pipeline/references/iteration.md +387 -0
  28. package/plugins/task-pipeline/skills/task-pipeline/references/knowledge-sources.md +1 -0
  29. package/plugins/task-pipeline/skills/task-pipeline/references/loop-guard.md +4 -1
  30. package/plugins/task-pipeline/skills/task-pipeline/references/portability.md +1 -0
  31. package/plugins/task-pipeline/skills/task-pipeline/references/retrospective.md +26 -1
  32. package/plugins/task-pipeline/skills/task-pipeline/references/stages.md +35 -11
  33. package/plugins/task-pipeline/skills/task-pipeline/references/waves.md +80 -36
  34. package/plugins/task-pipeline/skills/task-pipeline/references/work-graph.md +54 -5
  35. package/plugins/task-pipeline/skills/task-pipeline/scripts/backlog_sources.py +212 -0
  36. package/plugins/task-pipeline/skills/task-pipeline/scripts/context_packets.py +3 -3
  37. package/plugins/task-pipeline/skills/task-pipeline/scripts/graph.py +205 -22
  38. package/plugins/task-pipeline/skills/task-pipeline/scripts/lessons.py +1137 -0
  39. package/plugins/task-pipeline/skills/task-pipeline/scripts/stage_checkpoint.py +120 -15
  40. package/plugins/task-pipeline/skills/task-pipeline/scripts/waves.py +546 -0
  41. package/plugins/task-pipeline/skills/task-pipeline/templates/README.md +6 -0
  42. package/plugins/task-pipeline/skills/task-pipeline/templates/backlog-sources.schema.json +96 -0
  43. package/plugins/task-pipeline/skills/task-pipeline/templates/canvas.md +97 -0
  44. package/plugins/task-pipeline/skills/task-pipeline/templates/dossier.md +82 -0
  45. package/plugins/task-pipeline/skills/task-pipeline/templates/inventory.schema.json +94 -0
  46. package/plugins/task-pipeline/skills/task-pipeline/templates/lesson.schema.json +221 -0
  47. package/plugins/task-pipeline/skills/task-pipeline/templates/questions.md +45 -0
  48. package/plugins/task-pipeline/skills/task-pipeline/templates/retro.md +4 -0
  49. package/plugins/task-pipeline/skills/task-pipeline/templates/run.md +2 -2
@@ -27,19 +27,63 @@ almost no window left, loses the middle of it, and re-derives what it already di
27
27
 
28
28
  **The loop mode collapses discretionary check-ins. It collapses nothing else.**
29
29
 
30
- - A `manual` gate still waits for an explicit operator go. Always.
31
- - An outward or irreversible act — deploy, publish, opening a PR, creating or
32
- editing a shared design file — still needs its own authorization. A recorded
33
- loop mode is a **generic** flag, and a generic flag is not a specific
34
- authorization; that floor is set in [`grill.md`](grill.md) and this file does
35
- not lower it.
36
- - **Default off.** Absent config and absent instruction, the mode is off. Silence
37
- arms nothing, exactly as silence authorizes no deploy.
30
+ - A `manual` gate requires the operator's explicit go. A specific standing authorization
31
+ naming that gate's act is such a go; cite its source and scope in the gate record.
32
+ Without it, the gate waits. A generic instruction to continue is not authorization.
33
+ - An outward or irreversible act — deploy, publish, a tag or a release, sending to a
34
+ person, spending money, creating or editing a shared design file — still needs its own
35
+ **specific** authorization. A recorded loop mode is a **generic** flag, and a generic
36
+ flag is not a specific authorization; that floor is set in [`grill.md`](grill.md) and
37
+ this file does not lower it.
38
+ - **Pushing this repository's work and opening its pull request** is armed by a specific
39
+ standing authorization that names it — a recorded instruction to push the requested work
40
+ to the repository's own remote ([`build.md`](build.md) → *6. Integrate, then finish*).
41
+ Without one it waits for the go like the acts above. Another repository's PR is outward
42
+ every time ([`conventions.md`](conventions.md)).
43
+
44
+ **What arms the loop — exactly three sources, and the ledger says which.**
45
+ 1. `run.loop` in `pipeline.json` (Part 1);
46
+ 2. the operator's answer at preflight;
47
+ 3. **a standing instruction the host already carries** — an organisation's principle that
48
+ a free agent takes the next task, a global instruction file, a recorded decision.
49
+
50
+ The run cites its source once, in the ledger: `loop: armed by <source:line>`.
51
+ **Silence still arms nothing**: absent all three, the mode is off, exactly as silence authorizes no
52
+ deploy. A project with no such instruction behaves as it always did.
53
+
54
+ **What a watcher may do unasked.** A wait is not a stop: while a review, CI, a peer's
55
+ answer or a release run is pending, the run starts a watcher and takes the next independent
56
+ item (*Waits outlive turns*, below). When the wait clears, the watcher may take — **only
57
+ where a standing instruction names that class of act** — these steps: merge under the
58
+ repository's own integration policy, release a lease, rebase a stacked branch onto what
59
+ landed, notify. Deploy, publish, tag and sending to people stay gated unless a *specific*
60
+ standing authorization names them. A recorded "releases are the agent's" decision is one:
61
+ it names the act class — the tag, and the publish its release run performs — and, when it
62
+ names no repositories, it covers every repository its owner governs. It does not stretch to
63
+ a deploy or a message it does not name.
64
+
65
+ **Work that depends on a pending change is not blocked by it**: start it on a branch
66
+ stacked on the pending one, open its PR against that branch, and rebase or merge when the
67
+ pending change lands. **A watcher polls at the pace its wait changes** — a PR or a peer's
68
+ answer every one to two minutes, a release run while it runs, a scheduled time at that time
69
+ — and that pace is separate from the loop's `/loop` interval below, which paces items, not
70
+ waits.
38
71
 
39
72
  The mode's whole content is the removal of *"should I continue?"* between items
40
73
  the operator already asked for. Anything beyond that is a different decision,
41
74
  taken separately.
42
75
 
76
+ ### Waits outlive turns
77
+
78
+ A watcher started inside a session — a background loop, a monitor, a session cron —
79
+ dies with the session. **A wait that can outlive the session goes on a durable trigger**: a
80
+ launchd or systemd job, an `at` one-shot, a CI schedule, or a board row with a due time that
81
+ a session-start hook surfaces, where the host has one. Its one line — what it waits on and which trigger acts on it —
82
+ goes into the handoff or the board ([`backlog.md`](backlog.md)), not only into the chat,
83
+ because the chat is the one place the next session will not read. On Claude Code the
84
+ session-bound primitives are a `run_in_background` loop, a Monitor and `/loop`; on other
85
+ harnesses, a background process or the host's own scheduler.
86
+
43
87
  ## Part 1 — the loop
44
88
 
45
89
  **On, the run advances one item per iteration and does not ask between items.**
@@ -52,15 +96,21 @@ This spans the whole run, not one stage:
52
96
  - the acceptance → retro tail, which is where runs most often stall one step from
53
97
  finished.
54
98
 
55
- It stops for exactly four things: a `manual` gate, a block it cannot resolve, a
99
+ It stops for exactly four things: an unmet `manual` gate, a block it cannot resolve, a
56
100
  genuine ambiguity the brief does not answer, and completion.
57
101
 
58
- **A block or an ambiguity stops its node, not the run.** The node is parked with the
59
- question as its reason, marked `needs-operator` and answerable without context
60
- ([`prioritisation.md`](prioritisation.md) → *5. Where the human goes*), and the run
61
- continues on every node it does not block. The run itself stops only when the whole
62
- frontier is blocked — `graph.py next` exits `4` — and the questions are then asked
63
- together. **When the board is empty, say so once**, and do not invent work to fill it.
102
+ **A block or an ambiguity stops its node, not the run.** An ambiguity whose answer is
103
+ internal and reversible is not a stop at all: the run takes the recommended answer, records
104
+ it as **assumed** on the node, and continues ([`iteration.md`](iteration.md) → *Question
105
+ rounds*). Otherwise park the node with its actual reason and owner: only human-owned
106
+ questions are marked `needs-operator` and made answerable without context
107
+ ([`prioritisation.md`](prioritisation.md) → *5. Where the human goes*); external waits
108
+ get watchers, and project-owned questions go to the owning Project under
109
+ [`iteration.md`](iteration.md)'s board rule. The run continues on every node it does
110
+ not block. When the whole frontier is blocked — `graph.py next` exits `4` — classify the
111
+ recorded reasons: external waits go on watchers, human decisions go into the question
112
+ batch. Exit 4 does not prove a human gate or completion. A watcher keeps the recorded
113
+ next action alive while no independent node is runnable. **When the board is empty, say so once**, and do not invent work to fill it.
64
114
 
65
115
  **This extends [`build.md`](build.md); it does not replace it.** That file's
66
116
  *Continuous execution* rule governs the inside of a stage-5 execution — do not
@@ -84,8 +134,13 @@ and still leave the run picking its next move by recollection — which is the f
84
134
  nodes and nothing else. It is preferred over the two below for one measured reason — a
85
135
  400-node graph and a 4-node graph produce the same 27-byte frontier, so the cost of knowing
86
136
  what is next does not grow with the programme. `run.loop.queue: work-graph` records it, and
87
- `next`'s exit codes are what the loop branches on: `3` is *every node is done*, `4` is
88
- *what remains is blocked or parked*, and those are different endings.
137
+ `next`'s exit codes are what the loop branches on: `3` is *every node is terminal*
138
+ (including deliberately parked nodes), `4` retains another unresolved barrier, and
139
+ `6` means recorded watched waits hold every remaining dependency leaf. On 6, keep
140
+ the recorded watchers armed and take independent work; it is neither completion
141
+ nor a new human gate. `graph.py wait` records the locator and `resume --wait-id`
142
+ resolves that exact wait; neither executes a watcher or grants authority. See
143
+ [`work-graph.md`](work-graph.md) → *Watched external waits*.
89
144
 
90
145
  **Otherwise the queue is the module map** ([`decomposition.md`](decomposition.md)) when the brief
91
146
  was a platform, and the plan's task list otherwise. Both already exist and both are
@@ -97,6 +152,10 @@ stage 2** and the run says so in one line. It is not asked for at that point, fo
97
152
  same reason the mode is recorded rather than requested: re-asking would rebuild the habit
98
153
  the config exists to retire.
99
154
 
155
+ **A standing instruction the host carries counts as recorded** (*The limit, before the
156
+ capability*, source 3): it arms at the close of stage 2 like `run.loop`, unless the
157
+ instruction itself says otherwise, and the ledger cites it.
158
+
100
159
  **Where nothing is recorded, nothing arms.** Silence arms nothing here too — this section
101
160
  moves *where* a recorded mode is armed, from preflight to the close of stage 2. It does
102
161
  not make arming unconditional, and a reader who takes it that way would arm a loop in a
@@ -104,7 +163,8 @@ project with no `pipeline.json` at all. That reading was in this section's first
104
163
  an independent reader found it before it shipped.
105
164
 
106
165
  **What arming does NOT change, and this is load-bearing:** the four stops are the four
107
- stops. A `manual` gate still waits. An outward or irreversible act still needs its own
166
+ stops. A `manual` gate waits unless a specific standing authorization already names
167
+ its act, cited with its source and scope. An outward or irreversible act still needs its own
108
168
  specific authorization — *a generic flag is not a specific authorization*, and arming a
109
169
  queue is the most generic flag there is. Arming decides only that the run does not stop
110
170
  to ask *"shall I take the next one?"*.
@@ -293,10 +353,12 @@ true.
293
353
 
294
354
  ## What happens at the signal
295
355
 
296
- The four acts above, in order, and one prohibition: **do not begin an item you
297
- cannot finish inside what is left.** When the next item is plainly too large,
298
- say so and take the smaller thing that fits — closing a ledger, writing a decision
299
- that is already settled, updating a REQ status.
356
+ The four acts above, in order, and one prohibition: **no new item starts.** This is the one
357
+ carve-out from "take the next task in the same turn": **at the compaction signal, finish the
358
+ current unit and write the next task into the handoff** — the ledger's next line, the board
359
+ row — **instead of starting it.** Until compaction, the only writes are to what already
360
+ exists: the ledger, the plan, the decisions already settled, the REQ statuses. The next
361
+ turn, after compaction, takes the written task from there.
300
362
 
301
363
  If the project has recorded that it must not cross a compaction mid-stage, stop at
302
364
  the stage boundary instead and hand off. That is a project answer, not a default:
@@ -318,6 +380,11 @@ right costs nothing extra and pays twice.
318
380
 
319
381
  ## Part 3 — workflow memory at the stage boundary
320
382
 
383
+ Project Observatory is a separately installed, public engine:
384
+ [passioncode-ai/project-observatory-dashboard](https://github.com/passioncode-ai/project-observatory-dashboard)
385
+ — its README's *Install* and *MCP* sections say how to run it and connect it. Without it,
386
+ everything below degrades to one ledger line and the run continues.
387
+
321
388
  Which of the five handoff mechanisms carries what — the Git record, Observatory's lease
322
389
  and checkpoint, a host's launch context, the inbound queue — and the order a successor
323
390
  reads them in, has one home:
@@ -333,9 +400,9 @@ checkpoint**, and the next executor continues from the last finished stage.
333
400
  - **How.** `scripts/stage_checkpoint.py emit` prints the tool's arguments, built from the ledger alone: the topic, the verdicts, the next stage, the operator's constraints and key names. Pass them to `observatory_checkpoint_write`, or to `memory.checkpoint.write` under memory/0.1. Then hand the answer to `stage_checkpoint.py record --answer -`.
334
401
  - **The constraints.** Give the brief's restrictive rules once, as `--constraint`. They are carried to every later boundary, and a successor reads them first.
335
402
  - **Keys.** Pass keys by name, as `--credential PROJECT/ENV/NAME`, never as a value.
336
- - **Without the tools.** `stage_checkpoint.py record --unavailable "<why>"` appends one `event: memory — unavailable` line, and the run continues exactly as before. Missing memory is a state the ledger names, not a failure.
337
- - **A planned change of executor** — a quota running out, a route moving the work to another model or account. `stage_checkpoint.py handoff --to-provider <p> [--to-model <m>] --reason limit|plan_route|operator` prints `observatory_handoff_create`'s arguments; `record --answer -` keeps the offer as one ledger line, and the lease stays with this run until the successor accepts. The successor runs `stage_checkpoint.py accept --handoff-id <id>` → `observatory_handoff_accept` → `record --answer -` **before its first write**, and obeys the constraints the answer carries first. `LeaseLost` is then left for the race nobody planned.
338
- - **The reminder.** `hooks/memory-nudge.sh` (PostToolUse) reads the ledger after each tool call and, once per `stage:` line with no `event: memory` line after it, puts one sentence in front of the model naming the two commands above. It decides nothing and blocks nothing; adoption measured before it was one write in 293 sessions.
403
+ - **Without the tools.** `stage_checkpoint.py record --unavailable "<why>"` appends one `event: memory — unavailable` line, and the run continues exactly as before. Missing memory is a state the ledger names, not a failure. When the tools are absent for the whole run — no Observatory on this machine — say it **once**: `record --unavailable "<why>" --for-run` appends one `unavailable for this run` line and leaves a marker in `.task-pipeline/memory.json`; no later gate is nudged or needs a line. Any later `record --answer` (the tools came back) clears the marker.
404
+ - **A planned change of executor** — a quota running out, a route moving the work to another model or account. `stage_checkpoint.py handoff --to-provider <p> [--to-model <m>] --reason limit|plan_route|operator` prints `observatory_handoff_create`'s arguments; `record --answer -` keeps the offer as one ledger line, and the lease stays with this run until the successor accepts. The successor runs `stage_checkpoint.py accept --handoff-id <id>` → `observatory_handoff_accept` → `record --answer -` **before its first write**, and obeys the constraints the answer carries first. `LeaseLost` is then left for the race nobody planned. A retried offer keeps its idempotency key until a memory event (a checkpoint, a refusal, a recorded offer — never `unavailable`) is appended, so a `gate:` or `stage:` line between retries does not turn it into a new offer that replaces the unaccepted one.
405
+ - **The reminder.** `hooks/memory-nudge.sh` (PostToolUse) reads the ledger after each tool call and, once per `stage:` line with no `event: memory` line after it, puts one sentence in front of the model naming the two commands above — unless the run-level marker says memory is unavailable for this run, in which case it stays silent. The first reminder of a run also says where Observatory comes from, once. It decides nothing and blocks nothing; adoption measured before it was one write in 293 sessions.
339
406
  - **A refusal.** `LeaseLost` means another executor holds the workflow now. The script drops the token. Read the workflow (`observatory_checkpoint_latest` with `stage_checkpoint.py state`'s id) before doing anything else. A stale writer stops after one refusal.
340
407
  - **The lease token.** It lives in `.task-pipeline/memory.json` (mode 0600, git-ignored) and never in the ledger, a reply or a commit.
341
408
  - **What this is not.** Not a second ledger and not the narrative. The checkpoint is the work's state for the next executor. The wiki and the ledger keep everything else.
@@ -344,7 +411,9 @@ checkpoint**, and the next executor continues from the last finished stage.
344
411
 
345
412
  | Excuse | Reality |
346
413
  |---|---|
347
- | "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`. |
414
+ | "The operator obviously wants it to keep going, I'll just loop" | Default off. Silence arms nothing — the same floor deploy authorization uses. Arm from `run.loop`, the preflight answer, or a standing instruction the host carries, and cite which in the ledger. |
415
+ | "The watcher can push the release through when CI goes green" | A watcher takes only the act classes a standing instruction names — merge, release a lease, rebase, notify. A tag or a deploy needs its own specific authorization. |
416
+ | "My background loop will catch it tomorrow" | It dies with the session. A wait that can outlive it goes on a durable trigger, and its line goes into the handoff. |
348
417
  | "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. |
349
418
  | "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. |
350
419
  | "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. |
@@ -165,6 +165,16 @@ shipped — and it is exactly what the stage-8 gate is for.
165
165
 
166
166
  ### When the release waits for an approval
167
167
 
168
+ **Establish the authority for the act separately from the approval mode.** Optional
169
+ `release.authorized_by` records a single-line source locator, such as a committed
170
+ `source:line`, for the standing grant covering the tag and publication. A locator
171
+ is not authorization: read its source and verify the issuer's authority, the grant's
172
+ currentness and its exact act and scope. A missing, unreadable or ambiguous source
173
+ cannot establish a grant. If the field is absent, inspect existing recorded authority
174
+ before asking; neither field presence nor `approval: checks` supplies permission.
175
+ Human-only actions remain human, and a release grant does not authorize a separate
176
+ deployment or message it does not name.
177
+
168
178
  **Read the project's approval mode before tagging, and do not guess it.** It is one of
169
179
  two, and each owes the operator something different.
170
180
 
@@ -172,8 +182,11 @@ two, and each owes the operator something different.
172
182
  `release-guard` checks that the tag is on main and that CI on that commit is green,
173
183
  and the `release` environment has no reviewers. PassionCode products declare this in
174
184
  `passioncode-ai/.github` `release-signing/products.json` (`"approval": "checks"`).
175
- Push the tag, watch the run selected **by the tag you pushed**, and report what was
176
- published, or the guard's refusal and its cause. A refusal is fixed at its cause,
185
+ Push the authorized tag and put the run selected **by that tag** on a watcher.
186
+ Follow [`continuity.md`](continuity.md) → *Waits outlive turns*: take independent work
187
+ meanwhile, and use a durable trigger if the wait may outlive the session. On success,
188
+ continue stage 8 on the published artefact and report; on failure, report the cause.
189
+ A refusal is fixed at its cause,
177
190
  never worked around. Send no approval request: there is nobody to send it to.
178
191
  - **`reviewers`** — the run stops at an environment with required reviewers. Find that
179
192
  run by the tag, and confirm its status is `waiting` before saying anything:
@@ -184,7 +197,11 @@ two, and each owes the operator something different.
184
197
 
185
198
  Then hand the operator the **direct link** to that run, where they press *Review
186
199
  deployments*, together with the tag and the jobs that are waiting. A request without
187
- the link is incomplete, and so is a link to a run that is not waiting.
200
+ the link is incomplete, and so is a link to a run that is not waiting. Put that run
201
+ on a watcher that continues stage 8 after approval and successful publication. Where
202
+ standing host instructions name an approval-notification channel, send the same link
203
+ there with a stable event id per repository/tag/run. An unavailable channel is reported;
204
+ it is not a reason to invent another recipient or omit the direct link.
188
205
 
189
206
  The mode comes from, in order:
190
207
  1. `pipeline.json` → `release.approval`;
@@ -204,7 +221,7 @@ A run that cannot establish the mode says so. It does not assume `checks`.
204
221
 
205
222
  ## The verification trio
206
223
 
207
- Whatever the platform, stage 8's gate needs the same three, and all three:
224
+ For a served application, stage 8's gate needs the same three, and all three:
208
225
 
209
226
  1. **Process/deployment state** — is the new version the running version
210
227
  2. **Runtime logs** — clean boot, no error spike
@@ -213,3 +230,12 @@ Whatever the platform, stage 8's gate needs the same three, and all three:
213
230
  One or two of the three is where "deployed successfully" gets said about a
214
231
  service that is crash-looping. If any of the three cannot be obtained, that is
215
232
  the honest degradation report the gate asks for — not a reason to call it green.
233
+
234
+ **Installed artefacts use their consumer boundary.** For a package, plugin, skill or CLI,
235
+ verify the registry's published version; refresh existing installations within the
236
+ authorized rollout through the owner's update path, then read back their actual versions
237
+ and installed payloads. Read the update/runtime diagnostics and run the supported consumer
238
+ smoke check for each claimed channel. A registry version alone does not prove an installed
239
+ update, and readable files do not prove native discovery or model/task quality. If a channel
240
+ cannot be checked, name it and leave its acceptance open. Do not invent a server health
241
+ URL or clean-boot log for a target that has neither.
@@ -28,6 +28,7 @@ UX track on a user-facing task.
28
28
  | 2 Brainstorm | `references/brainstorm.md` |
29
29
  | 2 Decompose (platforms only) | `references/decomposition.md` |
30
30
  | 0–10 · **wave mode** — the whole board: 0–4 once, 5–8 per wave, 9–10 to close | `references/waves.md` |
31
+ | 0–10 · **release iteration** — the loop around the waves: dossiers, integration, question rounds, checks as nodes land, release, post-release check, next pool, the shared lesson store | `references/iteration.md` |
31
32
  | 3 Spec | `references/spec.md` |
32
33
  | 4 Plan | `references/planning.md` |
33
34
  | the queue the loop walks | `references/work-graph.md` |
@@ -50,12 +50,14 @@ From [`../pipeline.schema.json`](../pipeline.schema.json), one per stage:
50
50
  |---|---|---|
51
51
  | `auto` | the orchestrator verifies the `check` itself, pass/fail, and stops on fail | advancing on an unverified check |
52
52
  | `judgment` | somebody **rules** on it, because no complete deterministic check exists; the gate names its `judge` | recording the ruling in the slot reserved for what a machine established |
53
- | `manual` | wait for the operator's **explicit** go | treating an auto verification as the approval |
53
+ | `manual` | the operator's **explicit** go, or specific standing authorization naming the act | treating an auto verification as the approval |
54
54
 
55
55
  **An auto gate never substitutes for a required manual approval.** A green table is
56
56
  not the operator confirming it is what they asked for, and no amount of checking
57
57
  makes it one. Which stages are manual is the **operator's** decision, recorded in
58
58
  their `pipeline.json`; the framework fixes no stage count and no gate assignment.
59
+ A standing authorization is cited with its source and scope, not inferred from a generic
60
+ loop flag ([`continuity.md`](continuity.md) → *The limit, before the capability*).
59
61
 
60
62
  **That sentence is about the pipeline's SHAPE, and nothing else.** It says a project
61
63
  chooses how many stages it runs and which of them wait for a person. It does not say the
@@ -495,8 +497,9 @@ run:
495
497
  what it does not cover, stated, beats two measurements and no decision.
496
498
 
497
499
  **This never licenses skipping a gate.** The gates are the floor, and the floor is
498
- not proportionate to anything — a `manual` gate waits, `unknown` fails stage 10, and
499
- a green nobody watched fail is not evidence at any blast radius. What is
500
+ not proportionate to anything — a `manual` gate waits without an explicit go or a
501
+ specific standing authorization naming its act, cited with source and scope;
502
+ `unknown` fails stage 10, and a green nobody watched fail is not evidence at any blast radius. What is
500
503
  proportionate is the work *above* the floor: how many axes, how many passes, how
501
504
  much of the corpus. Cutting the floor to go faster is not speed; it is the failure
502
505
  this whole file exists to prevent, arriving on schedule.
@@ -168,7 +168,7 @@ explicit "stop and ask me here":
168
168
  | Stage | What to settle up front |
169
169
  |---|---|
170
170
  | run-wide | the model decision ([`model-tiering.md`](model-tiering.md)); what to decide autonomously vs escalate |
171
- | 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 |
171
+ | 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? Three sources arm it: `pipeline.json` → `run.loop` (read first — a recorded mode is the answer and is not re-asked), this answer, or a standing instruction the host already carries; the ledger cites which as `loop: armed by <source:line>`. **Absent all three, 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 |
172
172
  | 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) |
173
173
  | 0 Duplicates | for every artifact the build reads — a Dockerfile, a schema, a lockfile, a spec — **which copy does the consumer actually name**. Quoted from the workflow or the Makefile, not inferred from the tree: the copy that ships is often not the copy people open (`learned.md` rule 20) | the consumer line, quoted |
174
174
  | 0 Fixtures | what **persists between runs** on this machine — a database, a volume, a cache, generated files — and the command that recreates it from nothing. A suite green against accumulated state carries a premise that is false on every runner (`learned.md` rule 18) | the recreate command, stated |
@@ -219,7 +219,8 @@ Since v1.50.0 the plugin carries hooks of its own. `hooks/release-gate.sh`
219
219
  tag push, `gh release create`, `npm publish` — while the run says the suite has not
220
220
  passed. `hooks/gate-observer.sh` (`PostToolUse` and `PostToolUseFailure`) records
221
221
  what the declared gate command actually did. `hooks/memory-nudge.sh` (`PostToolUse` on `Bash|Edit|Write|MultiEdit`) reminds,
222
- once per returned gate, that no workflow-memory line follows it
222
+ once per returned gate, that no workflow-memory line follows it — unless the run recorded
223
+ memory unavailable with `--for-run`
223
224
  ([`continuity.md`](continuity.md), Part 3).
224
225
 
225
226
  **Two lessons from v1.50.0, both shipped as defects and both fixed in v1.51.0.**