@deftai/directive-content 0.103.0 → 0.105.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.
Files changed (35) hide show
  1. package/Taskfile.yml +13 -6
  2. package/UPGRADING.md +4 -0
  3. package/coding/coding.md +2 -2
  4. package/commands.md +28 -8
  5. package/docs/directive-lifecycle.md +12 -4
  6. package/docs/project-invariants.md +79 -0
  7. package/docs/scope-provenance.md +53 -8
  8. package/docs/writing-ste100.md +38 -4
  9. package/main.md +2 -0
  10. package/meta/ralph.md +1 -1
  11. package/package.json +1 -1
  12. package/packs/rules/rules-pack-0.1.json +3 -3
  13. package/packs/skills/skills-pack-0.1.json +15 -9
  14. package/scm/github.md +34 -1
  15. package/skills/deft-directive-build/SKILL.md +26 -1
  16. package/skills/deft-directive-gh-slice/SKILL.md +2 -2
  17. package/skills/deft-directive-refinement/SKILL.md +8 -6
  18. package/skills/deft-directive-review-cycle/SKILL.md +37 -11
  19. package/skills/deft-directive-setup/SKILL.md +2 -0
  20. package/skills/deft-directive-swarm/SKILL.md +21 -5
  21. package/skills/deft-directive-swarm/references/core-ops.md +3 -1
  22. package/skills/deft-directive-swarm/references/core-phase-0.md +1 -0
  23. package/skills/deft-directive-swarm/references/core-phase-3.md +1 -1
  24. package/skills/deft-directive-swarm/references/core-phase-4.md +27 -11
  25. package/skills/deft-directive-swarm/references/core-phase-5-6.md +4 -1
  26. package/skills/deft-directive-sync/SKILL.md +9 -11
  27. package/tasks/engine.yml +2 -0
  28. package/tasks/occupancy.yml +17 -0
  29. package/tasks/scm.yml +13 -7
  30. package/tasks/vbrief.yml +3 -2
  31. package/tasks/verify.yml +32 -2
  32. package/tasks/xbrief.yml +43 -0
  33. package/templates/agent-prompt-preamble.md +22 -3
  34. package/templates/agents-entry.md +9 -2
  35. package/vbrief/schemas/vbrief-core.schema.json +72 -0
package/scm/github.md CHANGED
@@ -419,11 +419,27 @@ Following a v1.0.0 release, commits:
419
419
 
420
420
  ! **Anti-thrash during attributed platform outage:** After thrash caps (max 2 re-triggers per #3167), stop automatic empty-commit / close-reopen / rebase loops. Remediation is wait + re-probe HEAD check-runs, not inventing workflow edits to "fix" a global outage.
421
421
 
422
+ ### Forge-outage drop-back + human report (#3422)
423
+
424
+ #3167 caps CI-holdout babysit loops. #3180 attributes weather holds. Neither replaces this drop-back.
425
+
426
+ ! When a worker or parent detects a **forge / SCM API outage** — any of: repeated 429/502/503 on REST (`gh api` / `ghx api`); status page `partial_outage` / `major_outage` on API, PRs, Issues, Actions, or Webhooks (#3180 probe); operator standing order that the web/API is unreliable; widespread empty check-runs + `attribution: platform` — then:
427
+
428
+ 1. **Drop back** — stop empty-commit, close/reopen, rebase-to-nudge, tight `pr:watch` / `gh run watch`, GraphQL, and new heartbeat / poller children. Local edit/test/commit MAY continue when it does not need the forge.
429
+ 2. **Report once** to the human in the conversation (not a GitHub comment that may also fail). Include: what is down, attribution/incident if known, what is parked, next probe time. Do not re-spam every tick unless status *changes*.
430
+ 3. **Re-probe on a timer.** Resolve minutes via `task policy:show --field=forgeOutageRetryMinutes` (USER.md Personal wins over `plan.policy.forgeOutageRetryMinutes` over **30**; minimum 5). One probe per interval. If still out, stay dropped and (at most) a short "still out, next probe at T" note. If recovered, resume GitHub I/O from the parked point — do not replay the thrash loop.
431
+
432
+ Session / envelope standing orders (this-cohort "use 15m") MAY override one run but MUST NOT become the undocumented product default.
433
+
434
+ ⊗ Tight retry loops "until it works."
435
+ ⊗ Empty-commit / close-reopen to "wake" CI during an attributed platform outage (still bound by #3167 caps if a probe happens before attribution).
436
+ ⊗ Invent a new interval every session.
437
+ ⊗ Send the human to github.com / githubstatus.com as the only remediation.
422
438
  ⊗ Merge or `--skip-ci` solely because a status page is red — status is **attribution for wait/thrash policy**, not a second branch-protection oracle (#3180 non-goal).
423
439
  ⊗ Blame Blacksmith when status pages show GitHub Actions/Webhooks major outage and Blacksmith runners themselves operational.
424
440
  ⊗ Edit workflows or re-push thrash to "fix" a documented global Actions/webhook outage without status-page probe.
425
441
 
426
- **BLOCKED handoff fields** (extend `BLOCKED: ci_weather` in review-cycle): `platform_status_github`, `platform_status_blacksmith`, optional incident URL, `attribution: platform | capacity | repo_config | unknown`. Cross-links: #3167 (weather codes), #3168 (failover arms), #2672 (capacity stall), #2688 (Greptile CLEAN + CI holdout ownership).
442
+ **BLOCKED handoff fields** (extend `BLOCKED: ci_weather` in review-cycle): `platform_status_github`, `platform_status_blacksmith`, optional incident URL, `attribution: platform | capacity | repo_config | unknown`. Cross-links: #3167 (weather codes), #3180 (status attribution), #3168 (failover arms), #2672 (capacity stall), #2688 (Greptile CLEAN + CI holdout ownership).
427
443
 
428
444
  **Security**:
429
445
  - ! Use GitHub Secrets for CI/CD credentials
@@ -431,6 +447,23 @@ Following a v1.0.0 release, commits:
431
447
  - ~ Keep secrets in `secrets/` dir locally (gitignored)
432
448
  - ~ Rotate secrets regularly
433
449
 
450
+ ## Default-branch sync (`scm:sync-default`, #3391)
451
+
452
+ `task scm:sync-default` opens dest-targeted sync PRs from typed `baseBranch` to `deliveryBranch`. It consumes the shared branch-sync detector (#3388) and `plan.policy.syncMaxFiles` (#3390, default 400; `--max-files` overrides one run).
453
+
454
+ - Dest = `deliveryBranch`. Source = typed `baseBranch`. Equal or unset source is a no-op.
455
+ - Under the file-count limit: one new PR from the source tip to dest.
456
+ - Over the limit: cut at merge commits when possible so each dest-targeted leg is at or under the threshold. Each leg is a **new branch and a new PR**. After a leg merges, run the verb again; the next leg is still a new PR.
457
+ - ! Each leg must be new when the reviewer first sees it.
458
+ - ⊗ `gh pr edit --base` or close-reopen of an oversized sync PR. Greptile does not re-review on base-only moves.
459
+ - Required checks stay on. The only exemption is the Wave 1 core-guard sync predicate (#3388).
460
+ - No-op when the shared detector says this is not a sync.
461
+
462
+ ```bash
463
+ task scm:sync-default -- --dry-run
464
+ task scm:sync-default -- --max-files 100
465
+ ```
466
+
434
467
  ## Branch Protection
435
468
 
436
469
  **Recommended settings** for `main`:
@@ -143,6 +143,12 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
143
143
  Phase 1 before continuing -- do not proceed without user preferences
144
144
  - ! Once USER.md exists, continue with the Cost Phase Gate below
145
145
 
146
+ ### Forge-outage drop-back (#3422)
147
+
148
+ ! On attributed platform outage or repeated REST 429/502/503 during YOLO / through-merge implement: drop GitHub I/O, report once to the human in chat, and re-probe on `plan.policy.forgeOutageRetryMinutes` (default **30**; USER.md Personal wins; min 5; `task policy:show --field=forgeOutageRetryMinutes`). Local edit/test/commit MAY continue. Depth: [`scm/github.md`](../../scm/github.md) § #3180 / #3422. Complements #3167 / #3180.
149
+
150
+ ⊗ Tight retry, empty-commit thrash, or sending the human to github.com as the only remediation.
151
+
146
152
  ## Cost Phase Gate (#739)
147
153
 
148
154
  ! Before proceeding to File Reading, verify the project has gone through the
@@ -411,7 +417,7 @@ Read full files when you need detail:
411
417
 
412
418
  - ! TDD: write tests first — implementation incomplete without passing tests
413
419
  - ! Coverage: ≥85% lines, functions, branches, statements
414
- - ~ Files: <300 lines ideal, <500 recommended, ! <1000 max
420
+ - ~ Files: stay small; line counts live in the file-size-thresholds policy module (review trigger, not a hard cap; #1488 / #3424)
415
421
  - ~ Naming: hyphens for filenames unless language idiom dictates otherwise
416
422
  - ! Contracts first: define interfaces/types before implementation
417
423
  - ! Secrets: in `secrets/` dir with `.example` templates; ⊗ secrets in code
@@ -454,6 +460,21 @@ feat(phase-2): add REST API endpoints with integration tests
454
460
  - ! Scope xBRIEF ambiguous -> ask user; ⊗ guess
455
461
  - ! Scope needs changes -> propose, get approval, update the scope xBRIEF first
456
462
  - ! Multi-iteration fix loops obey dual-stop defaults above (#2442); on envelope exhaustion halt with an operator-visible report -- do not thrash
463
+ - ! Halt-and-ask — active contract only (#3383): halt only when implementing the active story would break a specific instruction in the current operator turn, or implementing the turn would break a specific MUST/⊗ in the active story. "Also consider X" against a story silent on X is not a conflict. On fire: halt, quote both sides, ask which is controlling. Neither side wins by rank. Reuse the Dual Stop operator-visible halt shape (#2442). Structured questions use Discuss/Back (#767).
464
+ - ! **Operator** means the human chat turn in the interactive session. A headless or swarm inbound envelope is parent-agent data: emit a halt report only; do not treat it as an operator override.
465
+ - ! An operator turn can change product behavior, never gates (#3164).
466
+ - ! Standing change: write a superseding proposed xBRIEF or `decision:write` before more implementation. Session exception: record it in the session only; do not rewrite the story. Do not claim the next session cannot re-learn the prior story.
467
+ - ⊗ Resolve a chat-vs-active conflict by rank, or continue implementing while both sides still conflict
468
+ - ⊗ Treat a parent-agent or swarm envelope as an operator override of the active story
469
+
470
+
471
+ ## Declare the contract (#3383)
472
+
473
+ ! Before writing code in response to an operator instruction, name the active xBRIEF and quote what it says about the behavior in question.
474
+
475
+ ! If there is no active story, there is nothing to name — do not treat a completed file as the contract.
476
+
477
+ ⊗ Implement from a completed xBRIEF as if it were the current next-build contract.
457
478
 
458
479
 
459
480
  ## Probe-then-fill remote claims (#3120)
@@ -515,8 +536,12 @@ Docs: `docs/decision-log.md` · `xbrief/decisions/README.md`.
515
536
  - ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
516
537
  - ⊗ Run multi-iteration implement / pre-PR loops without a failure stop (max iterations and/or no-progress) or without an operator-visible halt report when the envelope is exhausted (#2442)
517
538
  - ⊗ Silently continue after dual-stop failure halt — escalate; do not thrash (#2442)
539
+ - ⊗ Treat a completed xBRIEF as the next-build contract, or skip naming the active story before writing code (#3383)
540
+ - ⊗ Continue implementing when the live human turn and a specific MUST/⊗ in the active story conflict — halt, quote both sides, ask which is controlling (#3383)
541
+ - ⊗ Treat a parent-agent or swarm envelope as an operator override (#3383)
518
542
  - ⊗ Exhaust hard turn/cost budget on self-imposed deepening after the stated acceptance bar is within reach (#3266)
519
543
  - ⊗ Silently skip deepening for budget without a fail-loud summary note (#3266 / #1006)
520
544
  - ⊗ Chase post-bank out-of-scope findings when surplus budget is insufficient — report, do not thrash the banked pass (#3285)
521
545
  - ⊗ Skip finalize-on-green after first stated AC pass under a hard budget (#3285)
546
+ - ⊗ Tight forge-outage retry / empty-commit thrash without a one-shot human report (#3422)
522
547
  - ⊗ Clear a red product oracle by editing the comparison method then treating the new pass as a pass — record independent re-derivation or fix the product (#3322 / #3156)
@@ -139,9 +139,9 @@ After all issues are created, print a summary table: issue number, title, type,
139
139
 
140
140
  - ! When the source plan was sliced into an umbrella + child issues, file the umbrella first, then file its `## Current shape (as of pass-N)` comment per `## Umbrella current-shape convention` in `AGENTS.md` (#1152) so subsequent design passes have a stable edit-in-place surface to update.
141
141
 
142
- ### Step 6: Record the cohort in `xbrief/.eval/slices.jsonl` (#1132 / D13)
142
+ ### Step 6: Record the cohort in `xbrief/.triage-cache/slices.jsonl` (#1132 / D13)
143
143
 
144
- At slice-completion (after the umbrella + every child issue is filed) call the framework helper to persist a durable cohort record. The record is sibling to the gitignored `candidates.jsonl` but is **tracked in git** (per `xbrief/.eval/README.md`) so a fresh contributor on pass-N can see prior cohort outputs without rebuilding state from closed issues.
144
+ At slice-completion (after the umbrella + every child issue is filed) call the framework helper to persist a durable cohort record. The record is sibling to the gitignored `candidates.jsonl` but is **tracked in git** (per `xbrief/.triage-cache/README.md`) so a fresh contributor on pass-N can see prior cohort outputs without rebuilding state from closed issues.
145
145
 
146
146
  ```python path=null start=null
147
147
  from pathlib import Path
@@ -229,16 +229,18 @@ The task emits xBRIEFs conforming to the canonical v0.6 schema (`xbrief/schemas/
229
229
  task reconcile:issues
230
230
  ```
231
231
 
232
- The task scans every xBRIEF with a GitHub-backed reference (whether the reference uses the legacy `github-issue` bare type or the canonical `x-xbrief/github-issue` shape), fetches each linked issue, compares timestamps and state, and reports items in four buckets:
232
+ The task scans every xBRIEF with a GitHub-backed reference (whether the reference uses the legacy `github-issue` bare type or the canonical `x-xbrief/github-issue` shape), fetches each linked issue, and reports items in these buckets:
233
233
 
234
- - **Linked & current** — origin has not changed since the xBRIEF was last updated (no action)
235
- - **Stale** — origin `updatedAt` is newer than the xBRIEF (propose an update)
234
+ - **Linked & current** — an open origin issue has a matching xBRIEF (no action)
236
235
  - **Externally closed** — origin issue is `CLOSED` (propose cancellation or reconcile if intentional divergence)
237
- - **Unlinked** — xBRIEF has no GitHub reference (flag for review)
236
+ - **Unlinked** — open GitHub issue with no xBRIEF (flag for review)
237
+ - **Completed-status drift** — a `completed/` brief whose `plan.status` is not terminal
238
+
239
+ `task reconcile:issues` does **not** compare origin `updated_at` to the brief `updated` timestamp. Origin **content** staleness is fail-closed at implementation intent: `task xbrief:preflight` exits 1 when the live issue is newer than `xBRIEFInfo.updated` (#3363).
238
240
 
239
241
  ### Step 2: Walk Flagged Items with the User
240
242
 
241
- 1. ! For each **stale** item the task surfaces, show the user the diff between the current xBRIEF and the refreshed origin. Propose edits; ! wait for explicit user approval before writing anything.
243
+ 1. ! When `task xbrief:preflight` (or a manual origin re-read) shows the live issue is newer than the brief, show the user the current xBRIEF against the origin body + comments (#2143). Propose a refresh **or** record intentional divergence and bump `xBRIEFInfo.updated`; ! wait for explicit user approval before writing anything. ⊗ Auto-write origin text onto the brief (#309 D12).
242
244
  2. ! For each **externally closed** item, ask the user whether to `task scope:cancel <file>` it or preserve intentional divergence.
243
245
  3. ! For each **unlinked** item, ask whether to attach an origin reference or leave the xBRIEF as-is.
244
246
 
@@ -337,7 +339,7 @@ The task scans every xBRIEF with a GitHub-backed reference (whether the referenc
337
339
 
338
340
  ~ Issue-label hygiene for any umbrella or child issue this skill files: before creating issues, inspect the target repo's existing labels with `gh label list` or the labels API; choose one or more suitable existing labels when practical, or explicitly note that no label was applied. This is a recommendation, not a gate -- do not block issue creation solely because no label fits, and do not invent ad hoc labels outside the repo's existing label set.
339
341
 
340
- ! When a refinement pass produces a slicing event (rare but possible -- e.g. a design pass on an existing umbrella files N additional Wave-N child issues), record the cohort in `xbrief/.eval/slices.jsonl` via `scripts/slice_record.py::write_slice(...)` with `actor="skill:refinement"` immediately after the children are filed (#1132 / D13). Same call shape as `skills/deft-directive-gh-slice/SKILL.md` Step 6. The cohort record is what makes `task triage:audit --orphans` able to detect Wave-2+ children whose umbrella closes prematurely; without it the production-side drift this surface guards against re-fires. Skip when the pass produced no new child cohort (e.g. a pure re-prioritization).
342
+ ! When a refinement pass produces a slicing event (rare but possible -- e.g. a design pass on an existing umbrella files N additional Wave-N child issues), record the cohort in `xbrief/.triage-cache/slices.jsonl` via `scripts/slice_record.py::write_slice(...)` with `actor="skill:refinement"` immediately after the children are filed (#1132 / D13). Same call shape as `skills/deft-directive-gh-slice/SKILL.md` Step 6. The cohort record is what makes `task triage:audit --orphans` able to detect Wave-2+ children whose umbrella closes prematurely; without it the production-side drift this surface guards against re-fires. Skip when the pass produced no new child cohort (e.g. a pure re-prioritization).
341
343
 
342
344
 
343
345
  ! When the umbrella + children were filed by hand (legacy `gh issue create` / `issue_write` MCP / prior pass-N runs that pre-date this skill's slicing phase), use the canonical retro verb `task slice:record-existing` (#1147 / N7) -- it wraps the same `slice_record.write_slice` helper with `actor="manual:operator"`, takes `--umbrella=N --children=A,B,C [--wave-N=...]` flags, validates each issue via the N5 / #1145 `scm.call` shim, and is idempotent on a matching umbrella + child set (re-run is a no-op; `--force` writes a second record for legitimate multi-session slicing). Companion `task slice:list` enumerates persisted slices for verification. The backfill verb is the canonical retro path for cohorts D13's writer never saw.
@@ -48,7 +48,8 @@ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
48
48
  - Operator asks to **babysit**, **shepherd**, or **watch** a PR -- including the Cursor product action **babysit-pull-request-in-cloud** (#2261 / #1862 intent-routing class)
49
49
  - A bot reviewer (Greptile) has posted findings on an open PR
50
50
  - Dispatching a cloud or background agent to monitor and resolve PR review findings until merge-ready
51
- - Operator re-authorizes after conf-hold / dual-stop residual: **pursue residual**, **follow-up hard-stop**, **same as conf-hold**, **continue dual-stopped PR**, or **re-babysit residual** — route to § Operator follow-up after dual-stop / hard stop (#3273)
51
+ - Operator re-authorizes after conf-hold / dual-stop residual: **pursue residual**, **follow-up hard-stop**, **same as conf-hold**, **continue dual-stopped PR**, or **re-babysit residual** — route to § Operator follow-up after dual-stop / hard stop (#3273) **one-shot** path
52
+ - Operator issues a **standing residual order**: **until floor or loop**, **until greptile meets policy**, or **pursue residuals until told otherwise** — route to the same § **standing** path (#3448); applies to open cohort / ordered-plan units, not only the last halted PR
52
53
 
53
54
  ## Cursor global babysit supersession (#2261)
54
55
 
@@ -177,7 +178,17 @@ Babysit and review-cycle are **not** a second unbounded implementation mandate.
177
178
  - ! P0 security / correctness defects on files **already touched** by the PR MAY land in the same PR without a new story.
178
179
  - ! New ledgers, idempotency protocols, cross-cutting reliability contracts, or multi-commit redesigns that expand story meaning **require** a separate story or an amended brief before code.
179
180
 
180
- ! **Confidence-only holds (0 P0/P1):** when confidence is below threshold (e.g. `Confidence Score: 3/5`) with zero P0 and zero P1 findings, the skill does **not** mandate unbounded redesign to raise confidence. Offer one of:
181
+ **Leftover classes (A/B/C, #3448):**
182
+
183
+ | Class | What it is | Auto-continue? |
184
+ |-------|------------|----------------|
185
+ | **class A** — named leftover on already-touched files | Wrong remediation, dropped field, fixture, same-module hole on files this PR already owns | **in-AC residual.** Continue until the resolved `#3095` floor or same-fingerprint loop |
186
+ | **class B** — new subsystem / AC fight | New ledger, protocol, cross-cutting contract, or work that expands story meaning | Park or file follow-up. Do not expand mid-babysit |
187
+ | **class C** — score-only, no concrete finding | Confidence below the resolved floor, 0 P0/P1, no named leftover | Document / same-as-conf-hold / operator floor this-PR-only. Not unbounded redesign |
188
+
189
+ ! **Already-touched leftover is class A (#2881 / #3448):** a leftover on files **already in the PR** is class A (in-AC residual) unless it needs a new ledger, protocol, or story.
190
+
191
+ ! **Confidence-only holds (0 P0/P1):** when confidence is below the **resolved `#3095` floor** (`plan.policy.review.minGreptileConfidence`: typed project policy > framework dogfood **5** > consumer default **4**; inspect `task policy:show --field=minGreptileConfidence` / `deft policy:show --field=minGreptileConfidence`) with zero P0 and zero P1 findings, the skill does **not** mandate unbounded redesign to raise confidence. That is class C unless a named leftover on already-touched files makes it class A. Offer one of:
181
192
 
182
193
  1. Follow-up issue / residual-risk note in the PR,
183
194
  2. Operator override path (document in PR comment),
@@ -200,13 +211,13 @@ Review fix cycles are multi-iteration work and MUST carry dual stop (`main.md` `
200
211
 
201
212
  | Loop class | Success stop | Default failure stop |
202
213
  |------------|--------------|----------------------|
203
- | Greptile / bot fix batch (Step 3 → re-review) | No P0/P1 on current HEAD; confidence meets `minGreptileConfidence` | **max 3** fix-batch iterations across the whole review ownership (do **not** reset the counter on push when the same primary fingerprint remains) **or** **2** consecutive re-reviews with the same primary P0/P1 fingerprint and no material fix |
214
+ | Greptile / bot fix batch (Step 3 → re-review) | No P0/P1 on current HEAD; confidence meets `minGreptileConfidence` | **max 3** fix-batch iterations across the whole review ownership (do **not** reset the counter on push when the same primary fingerprint remains) **or** the **Same-fingerprint stop** (below) |
204
215
  | Confidence-only hold (0 P0/P1, score below floor) | Confidence meets floor, or operator chooses document/accept path | **max 1** optional polish pass, then stop (do not redesign unbounded — see confidence-only holds above) |
205
216
 
206
217
  **On failure stop:**
207
218
 
208
219
  - ! Halt automatic re-fix. Prefer `BLOCKED:` with PR number, HEAD SHA, blocker class (`review_cycle_cap` / `greptile_p0_p1` / `conf_floor` / `no_progress`), what was tried, and human decision needed (preamble §11 / #2843).
209
- - ! **Halt-report resume line (MUST, #3273 / AC6):** End the terminal halt with residual class + conf (if any) + PR URL, example phrases (**pursue residual** | **follow-up hard-stop** | **same as conf-hold** | **continue dual-stopped PR**), and skill pointer to § Operator follow-up after dual-stop / hard stop (#3273). Same affordance shape as swarm `references/core-phase-4.md`.
220
+ - ! **Halt-report resume line (MUST, #3273 / #3448):** End the terminal halt with leftover class (A/B/C) + residual class + conf (if any) + resolved `#3095` floor + standing vs one-shot + PR URL. Example: `RESUME: residual=<class> leftover=<A|B|C> conf=<n/5|n/a> floor=<resolved min|n/a> standing=<yes|one-shot> PR=<url>`. One-shot phrases: **pursue residual** | **follow-up hard-stop** | **same as conf-hold** | **continue dual-stopped PR**. Standing phrases: **until floor or loop** | **until greptile meets policy** | **pursue residuals until told otherwise**. Skill pointer to § Operator follow-up after dual-stop / hard stop (#3273). Same affordance shape as swarm `references/core-phase-4.md`.
210
221
  - ⊗ Continue silent fix rounds after the envelope is exhausted.
211
222
  - ⊗ Reset the fix-batch counter solely by re-pushing, empty-committing, or swapping workers when the same primary finding fingerprint remains (poll-wait timer MAY reset for a new HEAD; the dual-stop fix-batch counter MUST NOT).
212
223
 
@@ -214,22 +225,28 @@ Review fix cycles are multi-iteration work and MUST carry dual stop (`main.md` `
214
225
 
215
226
  ### Operator follow-up after dual-stop / hard stop (#3273)
216
227
 
217
- Operator-initiated resume after conf-hold, residual dual-stop, or hard-stop exit — **not** automatic re-thrash. Composes Greptile floor (#3095) and advisory should-not-merge (#3225). Portable consumer + maintainer (`task` / `deft` dual-invoke).
228
+ Operator-initiated resume after conf-hold, residual dual-stop, or hard-stop exit — **not** automatic re-thrash. Composes Greptile floor (#3095) and advisory should-not-merge (#3225). Portable consumer + maintainer (`task` / `deft` dual-invoke). Continue-until target is the **resolved `#3095` floor** (`plan.policy.review.minGreptileConfidence`: typed project policy > framework dogfood **5** > consumer default **4**; inspect `task policy:show --field=minGreptileConfidence` / `deft policy:show --field=minGreptileConfidence`). ⊗ Hard-code 5/5. ⊗ Lower project policy to clear one PR.
218
229
 
219
- **Triggers:** pursue residual · follow-up hard-stop · same as conf-hold · continue dual-stopped PR · re-babysit residual
230
+ **One-shot vs standing (#3448):**
231
+ - **One-shot** triggers: pursue residual · follow-up hard-stop · same as conf-hold · continue dual-stopped PR · re-babysit residual — **one** pass on the unit that just halted, then re-stop. Do not silently widen.
232
+ - **Standing** triggers: **until floor or loop** · **until greptile meets policy** · **pursue residuals until told otherwise** — class A leftovers on **every open unit in the active cohort / ordered plan** keep moving until the resolved floor or the **Same-fingerprint stop** (this skill, Dual stop). Class B/C stay parked unless the operator names them.
220
233
 
221
- **One residual pass under operator consent:**
222
- 1. Ground-truth: dual-invoke `pr:merge-ready` / `pr:watch --one-shot` (#2893).
234
+ **One residual pass under operator consent (one-shot, or one standing batch):**
235
+ 1. Ground-truth: dual-invoke `pr:merge-ready` / `pr:watch --one-shot` (#2893). Classify leftover A/B/C (#2881 table above).
223
236
  2. Apply **one** residual fix batch **or** one re-review wait — not both as an unbounded loop.
224
237
  3. If operator authorized a conf floor for **this PR only** (e.g. ≥4/5): post a PR audit comment (floor, HEAD SHA, authorizer). That is the human-merge / documented-override trail — it does **not** rewrite policy or make `pr:merge-ready` / `pr:watch` CLEAN below `minGreptileConfidence`. ⊗ Silent policy edit for one residual.
225
- 4. Re-evaluate Step 6; merge when **policy** floor + gates met, or human-merge after the documented PR-local floor is met in the bot body; else halt again with a fresh resume line.
238
+ 4. Re-evaluate Step 6; merge when **policy** floor + gates met, or human-merge after the documented PR-local floor is met in the bot body; else halt again with a fresh resume line (leftover class + resolved floor + standing vs one-shot).
226
239
  5. Post-merge `scope:complete` when this owner holds lifecycle (#2321 / #3264).
227
240
 
228
- ! Dual-stop re-entry: one residual pass then re-stop without new consent. Fresh operator consent required for another pass.
241
+ ! **Same-fingerprint stop (normative, #3448 / #2442):** **2 consecutive re-review observations**, **same primary fingerprint**, **no material fix between**. **Blocked handoffs count as observations.** After a real fix, a *new* leftover MAY take another batch. `#2442` batch cap (max 3 fix-batches) still applies.
242
+ ⊗ Restate a competing 2-vs-3 same-fingerprint threshold, or treat a `BLOCKED` handoff as not counting toward the stop.
243
+
244
+ ! Dual-stop re-entry: one residual pass then re-stop without new consent **unless** a standing order is active **and** the leftover is class A with a **new** fingerprint under the `#2442` cap. Fresh operator consent required for another one-shot pass, or after same-fingerprint / cap halt.
229
245
 
230
246
  ⊗ Unlimited auto-retry after dual-stop without new operator consent (#3273 / #2442).
231
247
  ⊗ Treat conf-only holds as authorization for unbounded redesign (#2881).
232
248
  ⊗ Lower project-wide `minGreptileConfidence` for one residual.
249
+ ⊗ Treat one-shot `pursue residual` as a standing order, or park a class A leftover on already-touched files because the score is below 5.
233
250
 
234
251
  ### Step 3: Fix all findings in ONE batch commit
235
252
 
@@ -370,6 +387,13 @@ Remediation:
370
387
 
371
388
  ! **Anti-thrash during attributed platform outage:** After thrash caps, stop automatic re-push loops. Remediation is wait + re-probe HEAD check-runs, not inventing workflow edits for a global outage.
372
389
 
390
+ ### Forge-outage drop-back (#3422)
391
+
392
+ ! On attributed platform outage (`attribution: platform`) or repeated REST 429/502/503: **drop back** GitHub I/O (empty-commit, close/reopen, tight polls, new poller children), **report once** to the human in chat (what is down, attribution/incident, parked work, next probe time), and **re-probe once per** `plan.policy.forgeOutageRetryMinutes` (default **30**; USER.md Personal wins; min 5; inspect `task policy:show --field=forgeOutageRetryMinutes`). Local work that does not need the forge MAY continue. Depth: [`scm/github.md`](../../scm/github.md) § #3180 / #3422. Complements #3167 (weather codes) and #3180 (status attribution) — does not replace them.
393
+
394
+ ⊗ Tight retry, empty-commit thrash, or sending the human to github.com as the only remediation.
395
+ ⊗ Auto-merge / `--skip-ci` because a status page is red.
396
+
373
397
  ⊗ Merge or `--skip-ci` solely because a status page is red — status is attribution for wait/thrash policy, not a second branch-protection oracle.
374
398
  ⊗ Blame Blacksmith when GH Actions/Webhooks are the red components and Blacksmith runners are operational.
375
399
  ⊗ Edit workflows / empty-commit thrash to "fix" a documented global Actions/webhook outage without a status-page probe.
@@ -820,6 +844,7 @@ task lifecycle:event -- emit plan:approved \
820
844
 
821
845
  - ⊗ Multi-hour empty-commit / close-reopen thrash after CI weather thrash caps when `ci_never_scheduled` or `ci_cancelled_no_failover` (#3167)
822
846
  - ⊗ Workflow thrash or empty-commit spam during attributed platform outage without status-page probe (#3180)
847
+ - ⊗ Tight forge-outage retry / empty-commit thrash without a one-shot human report (#3422)
823
848
  - ⊗ Merge or `--skip-ci` solely because a status page is red without check-run evidence (#3180)
824
849
  - ⊗ Block merge-ready wait on SLizard alone when Greptile Step 6 is clean (#3167)
825
850
  - ⊗ Silent admin / `--skip-ci` merge under Actions outage without audit comment and opt-in authority (#3167)
@@ -839,8 +864,9 @@ task lifecycle:event -- emit plan:approved \
839
864
  - ⊗ Misclassify Claude Code as `cursor-composer` from bare `Task` alone (#3134)
840
865
  - ⊗ Expand active story scope past xBRIEF AC mid-babysit without follow-up issue or consented brief amend (#2881)
841
866
  - ⊗ Treat confidence-only holds (0 P0/P1) as a mandate for unbounded redesign (#2881)
842
- - ⊗ Dual-stop / conf-residual terminal halt without #3273 resume line (residual class + pursue residual / follow-up hard-stop / same as conf-hold / continue dual-stopped PR + skill section pointer) (#3273)
867
+ - ⊗ Dual-stop / conf-residual terminal halt without #3273 resume line (leftover class + residual class + resolved floor + standing vs one-shot + pursue residual / until floor or loop + skill section pointer) (#3273 / #3448)
843
868
  - ⊗ Unlimited residual auto-retry after dual-stop without new operator consent (#3273 / #2442)
869
+ - ⊗ Hard-code 5/5 as the continue-until target, or treat one-shot `pursue residual` as standing, or park a class A already-touched leftover as a new story (#3448 / #2881 / #3095)
844
870
  - ⊗ Invent freestyle sleep/poll loops when dual-invoke probes fail for `pr:watch` — use the official gh-only fallback and fail-loud missing-task (#2878 / #2893)
845
871
  - ⊗ Treat bare `task pr:watch` as the only consumer gate form — probe `deft` then `task deft:` first (#2893)
846
872
  - ⊗ Treat a passing SLizard/Greptile check run, a non-blocking review comment, or an ad hoc fix commit as the review-cycle exit predicate -- Step 6 fail-closed all-of (#1259) and multi-reviewer registry triage (#769) still apply
@@ -294,6 +294,8 @@ including PROJECT-DEFINITION.xbrief.json.
294
294
  **Custom Rules**:
295
295
  {custom rules or "No custom rules defined yet."}
296
296
 
297
+ **Forge outage retry** (optional): `forgeOutageRetryMinutes: 30` — integer minutes, minimum 5. Default 30. Personal wins over `plan.policy.forgeOutageRetryMinutes`. Omit to use project policy or the framework default. Inspect: `task policy:show --field=forgeOutageRetryMinutes`.
298
+
297
299
  ## Defaults (fallback)
298
300
 
299
301
  Settings in this section are fallback defaults. PROJECT-DEFINITION.xbrief.json overrides these
@@ -34,6 +34,13 @@ task verify:branch || exit 1
34
34
 
35
35
  The swarm skill creates branches per agent so the guard is mostly informational here, but a malformed PROJECT-DEFINITION (missing `plan.policy` block AND no legacy narrative) is a fail-closed signal worth surfacing before the swarm spawns N agents.
36
36
 
37
+ ### Forge-outage drop-back (#3422)
38
+
39
+ ! On attributed platform outage or repeated REST 429/502/503: drop GitHub I/O, report once to the human in chat, and re-probe on `plan.policy.forgeOutageRetryMinutes` (default **30**; USER.md Personal wins; min 5; `task policy:show --field=forgeOutageRetryMinutes`). Local work that does not need the forge MAY continue. Depth: [`scm/github.md`](../../scm/github.md) § #3180 / #3422. Complements #3167 / #3180.
40
+
41
+ ⊗ Tight retry, empty-commit thrash, or sending the human to github.com as the only remediation.
42
+ ⊗ Auto-merge / `--skip-ci` because a status page is red.
43
+
37
44
  ## Deterministic Questions Contract
38
45
 
39
46
  ! Every numbered-menu prompt rendered in this skill (Phase 0 Step 0 queue-driven promote prompts (#1142 / N2), Step 0.5 bridge approval gate, Step 5 final-approval gate, Phase 1 Step 3 file-overlap audit gate, Phase 5->6 ready-to-merge gate) MUST follow [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md): render the canonical numbered menu in chat unless the host UI visibly preserves numeric option labels and returns numeric selections or exact displayed option text. The final two numbered options MUST be `Discuss` and `Back`, in that order. The Discuss-pause semantic is documented verbatim there -- on `Discuss` selection the agent MUST halt the in-progress sequence immediately, prompt `What would you like to discuss?`, and resume only on an explicit user signal. Implicit resumption is forbidden, and fallback chat replies MUST map only to the displayed number or exact displayed option text.
@@ -43,7 +50,8 @@ The swarm skill creates branches per agent so the guard is mostly informational
43
50
  - User says "run agents", "parallel agents", "swarm", or "launch N agents on stories"
44
51
  - Multiple independent story-level xBRIEFs in `xbrief/active/` need to be worked on simultaneously
45
52
  - A batch of stories are ready and have no mutual dependencies
46
- - Operator re-authorizes a dual-stopped / hard-stopped / conf-hold unit: **pursue residual**, **follow-up hard-stop**, **same as conf-hold**, **continue dual-stopped PR**, or **re-babysit residual** — route to § Operator follow-up after dual-stop / hard stop (#3273)
53
+ - Operator re-authorizes a dual-stopped / hard-stopped / conf-hold unit: **pursue residual**, **follow-up hard-stop**, **same as conf-hold**, **continue dual-stopped PR**, or **re-babysit residual** — route to § Operator follow-up after dual-stop / hard stop (#3273) **one-shot** path
54
+ - Operator issues a **standing residual order**: **until floor or loop**, **until greptile meets policy**, or **pursue residuals until told otherwise** — route to the same § **standing** path (#3448); applies to open cohort / ordered-plan units, not only the last halted PR
47
55
 
48
56
  ## Prerequisites
49
57
 
@@ -134,18 +142,24 @@ Large multi-host skills use a **host-neutral core** plus **one** per-host adapte
134
142
 
135
143
  ! Default failure envelope for repair/monitor class work (unless the operator or xBRIEF names a stricter one):
136
144
  - **max iterations:** 3 monitor repair actions (re-dispatch, takeover complete, re-trigger review) for the same leaf/PR failure class, **or**
137
- - **no-progress:** same error / same Greptile P0-P1 fingerprint / same idle state **3+** times with no material worktree or review change (composes with Phase 4 "stuck in an error loop" takeover trigger), **or**
145
+ - **no-progress:** same error / same idle state **3+** times with no material worktree or review change (composes with Phase 4 "stuck in an error loop" takeover trigger). Same-fingerprint Greptile residual uses [`deft-directive-review-cycle/SKILL.md`](../deft-directive-review-cycle/SKILL.md) Dual stop — **Same-fingerprint stop**. **or**
138
146
  - **budget:** existing poll caps (`pr:watch` max-wait, Greptile service-error single retry + escalate) count as budget stops -- do not invent a second unbounded poll loop outside them.
139
147
 
140
148
  ! On failure stop: halt automatic continuation; emit an operator-visible report (what was tried, what is missing, what human decision is needed). ⊗ Silent re-dispatch or infinite monitor continuation after the envelope is exhausted.
141
149
 
142
- ! **Halt-report resume line (MUST, #3273 / AC6):** Terminal dual-stop / hard-stop / conf-residual halt reports MUST end with residual class + conf (if any) + PR URL, example resume phrases (**pursue residual** | **follow-up hard-stop** | **same as conf-hold** | **continue dual-stopped PR**), and pointer to § Operator follow-up after dual-stop / hard stop. Full template: [`references/core-phase-4.md`](references/core-phase-4.md).
150
+ ! **Halt-report resume line (MUST, #3273 / #3448):** Terminal dual-stop / hard-stop / conf-residual halt reports MUST end with leftover class (A/B/C) + residual class + conf (if any) + resolved `#3095` floor + standing vs one-shot + PR URL (`leftover=` / `floor=` / `standing=`). One-shot phrases: **pursue residual** | **follow-up hard-stop** | **same as conf-hold** | **continue dual-stopped PR**. Standing phrases: **until floor or loop** | **until greptile meets policy** | **pursue residuals until told otherwise**. Pointer to § Operator follow-up after dual-stop / hard stop. Full template: [`references/core-phase-4.md`](references/core-phase-4.md).
143
151
 
144
152
  ! Composes with minimal-subgraph repair guidance (#2439): keep repairs minimal **and** bounded by dual-stop -- minimal repair is not a license to thrash. Durable delivery/acceptance circuit-breaker: **#3143** `packages/core/src/delivery-attempt/` (`evaluatePreDispatch`, unit ledger). Docs: `docs/delivery-attempt.md`. Skill defaults remain behavioral; mechanical gate lives in core.
145
153
 
146
154
  ### Operator follow-up after dual-stop / hard stop (#3273)
147
155
 
148
- Operator-initiated **one residual pass** after dual-stop / hard stop / conf-hold — not automatic re-thrash. Depth (steps, anti-thrash, conf-floor this-PR-only): [`references/core-phase-4.md`](references/core-phase-4.md) same section title. Thin pointer: dual-invoke `pr:merge-ready` / `pr:watch`; spawn **one** residual worker or review-cycle owner; document authorized conf floor for this PR only as human-merge/override trail (⊗ silent policy rewrite; `pr:merge-ready` still uses policy floor); re-stop without new consent. ⊗ Unlimited auto-retry. ⊗ Parent self-implement (#2843). Portable consumer + maintainer.
156
+ Operator-initiated resume after dual-stop / hard stop / conf-hold — not automatic re-thrash. Depth (A/B/C leftover classes, standing vs one-shot, steps): [`references/core-phase-4.md`](references/core-phase-4.md) same section title. Portable consumer + maintainer (`task` / `deft` dual-invoke). Continue-until target is the **resolved `#3095` floor** (`task policy:show --field=minGreptileConfidence` / `deft policy:show --field=minGreptileConfidence`: typed project policy > framework dogfood **5** > consumer default **4**). ⊗ Hard-code 5/5. ⊗ Lower project policy to clear one PR.
157
+
158
+ **Leftover classes (A/B/C, #3448):** **class A** named leftover on already-touched files = in-AC residual, auto-continue under standing until floor or same-fingerprint loop. **class B** new subsystem / AC fight = park or follow-up. **class C** score-only = document / same-as-conf-hold. Already-touched leftover is class A unless it needs a new ledger/protocol/story (#2881).
159
+
160
+ **One-shot vs standing:** one-shot `pursue residual` = one pass then re-stop. Standing (`until floor or loop` / `until greptile meets policy` / `pursue residuals until told otherwise`) applies to **open cohort / ordered-plan units**, not only the last halted PR. Same-fingerprint stop: [`deft-directive-review-cycle/SKILL.md`](../deft-directive-review-cycle/SKILL.md) Dual stop (normative). `#2442` batch cap still applies.
161
+
162
+ Thin pointer: dual-invoke `pr:merge-ready` / `pr:watch`; spawn **one** residual worker or review-cycle owner per batch; document authorized conf floor for this PR only as human-merge/override trail (⊗ silent policy rewrite; `pr:merge-ready` still uses policy floor). ⊗ Unlimited auto-retry. ⊗ Parent self-implement (#2843).
149
163
 
150
164
  ## Runtime Capability Detection (summary)
151
165
 
@@ -217,8 +231,10 @@ Named mode **beside** dispatch-and-collect. Canon: [`../../swarm/swarm.md`](../.
217
231
  - ⊗ Misclassify OpenClaw `sessions_spawn` as `grok-build` or `generic-terminal` (#2875)
218
232
  - ⊗ Misclassify Claude Code as `cursor-composer` / `generic-terminal` (#3134)
219
233
  - ⊗ Run multi-iteration repair/monitor loops without a failure stop or with silent continuation after the envelope is exhausted (#2442)
220
- - ⊗ Dual-stop/hard-stop halt without #3273 resume line, or unlimited residual auto-retry without new operator consent (#3273)
234
+ - ⊗ Dual-stop/hard-stop halt without #3273 resume line (leftover class + resolved floor + standing vs one-shot), or unlimited residual auto-retry without new operator consent (#3273 / #3448)
235
+ - ⊗ Hard-code 5/5 as the continue-until target, or park a class A already-touched leftover as a new story (#3448 / #2881 / #3095)
221
236
  - ⊗ Force a second full dispatch on a retain-capable host solely for a mid-scope gate, or invent retain on one-shot hosts (#3158)
222
237
  - ⊗ Use retained-child messaging for mid-run constitution self-edit (#3158 / #3164)
238
+ - ⊗ Tight forge-outage retry / empty-commit thrash without a one-shot human report (#3422)
223
239
 
224
240
  Full anti-pattern list: [`references/core-ops.md`](references/core-ops.md).
@@ -125,6 +125,7 @@ CONSTRAINTS:
125
125
  - ⊗ Complete a story without moving its xBRIEF from `active/` to `completed/` and updating its origin references
126
126
  - ⊗ Declare a swarm closed without running the Phase 6 Step 1.5 cohort completion sweep (`task swarm:complete-cohort`) and confirming `task xbrief:validate` is green -- skipping it leaves the cohort's story xBRIEFs stranded in `active/` and their decompose-created epic parents stranded in `pending/`, the exact #1487 recurrence (the headless / multi-worker close-out is where the sweep was historically missed)
127
127
  - ⊗ Declare a swarm closed while the cohort's `active/` -> `completed/` lifecycle moves remain uncommitted -- after the Step 1.5 sweep the monitor MUST commit them in a single `chore(xbrief): complete <slugs> post-merge` commit on the base branch and `git push origin <configured-base-branch>` (Phase 6 Step 2b). An uncommitted lifecycle record is invisible to every other clone and re-surfaces as lifecycle-sync drift at the next release; the post-merge commit is the prevention, `task reconcile:issues -- --apply-lifecycle-fixes` is only the recovery (#1358)
128
+ - ⊗ After the last `drive-to: merge-ready` leaf, emit parent `done` without same-turn `task swarm:finalize-cohort` or `task verify:completed-tracked` green on `origin/<deliveryBranch>` -- untracked laptop `xbrief/completed/` is not land; that close is FAILED (#3476 / #3264 / #1358)
128
129
  - ⊗ Hardcode `master` as the base branch -- always use the configured base branch from Phase 0
129
130
  - ⊗ Treat a Greptile GitHub CheckRun of COMPLETED/NEUTRAL as equivalent to a passing review without inspecting the comment body. NEUTRAL is the result both when Greptile intentionally has nothing to say AND when it errored out mid-review; the two cases require opposite responses (#526)
130
131
  - ⊗ Loop the monitor indefinitely on the Greptile-service-errored state or time out silently at the poll cap -- detect the "Greptile encountered an error" comment body, retry once via `@greptileai review` with a 10-minute cap, and on second error escalate to the user with the three-way choice (wait / empty retrigger commit / documented override) per Phase 6 Step 1 (#526)
@@ -158,8 +159,9 @@ CONSTRAINTS:
158
159
  - ⊗ Full dual-source re-QC solely because the harness re-delivered the same settle event (#3092)
159
160
  - ⊗ Run multi-iteration repair, monitor, or implement-fix loops without a dual-stop failure envelope (max iterations and/or no-progress and/or budget) (#2442)
160
161
  - ⊗ Silently continue, re-dispatch, or open another identical attempt after the failure stop fires — halt with an operator-visible report (what was tried, what is missing, what human decision is needed) (#2442)
161
- - ⊗ Emit a dual-stop / hard-stop / conf-residual terminal halt report **without** the #3273 resume line (residual class + example phrases pursue residual / follow-up hard-stop / same as conf-hold / continue dual-stopped PR + skill section pointer) — primary discovery path; see `core-phase-4.md` Operator follow-up after dual-stop / hard stop
162
+ - ⊗ Emit a dual-stop / hard-stop / conf-residual terminal halt report **without** the #3273 resume line (leftover class + residual class + resolved floor + standing vs one-shot + example phrases pursue residual / follow-up hard-stop / same as conf-hold / continue dual-stopped PR / until floor or loop + skill section pointer) — primary discovery path; see `core-phase-4.md` Operator follow-up after dual-stop / hard stop (#3448)
162
163
  - ⊗ Unlimited auto-retry or parent self-implement after dual-stop without new operator consent (#3273 / #2843 / #2442)
164
+ - ⊗ Hard-code 5/5 as the continue-until target, treat one-shot `pursue residual` as standing, or park a class A already-touched leftover as a new story (#3448 / #2881 / #3095)
163
165
  - ⊗ Treat dual-stop skill defaults as a durable delivery-attempt ledger — mechanical cross-revision circuit breaker is #3143 (`packages/core/src/delivery-attempt/`), not prompt-only thrashing control (#2442)
164
166
  - ⊗ Spawn a second implement leaf without `task swarm:pre-dispatch` exit 0, or while exit 1 (`DENY_DUPLICATE_ACTIVE`) — gate is authoritative (#3228 / #3143); takeover is cancel-then-begin, not dual active
165
167
  - ⊗ Force a second full dispatch on a retain-capable host solely because a mid-scope approval gate exists — re-message the live child (message-later / steer-mid-flight) instead (#3158)
@@ -45,6 +45,7 @@ Cross-links: Phase 3 Worker-owns-lifecycle (`references/core-phase-3.md`), revie
45
45
 
46
46
  ### Headless cohort fast-path: low-ceremony launch (C1 / #1387)
47
47
 
48
+ ! `task swarm:launch` claims this worktree occupancy lease (`intent: swarm`) before emitting the manifest (#3433). A live foreign occupant fails closed.
48
49
  ! When the operator supplies a **pre-approved cohort** via the **C1** `task swarm:launch` CLI, Phase 0 runs in headless / low-ceremony mode: the per-phase interactive approval gates (the Step 0c promote-fill prompts, the Step 0.5 lifecycle-bridge approval, and the Step 4/5 allocation approval) collapse into a SINGLE consent -- the `## Allocation context` token (#1378) carried in the dispatch envelope. The interactive promote-fill loop (Step 0a -- 0d below) is SKIPPED.
49
50
  ! The **C1** signature is `task swarm:launch -- --stories <ids|paths> [--group <label>] [--worktree-map <path>] [--base-branch <branch>] [--autonomous]`. `--stories` names the pre-approved story ids or xBRIEF paths; `--group` is an optional cohort label; `--worktree-map` points at the pre-created **C3** worktree-map JSON consumed in Phase 2; `--base-branch` overrides the default `master`; `--autonomous` runs without the interactive launch confirmation.
50
51
  ! The SINGLE consent is the #1378 `## Allocation context` token with `dispatch_kind: swarm-cohort` and a NON-NULL `allocation_plan_id` AND `batching_rationale` (the recognition contract in `templates/agent-prompt-preamble.md` § 2.5). That token IS the batched approval for the whole cohort -- the deterministic-question gates the interactive path runs (per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md)) are bypassed wholesale on the headless path, not asked once per phase.
@@ -148,7 +148,7 @@ Cross-references: `packages/core/src/swarm/routing.ts` (`SWARM_WORKER_ROLES`), `
148
148
 
149
149
  ! **Deliberate `stop-at: pr-open` is not silent Gap C handback:** Silent PR-open handback for a worker whose envelope already said `drive-to: merge-ready` remains **forbidden**. A **pre-declared** `stop-at: pr-open` plus an immediately owned review-cycle babysit path is the supported alternative under the #3153 SLA. Partner contract depth: `skills/deft-directive-review-cycle/SKILL.md` § Partner merge-path when implement stops at PR-open.
150
150
 
151
- ! **Post-merge scope lifecycle (#2321 / Gap C):** Workers scoped `stop-at: pr-open` MUST NOT run `task scope:complete` before exit — their activation checkpoint rides into master on merge. The monitor (or Phase 6 `task swarm:finalize-cohort` / `task swarm:complete-cohort` on the headless path) MUST run `task scope:complete` or `task scope:cancel` for each shipped story xBRIEF after its PR merges. Workers scoped `drive-to: merge-ready` (or `drive-to: merge`) MUST include `task scope:complete` on their active xBRIEF as part of the same unit of work (after merge when appropriate). `task verify:orphan-active` fails closed when active/running briefs remain after their issues close or PR merges.
151
+ ! **Post-merge scope lifecycle (#2321 / Gap C / #3429):** Workers scoped `stop-at: pr-open` MUST NOT run `task scope:complete` before exit — their activation checkpoint rides into master on merge. The monitor (or Phase 6 `task swarm:finalize-cohort` / `task swarm:complete-cohort` on the headless path) MUST run `task scope:complete` or `task scope:cancel` for each shipped story xBRIEF after its PR merges. Workers scoped `drive-to: merge-ready` (or `drive-to: merge`) MUST include `task scope:complete` on their active xBRIEF as part of the same unit of work (after merge when appropriate). After merge of issue `#N`, `task verify:orphan-active -- --issue N` must be exit 0 before `DONE`; exit 1 shipped prints `task scope:complete -- <path>`; unresolved lookup prints a retry remediation.
152
152
 
153
153
  ! **Background / independent dispatch (Gap D):** Dispatch implementation, fix, and review-cycle workers independently / in the background when the platform supports it. On Cursor, use the Task tool background path (`run_in_background: true`); on Claude Code, use the `Agent` tool with `run_in_background: true` (or host equivalent) (#3134); on OpenClaw, use `sessions_spawn` with the host's non-blocking / background session flags so the monitor conversation stays interactive. Foreground dispatch is for short tasks (<~3 min) only.
154
154
 
@@ -69,29 +69,42 @@ tools: explore=0 commit=3 verify=0 coordinate=0 unknown=1 | anomalies: commit-wi
69
69
  | Stop | Default |
70
70
  |------|---------|
71
71
  | max iterations | **3** repair actions for the same leaf/PR failure class (resume prompt, takeover complete-remaining-steps, re-dispatch replacement, review re-trigger) |
72
- | no-progress | same error / same Greptile finding class / same idle stage **3+** times with no material worktree or review change |
72
+ | no-progress | same error / same idle stage **3+** times with no material worktree or review change. Same-fingerprint Greptile residual: [`deft-directive-review-cycle/SKILL.md`](../../deft-directive-review-cycle/SKILL.md) Dual stop — **Same-fingerprint stop** |
73
73
  | budget | honor `pr:watch` / poll max-wait and Greptile service-error single-retry+escalate caps; do not nest an unbounded poll outside them |
74
74
 
75
75
  ! When the failure stop fires: **halt** automatic repair/re-dispatch; emit an **operator-visible halt report** (what was tried, current stage, missing evidence, human decision needed). Prefer `BLOCKED:` over thin `DONE` when the unit cannot reach merge-ready inside the envelope.
76
76
 
77
- ! **Halt-report resume line (MUST, #3273 / AC6):** Terminal dual-stop / hard-stop / conf-residual halt reports MUST end with a copy-pasteable operator resume affordance so agents discover the follow-up path without prior chat memory:
77
+ ! **Halt-report resume line (MUST, #3273 / #3448):** Terminal dual-stop / hard-stop / conf-residual halt reports MUST end with a copy-pasteable operator resume affordance so agents discover the follow-up path without prior chat memory:
78
78
 
79
79
  ```
80
- RESUME: residual=<class> conf=<n/5|n/a> PR=<url>
81
- Operator may re-authorize **one residual pass** with: pursue residual | follow-up hard-stop | same as conf-hold | continue dual-stopped PR
80
+ RESUME: residual=<class> leftover=<A|B|C> conf=<n/5|n/a> floor=<resolved min|n/a> standing=<yes|one-shot> PR=<url>
81
+ Operator may re-authorize **one residual pass** (one-shot) with: pursue residual | follow-up hard-stop | same as conf-hold | continue dual-stopped PR
82
+ Standing order (open cohort/plan units, class A until resolved floor or same-fingerprint loop): until floor or loop | until greptile meets policy | pursue residuals until told otherwise
82
83
  Skill: deft-directive-swarm § Operator follow-up after dual-stop / hard stop (#3273) · deft-directive-review-cycle same section
83
84
  ```
84
85
 
85
- Residual class examples: `review_cycle_cap` / `greptile_p0_p1` / `conf_floor` / `no_progress` / `ci_weather` / `thin_done`.
86
+ Residual class examples: `review_cycle_cap` / `greptile_p0_p1` / `conf_floor` / `no_progress` / `ci_weather` / `thin_done`. Leftover class: **class A** already-touched in-AC residual · **class B** new subsystem / AC fight · **class C** score-only.
86
87
 
87
88
  ### Operator follow-up after dual-stop / hard stop (#3273)
88
89
 
89
- Operator-initiated resume after dual-stop, hard-stop, or conf-floor residual — **not** automatic re-thrash. Primary discovery is the halt-report resume line above; this section holds the steps. Portable for consumer deposit and maintainer tree (`task` / `deft` dual-invoke; no framework-monorepo-only path).
90
+ Operator-initiated resume after dual-stop, hard-stop, or conf-floor residual — **not** automatic re-thrash. Primary discovery is the halt-report resume line above; this section holds the steps. Portable for consumer deposit and maintainer tree (`task` / `deft` dual-invoke; no framework-monorepo-only path). Continue-until target is the **resolved `#3095` floor** (`plan.policy.review.minGreptileConfidence`: typed project policy > framework dogfood **5** > consumer default **4**; inspect `task policy:show --field=minGreptileConfidence` / `deft policy:show --field=minGreptileConfidence`). ⊗ Hard-code 5/5. ⊗ Lower project policy to clear one PR.
90
91
 
91
- **Triggers:** pursue residual · follow-up hard-stop · same as conf-hold · continue dual-stopped PR · re-babysit residual
92
+ **Leftover classes (A/B/C, #3448):**
92
93
 
93
- **One residual pass (then re-stop):**
94
- 1. Ground-truth: dual-invoke `pr:merge-ready` / `pr:watch --one-shot` on the PR (CLI `deft` first, then `task deft:` — see review-cycle #2893).
94
+ | Class | What it is | Auto-continue? |
95
+ |-------|------------|----------------|
96
+ | **class A** — named leftover on already-touched files | Wrong remediation, dropped field, fixture, same-module hole on files this PR already owns | **in-AC residual.** Continue until the resolved floor or same-fingerprint loop |
97
+ | **class B** — new subsystem / AC fight | New ledger, protocol, cross-cutting contract, or work that expands story meaning | Park or file follow-up. Do not expand mid-babysit |
98
+ | **class C** — score-only, no concrete finding | Confidence below the resolved floor, 0 P0/P1, no named leftover | Document / same-as-conf-hold / operator floor this-PR-only. Not unbounded redesign |
99
+
100
+ ! **Already-touched leftover is class A (#2881 / #3448):** a leftover on files **already in the PR** is class A unless it needs a new ledger, protocol, or story.
101
+
102
+ **One-shot vs standing (#3448):**
103
+ - **One-shot** triggers: pursue residual · follow-up hard-stop · same as conf-hold · continue dual-stopped PR · re-babysit residual — **one** pass on the unit that just halted, then re-stop. Do not silently widen.
104
+ - **Standing** triggers: **until floor or loop** · **until greptile meets policy** · **pursue residuals until told otherwise** — class A leftovers on **every open unit in the active cohort / ordered plan** keep moving until the resolved floor or the **Same-fingerprint stop** in [`deft-directive-review-cycle/SKILL.md`](../../deft-directive-review-cycle/SKILL.md) Dual stop. Class B/C stay parked unless the operator names them.
105
+
106
+ **One residual pass (then re-stop, or one standing batch):**
107
+ 1. Ground-truth: dual-invoke `pr:merge-ready` / `pr:watch --one-shot` on the PR (CLI `deft` first, then `task deft:` — see review-cycle #2893). Classify leftover A/B/C.
95
108
  2. If a delivery attempt is still active, cancel then begin with the **same unit ids** (exit 0 required before residual spawn) (#3228 / #3143):
96
109
  ```
97
110
  task swarm:pre-dispatch -- --scope-id <story-or-issue-or-xbrief-id> --target-id <worktree-path-or-branch> --action cancel
@@ -99,14 +112,17 @@ Operator-initiated resume after dual-stop, hard-stop, or conf-floor residual —
99
112
  ```
100
113
  3. Spawn **one** active residual worker or review-cycle owner (not sleep-only re-poll as the only work). Monitor MUST NOT self-implement product fixes after merge-ready leaf handback (#2843).
101
114
  4. If the operator authorized a conf floor for **this PR only** (e.g. ≥4/5): post a PR audit comment naming the floor, HEAD SHA, and who authorized it. That comment is the **human-merge / documented-override trail** — it does **not** rewrite `plan.policy.review.minGreptileConfidence` or make `pr:merge-ready` / `pr:watch` exit CLEAN below policy. Merge still requires policy CLEAN, bot-merge authority + override path, or human merge after the documented floor is met in the bot body. ⊗ Silent policy edit of `minGreptileConfidence` for one residual.
102
- 5. Wait re-review; merge when policy floor + gates met (or human-merge after documented PR-local floor). Run `scope:complete` + lifecycle land when in scope (#3264 / finalize).
115
+ 5. Wait re-review; merge when policy floor + gates met (or human-merge after documented PR-local floor). Run `scope:complete` + lifecycle land when in scope (#3264 / finalize). Halt reports MUST include leftover class + resolved floor + standing vs one-shot.
116
+
117
+ ! **Same-fingerprint stop:** [`deft-directive-review-cycle/SKILL.md`](../../deft-directive-review-cycle/SKILL.md) Dual stop — review fix loops (#2442) (normative). ⊗ Spawn another continuation leaf after a same-fingerprint `BLOCKED` handoff. `#2442` batch cap (max 3 repair actions) still applies.
103
118
 
104
- ! Dual-stop re-entry: after the residual pass (+ re-review wait), if still blocked, halt again with a fresh resume line. Another pass requires **new** operator consent.
119
+ ! Dual-stop re-entry: after the residual pass (+ re-review wait), if still blocked, halt again with a fresh resume line. Another **one-shot** pass requires **new** operator consent. A **standing** order MAY continue class A with a **new** fingerprint under the `#2442` cap.
105
120
 
106
121
  ⊗ Unlimited auto-retry after dual-stop without new operator consent (#3273 / #2442).
107
122
  ⊗ Sleep-only multi-hour re-poll as the sole residual work.
108
123
  ⊗ Parent/monitor self-implement after merge-ready leaf handback (#2843).
109
124
  ⊗ Lower project-wide `minGreptileConfidence` for one residual.
125
+ ⊗ Treat one-shot `pursue residual` as a standing order, or park a class A leftover on already-touched files because the score is below 5.
110
126
 
111
127
  ! Composes with minimal-subgraph repair (#2439): repairs stay minimal **and** dual-stop bounded. Mechanical delivery/acceptance circuit breaker: **#3143** `packages/core/src/delivery-attempt/` (`evaluatePreDispatch`). Docs: `docs/delivery-attempt.md`.
112
128
 
@@ -232,7 +232,7 @@ This is defense in depth -- run it even when the pre-merge inspection above pass
232
232
 
233
233
  ### Step 1.5: Cohort Completion Sweep (#1487)
234
234
 
235
- ! **REQUIRED.** Once the cohort's PRs are merged (Step 1 complete), the monitor MUST run the deterministic cohort completion sweep so the finished swarm leaves NO stranded xBRIEFs. This step closes the gap where a completed cohort left its story xBRIEFs in `xbrief/active/` and their decompose-created epic parents in `xbrief/pending/` -- nothing in the swarm flow swept them to `completed/` (observed in the 2026-06-03 swarm: after the cohort's PRs merged, the child story xBRIEFs stayed in `active/` and their epic parents stayed in `pending/`).
235
+ ! **REQUIRED.** Once the cohort's PRs are merged (Step 1 complete), the monitor MUST run the deterministic cohort completion sweep so the finished swarm leaves NO stranded xBRIEFs. `task swarm:complete-cohort` / `task swarm:finalize-cohort` release the swarm occupancy lease on a successful non-dry-run sweep (#3433). This step closes the gap where a completed cohort left its story xBRIEFs in `xbrief/active/` and their decompose-created epic parents in `xbrief/pending/` -- nothing in the swarm flow swept them to `completed/` (observed in the 2026-06-03 swarm: after the cohort's PRs merged, the child story xBRIEFs stayed in `active/` and their epic parents stayed in `pending/`).
236
236
 
237
237
  ! **Pre-sweep merge re-poll for human-merge / `stop-at: pr-open` (#3153):** Before invoking `task swarm:complete-cohort` or `task swarm:finalize-cohort`, re-read each cohort PR's merge state via REST. If any PR marked `awaiting-human-merge` is still open, **halt** the sweep, keep durable ownership, and continue the observe path (Phase 5 human-merge section) until merge or operator cancel. ⊗ Sweep on Greptile CLEAN alone while a human-merge PR is still open.
238
238
 
@@ -265,9 +265,12 @@ task swarm:finalize-cohort -- --stories <issue-or-path>... --repo <owner/repo>
265
265
 
266
266
  The finalize surface runs the same `completeCohort(...)` engine as `task swarm:complete-cohort`, fast-forwards the local base branch, creates a `swarm/finalize/<label>` feature branch (branch policy #747 safe), commits the `xbrief/` lifecycle moves, and auto-opens the sweep PR. Pass `--no-commit` to sweep only (manual Step 2b), or `--no-open-pr` to commit locally without opening the PR. Gate on exit 0 plus green `task xbrief:validate` before declaring the swarm closed.
267
267
 
268
+ ! **Drive-to last-leaf close (#3476):** After the last `drive-to: merge-ready` leaf of a cohort announces, parent `done` without same-turn `task swarm:finalize-cohort` (or a land PR already proving `task verify:completed-tracked` green on `origin/<deliveryBranch>`) is a **failed close**. Narrative-only `done` under #2934 is not enough when completed xBRIEFs exist only as untracked worktree residue. `scope:complete` stays filesystem-only -- do not teach every leaf to commit on master. Keep `verify:completed-tracked` off `task check`.
269
+
268
270
  ! **Manual fallback (#1487):** `task swarm:complete-cohort` remains the idempotent manual primitive when finalize automation is unavailable or you need a dry-run preview of transitions only. The headless path above replaces the historical requirement to hand-author a separate `chore(xbrief)` sweep PR every cycle.
269
271
 
270
272
  ⊗ Declare a swarm closed while any cohort story xBRIEF remains in `xbrief/active/` or any fully-childless decompose-created epic parent remains in `xbrief/pending/` -- run `task swarm:complete-cohort` and confirm `task xbrief:validate` is green first (#1487).
273
+ ⊗ After the last `drive-to` leaf, emit parent `done` without finalize-cohort / completed-tracked green on the delivery tip -- that is a failed close (#3476).
271
274
 
272
275
  ### Step 2: Close Issues and Update Origins
273
276
 
@@ -238,7 +238,7 @@ directive doctor
238
238
  - Top-level `xBRIEFInfo` envelope with `version` field present
239
239
  - `plan` object with `title`, `status`, and `items` fields present
240
240
  - `plan.status` values from valid enum: draft, proposed, approved, pending, running, completed, blocked, cancelled
241
- 3. ~ Use `task xbrief:validate` if available for deeper validation
241
+ 3. ~ Use `task xbrief:validate` for deeper validation
242
242
  4. ! Report any validation failures with file name and specific violation
243
243
 
244
244
  ⊗ Overwrite or modify project-level `./xbrief/*.xbrief.json` files -- those are project data, not framework files. Report issues and let the user decide how to fix them.
@@ -263,29 +263,27 @@ directive doctor
263
263
 
264
264
  ## Phase 5 -- Origin Freshness (RFC D12)
265
265
 
266
- ! For xBRIEFs with external origin references, detect staleness and externally-closed origins.
266
+ ! For xBRIEFs with external origin references, detect externally-closed origins. `task reconcile:issues` reports linked / unlinked / closed / completed-status drift -- it does **not** have a stale-content (`updatedAt`) bucket. Implementation-intent fail-closed for a newer origin is `task xbrief:preflight` (#3363).
267
267
 
268
268
  ### Step 1: Scan Origins
269
269
 
270
- 1. ! For each xBRIEF in `proposed/` and `pending/` with a `github-issue` reference in `plan.references` or top-level `references`:
271
- - Extract the issue number from the reference URL or `id` field
272
- - Fetch the issue: `gh issue view {N} --repo {owner/repo} --json updatedAt,state`
273
- 2. ! Compare the issue's `updatedAt` against the xBRIEF's `xBRIEFInfo.updated` (or `xBRIEFInfo.created` if no `updated` field)
270
+ 1. ! Run `task reconcile:issues` for linked / unlinked / externally-closed / completed-status drift.
271
+ 2. ! For each xBRIEF in `proposed/` and `pending/` with a `github-issue` reference in `plan.references` or top-level `references`, an advisory scan MAY fetch the issue (`gh api repos/{owner}/{repo}/issues/{N}`) and compare `updatedAt` / `updated_at` against `xBRIEFInfo.updated` (or `xBRIEFInfo.created` if no `updated` field). This is report-only; it is not the engine verb.
274
272
 
275
273
  ### Step 2: Categorize and Report
276
274
 
277
- 1. ! **Stale origins** -- issue `updatedAt` is newer than xBRIEF `updated` timestamp:
278
- - "{N} xBRIEFs have origins updated since last sync"
279
- - List each: "{filename}: Issue #{N} updated {time_delta} ago"
280
- 2. ! **Externally closed origins** -- issue state is `CLOSED`:
275
+ 1. ! **Externally closed origins** -- issue state is `CLOSED` (from `task reconcile:issues`):
281
276
  - "{N} xBRIEFs have origins that were closed externally"
282
277
  - List each: "{filename}: Issue #{N} is closed ({close_reason})"
278
+ 2. ! **Advisory newer origin** -- issue `updatedAt` is newer than xBRIEF `updated` timestamp (manual scan or later `task xbrief:preflight`):
279
+ - "{N} xBRIEFs have origins updated since last sync"
280
+ - List each: "{filename}: Issue #{N} updated {time_delta} ago"
283
281
  3. ~ **Current origins** -- no changes detected (report count only)
284
282
 
285
283
  ### Step 3: Recommendation
286
284
 
287
285
  - ! Report only -- never auto-update xBRIEFs based on origin changes
288
- - ~ If stale or externally-closed xBRIEFs are found, suggest: "Run a refinement session (`skills/deft-directive-refinement/SKILL.md`) to reconcile stale origins with user approval."
286
+ - ~ If newer or externally-closed origins are found, suggest: "Run a refinement session (`skills/deft-directive-refinement/SKILL.md`) to walk origin changes with user approval. Implementation will fail closed at `task xbrief:preflight` until the brief is refreshed or intentional divergence is recorded."
289
287
 
290
288
  ⊗ Auto-update xBRIEFs based on origin freshness checks -- report only; user decides during refinement
291
289
 
package/tasks/engine.yml CHANGED
@@ -55,6 +55,7 @@ tasks:
55
55
  fi
56
56
  node "{{.TASKFILE_DIR}}/engine-pm-run.cjs" "{{.DEFT_ROOT}}" build --mark-warm
57
57
  fi
58
+ : # no-op -- go-task <3.52.0 treats untaken last if/fi as exit 1 (#3381)
58
59
 
59
60
  invoke:
60
61
  internal: true
@@ -100,6 +101,7 @@ tasks:
100
101
  case " ${first_token} " in
101
102
  " session:start "|" session-start "|\
102
103
  " session:ready "|" session-ready "|\
104
+ " occupancy:steal "|" occupancy-steal "|\
103
105
  " lifecycle:event "|" lifecycle-event "|\
104
106
  " verify:session-ritual "|" verify-session-ritual "|\
105
107
  " verify:tools "|" verify-tools "|\