@deftai/directive-content 0.85.0 → 0.87.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.
@@ -92,12 +92,60 @@ The release pipeline's Step 9/10/11 git mutations carry the bypass in subprocess
92
92
 
93
93
  ⊗ Foreground-block the operator chat on reconcile / `ci:local` / `release:e2e` when background dispatch is available (#1880 Gap D / #2692).
94
94
 
95
+ ### Fixable check failure — file-and-merge before resume (#2859)
96
+
97
+ ! When Step 4 (`task ci:local` or `task check`) fails on a **fixable product or test defect** (hang, failing test, validation bug — not operator env misconfiguration), the release cut MUST pause and route the blocker through normal issue → xBRIEF → feature branch → PR → merge before resuming Phase 1.
98
+
99
+ ? **Step 5 branch-coverage threshold misses** during `task release` (Vitest branch coverage below 85% with no other failure mode) are carved out to § Step 5 branch-coverage threshold — open-issue ledger hatch (#2866) below — not this file-and-merge path.
100
+
101
+ **Required path:**
102
+ 1. File a GitHub issue with root cause, recurrence signature, and acceptance criteria.
103
+ 2. Ingest / promote / activate scope xBRIEF; implement on a feature branch with `drive-to: merge-ready`.
104
+ 3. Merge; confirm `task check` / `ci:local` is green for the failure mode.
105
+ 4. Resume the release cut from Phase 1 (re-run Step 4).
106
+
107
+ ⊗ Lead with an inline-only hotfix on the release branch / default branch without a tracked issue and merged PR.
108
+ ⊗ Suggest untracked `--skip-ci` or `--allow-skip-ci` without a **tracked issue number** as the first recovery when the failure is a clear, shippable bug.
109
+ ⊗ Continue the cut with "raise timeouts," "fix it here," or other shortcut theater before file-and-merge completes.
110
+
111
+ ? **`--skip-ci` / `--allow-skip-ci=#N` remains valid** only under explicit operator incident review with a **tracked issue** cited on the flag (Phase 4 contract). It is NOT a substitute for filing and merging a fixable defect discovered in Phase 1.
112
+
113
+ **AGENTS.md bulk rejected (#2859):** Expanding `AGENTS.md` / `content/templates/agents-entry.md` with an always-on pin for this release-phase reminder was considered and **rejected**. This rule lives in the release skill (and optional lesson); do NOT add AGENTS.md / agents-entry bulk for it.
114
+
115
+ See [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Fixable check failure during release for the operator runbook and the existing `--allow-skip-ci=#N` incident contract.
116
+
117
+ ### Step 5 branch-coverage threshold — open-issue ledger hatch (#2866)
118
+
119
+ ! When **`task release` Step 5** fails on Vitest coverage below the 85% goal, apply this hatch **only** when **branches** is the **sole** metric below 85% (hairline branch miss — lines, functions, and statements all ≥ 85%). Confirm via the Step 5 failure output or `task coverage:hotspots` before hatching. If **any other metric** is also below 85%, or the failure is a hang / failing test / non-coverage defect, STOP — use § Fixable check failure — file-and-merge before resume (#2859) instead.
120
+
121
+ **Runtime disclosure (#2573):** `--allow-coverage-debt=#N` sets vitest coverage thresholds to zero for the release Step 5 run (`vitest.config.ts`). The hatch is justified only for branch-only hairlines; the filed debt issue MUST require restoring **all four metrics** (lines, functions, branches, statements) to ≥ 85% before close.
122
+
123
+ **Open-issue ledger (release-scoped only):**
124
+
125
+ 1. Check for an **open coverage-debt tracking issue** (unpaid hatch from a prior cut) — union all three probes and dedupe by issue number:
126
+ - **Marker search** (new-format debt issues):
127
+ ```
128
+ gh issue list --repo <owner>/<repo> --state open --search "coverage-debt in:title,body" --limit 20
129
+ gh issue list --repo <owner>/<repo> --state open --search "allow-coverage-debt in:body" --limit 20
130
+ ```
131
+ - **CHANGELOG citation scan** (legacy hatch issues filed before markers were mandatory): parse `CHANGELOG.md` `[Unreleased]` plus the last three `## [version]` sections for `--allow-coverage-debt=#N` / `allow-coverage-debt=#N` citations; for each `#N`, run `gh issue view N --json state --jq .state` — `OPEN` counts as unpaid debt even when title/body lack the new markers (#2866).
132
+ 2. If **no open coverage-debt issue exists** → file `#N` with title prefix `coverage-debt:` and body containing both markers `coverage-debt` and `--allow-coverage-debt`, documenting measured metrics, branch-only trigger, and acceptance criteria (restore **all four** coverage metrics ≥ 85%). Continue the cut with `--allow-coverage-debt=#N` on `task release` (PowerShell-safe: `--allow-coverage-debt=N` or `--allow-coverage-debt="#N"` — see Anti-Patterns #2621). The open `#N` remains WIP until coverage is restored and the issue is closed.
133
+ 3. If an **open coverage-debt issue from a prior hatch still exists** → ⊗ soft-pass again; restore real coverage (all four metrics ≥ 85%) and close the debt issue before the cut proceeds.
134
+
135
+ ⊗ Auto-pass on a near-miss band without `#N` (#2573).
136
+ ⊗ Silent soft-pass with no tracked issue.
137
+ ⊗ File a debt issue without `coverage-debt` / `allow-coverage-debt` markers in title or body — the ledger query will miss it and permit a consecutive soft-pass (#2866).
138
+ ⊗ Use this carve-out when lines, functions, or statements are also below 85%, or for hangs, failing tests, or non-coverage Step 5 failures — those stay under #2859 file-and-merge.
139
+ ⊗ Treat file-debt-then-hatch as the default for ordinary PR / `task check` work outside a release cut — this hatch is release-scoped only.
140
+
141
+ See [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Coverage debt hatch during release.
142
+
95
143
  ~ **Frozen Go-installer bridge (#1912 / #1972 / #1987):** by default a release tag *above* the frozen line (the `LAST_GO_INSTALLER` constant in `packages/core/src/legacy-bridge/sot.ts`) will NOT rebuild the 6 Go binaries -- the CI `freeze-gate` job in `.github/workflows/release.yml` skips the build (the run stays green; npm still ships from the separate `npm-publish.yml`). If this release must rebuild the Go installer, follow the runbook in [`docs/RELEASING.md`](../../../docs/RELEASING.md) § Frozen Go-installer bridge: roll `LAST_GO_INSTALLER` forward to the cut tag BEFORE tagging (pinning to the exact cut tag both releases the gate AND re-freezes at the new line), then see that section's "After the release" step for the re-pin.
96
144
 
97
145
  1. ! Verify the operator is on the configured base branch (default `master`) and the working tree is clean
98
146
  2. ! Confirm the next version number (`X.Y.Z`) with the user. Major / minor / patch decision flows from the `[Unreleased]` content (breaking change → major; new feature → minor; fix-only → patch)
99
147
  3. ! Inspect `[Unreleased]` content vs the proposed version bump. If a breaking change appears in `### Changed` / `### Removed` but only a patch is proposed, surface the mismatch and ask the user to choose
100
- 4. ! Verify `task ci:local` passes locally (or `task check` as the graceful-degradation fallback per `tasks/release.yml` line 9-10). The `task release` script will refuse to proceed otherwise -- but Phase 1 catches it earlier
148
+ 4. ! Verify `task ci:local` passes locally (or `task check` as the graceful-degradation fallback per `tasks/release.yml` line 9-10). The `task release` script will refuse to proceed otherwise -- but Phase 1 catches it earlier — **on failure from a fixable defect, STOP and follow § Fixable check failure below (#2859); do NOT proceed to step 5**
101
149
  5. ! Verify `gh auth status` reports authenticated (`task release` will refuse otherwise)
102
150
  6. ! **Run `task reconcile:issues -- --apply-lifecycle-fixes` to clear any closed-issue / non-completed-folder xBRIEFs before invoking `task release`** (#734). The release pipeline carries the deterministic gate at Step 3 (`scripts/release.py::check_vbrief_lifecycle_sync`, refuses with `EXIT_VIOLATION` on any Section (c) mismatch), but Phase 1 is the operator's first-line defence -- running the apply-mode flag here is the canonical clean path; `--allow-vbrief-drift` on the pipeline exists only as the explicit-acknowledgment escape hatch (analogous to `--allow-dirty`). The recurrence record is the v0.21.0 cut, which surfaced 13 stranded xBRIEFs (8 cycle-relevant + 5 historical residue) post-publish; the gate now blocks that drift before any irreversible action
103
151
  7. ! **Verify the proposed `v<version>` tag is not already in use locally, on origin, or as a published GitHub release** (#784). The release pipeline carries the deterministic gate at Step 4 (`scripts/release.py::check_tag_available`, refuses with `EXIT_VIOLATION` before any state mutation -- CHANGELOG promotion, ROADMAP refresh, build, commit), but Phase 1 is the operator's first-line defence. Quickly probe with `git tag -l v<version>` (local), `git ls-remote --tags origin refs/tags/v<version>` (remote), and `gh release view v<version> --repo <owner>/<repo>` (release-only, where `gh release view` exits 0 only when the release exists). The recurrence record is the v0.22.0 → v0.23.0 release attempt on 2026-05-01: the operator typed `0.22.0` (the prior release from 12 hours earlier) and the legacy pipeline ran 8 steps before failing at `git tag` -- leaving a wrong-version local commit + `dist/deft-0.22.0.zip` orphan + manual `git reset --hard` recovery. The new pre-flight gate blocks that mode before any irreversible action
@@ -310,4 +358,4 @@ Where `<one-line guidance>` is one of:
310
358
  - ⊗ Manually rewrite the Phase 8 Slack `*Summary*:` line to deviate from the CHANGELOG `[<version>]` blockquote -- the canonical narrative is authored ONCE at Phase 1 via `--summary` and propagates verbatim across all three audiences (CHANGELOG / GitHub release body / Slack). Per-audience hand-edits create documentation drift that the deterministic `--summary` flow is designed to prevent. If the operator wants Slack-specific tone, fold it into the canonical Phase 1 wording before passing `--summary`, OR amend the CHANGELOG blockquote BEFORE Phase 8 so all three surfaces stay aligned
311
359
  - ⊗ Export `DEFT_ALLOW_DEFAULT_BRANCH_COMMIT=1` for the entire release session or wrap `task release` / `task ci:local` in it (#1553) -- the env var is process-wide and leaks into nested tests and temporary repos, producing false preflight failures. Prefer `task policy:allow-direct-commits -- --confirm` and restore with `task policy:enforce-branches` after the cut (closeout commit+push may use a **scoped** env prefix on those three git commands only — see Branch-Protection Policy Guard, #2623)
312
360
  - ⊗ Pass `--allow-coverage-debt=#N` unquoted on Windows PowerShell (#2621) -- `#` starts a comment and silently drops the issue number. Use `--allow-coverage-debt=N` or `--allow-coverage-debt="#N"`
313
- - ⊗ Soft-pass coverage debt on consecutive releases when the prior cut already cited debt (#2618 / #2573) -- restore real branch coverage >= 85% instead of reusing the escape hatch
361
+ - ⊗ Soft-pass coverage debt while an **open** coverage-debt issue from a prior hatch still exists (#2866 / #2573) -- restore real branch coverage >= 85% and close the debt issue before reusing `--allow-coverage-debt`; the ledger is open GitHub issues, not prior CHANGELOG citations (#2618 superseded by open-issue ledger)
@@ -50,6 +50,17 @@ On repos with `.deft/core/` installed, **PR shepherding intent** routes here --
50
50
  - ! Cloud babysit workers use `worker_role: review-monitor` (or `drive-to: merge-ready` implementation workers that own the review cycle) -- not a generic babysit loop without Phase 1 audit or Step 6 exit predicate (#1259).
51
51
  - ⊗ Route **babysit-pull-request-in-cloud** to Cursor global babysit when `.deft/core/` is present -- that bypasses xBRIEF preflight, `task check`, Greptile fail-closed exit, and CHANGELOG discipline (#2261 recurrence).
52
52
 
53
+ ### OpenClaw babysit supersession (#2876 / #2261)
54
+
55
+ On OpenClaw hosts with Directive installed (`.deft/core/` or equivalent content deposit), **babysit / shepherd / watch** intent likewise routes here -- not host-local freestyle poll loops and not OpenClaw `cron` alone.
56
+
57
+ - ! When the OpenClaw tool surface exposes `sessions_spawn`, Approach 1 is the **default** babysit path: spawn a background review-monitor via `sessions_spawn` (register with `--platform-primitive sessions_spawn` or the alias `openclaw-sessions-spawn`).
58
+ - ! Prefer a **visible** Control UI subagent when OpenClaw Control UI is the operator control plane so humans can inspect the monitor.
59
+ - ! Long review-monitor ownership (>~3 min) MUST NOT block the parent OpenClaw session — background `sessions_spawn` + parent yield; same Gap D rule as Cursor/Grok Build (#1880).
60
+ - ! Prefer deep-think gates inside the monitor via the dual-invoke probe order (#2893): `deft pr:watch` / `deft pr:merge-ready` first, then `task deft:pr:watch` when the Taskfile include is present, then the #2878 gh-only fallback — bare `task pr:watch` is not the consumer form.
61
+ - ⊗ Treat OpenClaw `cron` (or any host scheduler alone) as Approach 1. Cron/timer re-invocation is Approach 2 only when `sessions_spawn` is unavailable.
62
+ - ⊗ Freestyle main-session `gh pr view` / `sleep` poll + ad-hoc cron when `sessions_spawn` is available — that is the statusreport#153 / #2876 process-routing failure mode.
63
+
53
64
  ## Branch-Protection Policy Guard
54
65
 
55
66
  ! Before entering the review/fix loop, run the skill-level branch-policy guard (#746 / #747). Halt before any state mutation if the project's `plan.policy.allowDirectCommitsToMaster` is unresolvable AND the operator has not set `DEFT_ALLOW_DEFAULT_BRANCH_COMMIT=1`. Concretely:
@@ -142,9 +153,39 @@ Both commands extract the "Comments Outside Diff" section with surrounding conte
142
153
  - Identify cross-file dependencies (a term, value, or field mentioned in multiple files)
143
154
  - Categorize by severity (P0, P1, P2 — where P0 is critical/blocking, P1 is a real defect, P2 is a style or non-blocking suggestion)
144
155
  - Plan a single coherent batch of fixes
156
+ - ! **Scope-check each finding against the active story xBRIEF** (`plan.items[].narrative.Acceptance`) before coding — see Out-of-AC gate (#2881) below
145
157
 
146
158
  ⊗ Start fixing individual findings as you encounter them.
147
159
 
160
+ ### Out-of-AC findings / active-story scope gate (#2881)
161
+
162
+ Babysit and review-cycle are **not** a second unbounded implementation mandate. When Greptile (or another reviewer) raises design-adjacent work outside the active story's acceptance criteria, default to follow-up — not silent redesign mid-babysit (PR #2871 / #2869 → #2880 recurrence).
163
+
164
+ ! Given an active story xBRIEF with fixed `plan.items`, when a finding is **outside** those Acceptance criteria:
165
+
166
+ 1. ! File or propose a **follow-up** GitHub issue / scope xBRIEF for the out-of-AC work, **or**
167
+ 2. ! Amend the active brief's `plan.items` (and narratives) **with explicit operator consent** before implementing a new subsystem,
168
+ 3. ! Then continue babysit only for in-AC and carve-out findings.
169
+
170
+ ! **P0 carve-out vs new-subsystem-needs-story:**
171
+
172
+ - ! P0 security / correctness defects on files **already touched** by the PR MAY land in the same PR without a new story.
173
+ - ! 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.
174
+
175
+ ! **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:
176
+
177
+ 1. Follow-up issue / residual-risk note in the PR,
178
+ 2. Operator override path (document in PR comment),
179
+ 3. Minimal in-AC polish only — then re-evaluate Step 6.
180
+
181
+ ! **`issue:emit` related-ref footgun:** `task issue:emit` treats any `plan.references[]` entry whose type matches `github-issue` / `x-xbrief/github-issue` / `x-vbrief/github-issue` as **already tracked** and SKIPs creating a new issue. When linking **related** (non-primary) work:
182
+
183
+ - ! Use a non-emit-tracking type for related issues (e.g. keep related links in narratives / PR body / `Refs #N` prose), **or** designate a single primary origin github-issue ref that emit should honor.
184
+ - ⊗ Add related-issue `x-*/github-issue` refs to a brief that still needs `issue:emit` for its primary origin — emit will SKIP as already tracked.
185
+
186
+ ⊗ Expand active story scope past xBRIEF AC mid-babysit without follow-up or consented amend (#2881).
187
+ ⊗ Treat confidence-only holds as authorization to invent new subsystems in-tree.
188
+
148
189
  ### Step 3: Fix all findings in ONE batch commit
149
190
 
150
191
  ! Apply ALL fixes across all files before committing:
@@ -186,7 +227,52 @@ Both commands extract the "Comments Outside Diff" section with surrounding conte
186
227
 
187
228
  ### Greptile CLEAN vs CI holdout (`pr:watch` / #2688)
188
229
 
189
- ! When waiting on a Greptile verdict for a `drive-to: merge-ready` worker (or any review-cycle owner), prefer `task pr:watch -- <N>` (or `--one-shot --json`) over ad-hoc sleep loops (#1056). Parse `clean_gate_holdout` on every probe.
230
+ ! When waiting on a Greptile verdict for a `drive-to: merge-ready` worker (or any review-cycle owner), prefer the dual-invoke probe order below over ad-hoc sleep loops (#1056 / #2893). Parse `clean_gate_holdout` on every probe.
231
+
232
+ ### Gates-surface dual invoke order (#2893 / #2878)
233
+
234
+ Deep-think gates (`pr:watch`, `pr:merge-ready`, `review-monitor:*`) have **three ordered invoke paths**. Agents MUST probe in this order; bare `task pr:watch` is **not** the sole (or first) consumer form.
235
+
236
+ ! **Probe order (MUST):**
237
+
238
+ 1. **`deft` / `directive` CLI first** — attempt `deft pr:watch --help` (or `directive pr:watch --help`). Primary for npm/package-manager installs; works without a root Taskfile. CLI forms take flags **without** go-task's bare `--` separator (e.g. `deft pr:watch <N> --json`, `deft verify:review-monitor --pr <N>`).
239
+ 2. **`task deft:<verb>` second** — when a root Taskfile includes `.deft/core/Taskfile.yml` under key `deft:`, go-task exposes **namespaced** tasks (`task deft:pr:watch`, `task deft:verify:review-monitor`, `task deft:review-monitor:register`). Probe `task --list` / `task deft:pr:watch -- --help`. Task forms **require** the bare `--` separator before verb flags (e.g. `task deft:pr:watch -- <N>`, `task deft:verify:review-monitor -- --pr <N>`).
240
+ 3. **#2878 gh-only fallback last** — only when both CLI and namespaced task probes fail, classify **missing-task: pr:watch** (or **missing-task: review-monitor**) and use the official gh-only subset below.
241
+
242
+ ⊗ Treat bare `task pr:watch` / `task review-monitor:register` as the only prescribed consumer form — under include key `deft:` those un-namespaced names are absent; that probe failure is not proof the gate is unavailable if `deft` or `task deft:` works (#2893).
243
+ ⊗ Pass go-task's bare `--` separator into `deft`/`directive` CLI forms (e.g. `deft pr:watch -- --help`) — CLI parsers reject the standalone `--` and the probe fails falsely (#2893).
244
+
245
+ ### Missing gate surface / consumer gh-only fallback (#2878)
246
+
247
+ Some consumer repos (e.g. sister product deposits) ship Directive skills but have **no working invoke path** for `pr:watch` / `review-monitor:*` (no `deft` CLI on PATH, no Taskfile include → no `task deft:…`). Agents MUST NOT invent a non-skill poll loop when every probe fails.
248
+
249
+ ! **After dual-invoke probe fails (#2893):** classify the session as **missing-task: pr:watch** (or the specific verb) and fail-loud:
250
+
251
+ ```
252
+ BLOCKED: missing-task pr:watch on this consumer
253
+ Remediation:
254
+ 1. Prefer `deft pr:watch` / install `@deftai/directive` so the CLI surface works, OR
255
+ 2. Add the root Taskfile include (doctor gates-surface snippet) so `task deft:pr:watch` works, OR
256
+ 3. Use the official gh-only fallback subset below (still this skill — not freestyle).
257
+ ```
258
+
259
+ ! **Official gh-only fallback** (when both `deft`/`directive` and `task deft:<verb>` probes fail for pr:watch / review-monitor):
260
+
261
+ 1. Still select Approach 1 when a sub-agent primitive exists (OpenClaw `sessions_spawn`, Cursor `Task`, `spawn_subagent`, `start_agent`) — spawn a review-monitor that runs the gh-only loop; do not block the parent.
262
+ 2. **Do not call** gate verbs via any surface the probe showed absent — those invocations cannot succeed and must not gate the spawn.
263
+ 3. Ownership claim without the tasks: post/update the sticky `<!-- deft:review-owner -->` PR comment via `gh api` (same field shape as the task-written lease) **or** keep ownership in the parent and document `missing-task: review-monitor` in the PR/parent handback. Never invent `.deft/review-monitor.json`.
264
+ 4. Poll with adaptive cadence (20-30s / 60s / 90s) using:
265
+ - `gh pr view <N> --comments` (dual-source + Step 1 rules still apply)
266
+ - `gh pr checks <N>`
267
+ - `gh api repos/<owner>/<repo>/pulls/<N> -q .head.sha` for HEAD pin
268
+ - `gh api repos/<owner>/<repo>/commits/<sha>/check-runs` for Greptile terminal check-run
269
+ 5. Evaluate the same Step 6 fail-closed all-of (terminal check-run + HEAD SHA + Last reviewed commit + confidence > 3 + no P0/P1).
270
+ 6. Surface missing-task once to the operator/parent on first detection; do not silently rebrand freestyle sleep as `pr:watch`.
271
+
272
+ ⊗ Fake a successful `pr:watch` or `review-monitor:*` gate when every dual-invoke probe failed.
273
+ ⊗ Block Approach 1 / parent yield on missing `review-monitor:*` after the dual-invoke probe — use the gh lease claim or parent-owned gh-only poll instead (#2878).
274
+ ⊗ Invent ad-hoc `sleep` / main-session poll / OpenClaw cron loops outside Approach 1–3 when the skill already names this fallback (#2878 / statusreport#153 recurrence).
275
+ ⊗ Skip Step 6 fail-closed fields because deterministic tasks are missing — the gh surfaces above remain mandatory.
190
276
 
191
277
  ! When `clean_gate_holdout=ci_failures` and Greptile otherwise satisfies the probe-side Step 6 fields (SHA match on HEAD, confidence > 3, no P0/P1, not errored): **MUST NOT** idle-poll hoping CI heals. Treat Greptile CLEAN + CI red with the **same ownership** as a Greptile P0 for a merge-ready worker — one fix batch, re-push, re-probe.
192
278
 
@@ -239,43 +325,55 @@ Both commands extract the "Comments Outside Diff" section with surrounding conte
239
325
 
240
326
  ! **Worker-owns-lifecycle (#1880 Gap C):** When this skill runs as part of an implementation worker scoped `drive-to: merge-ready`, the worker owns the full review/fix loop through merge-ready in its own tool loop — do NOT exit at PR-open expecting the orchestrator to spawn a separate review leaf.
241
327
 
328
+ ! **Swarm monitor must not self-implement (#2843 / Gap C):** When a cohort monitor receives `BLOCKED` or DONE-with-blockers from a `drive-to: merge-ready` implementation leaf, the monitor MUST NOT enter the review/fix loop inline on Tier 1 — background-dispatch ONE continuation leaf scoped `drive-to: merge-ready` on the same worktree. Monitor-inline review-cycle is permitted only on Tier 3 or with explicit operator consent (see `skills/deft-directive-swarm/SKILL.md` Phase 5 completion-notification decision tree).
242
329
 
243
330
 
244
- ! Select the monitoring approach based on runtime capability detection (the matrix in `skills/deft-directive-swarm/SKILL.md` Phase 3 Step 1, extended per #1342 slices 1-2 for `spawn_subagent` / "grok-build" and per #1877 for Cursor as first-class Tier-1 tiers). Probe the environment (tool set + env vars) to obtain the stable platform descriptor (`grok-build`, `warp-orchestrated`, `warp-manual`, `cursor-composer`, `cursor-cloud-agent`, etc.) from the launch adapter / `get_platform_capabilities` and map the descriptor to the appropriate tier + dispatch primitive (`start_agent`, `spawn_subagent`, or the Cursor `Task` tool). The descriptor (not hard-coded tool presence) is the single source of truth for both launch and review monitoring.
245
331
 
246
- - **Tier 1 (orchestrated sub-agent)** Approach 1 (spawn review-monitor sub-agent via the primitive matching the descriptor: `start_agent`, `spawn_subagent`, or the Cursor `Task` tool with `run_in_background: true`)
247
- - **Tier 2 (no sub-agent primitive, but scheduler/timer/auto-reinvocation)** → Approach 2 (yield-between-polls)
332
+ ! Select the monitoring approach based on runtime capability detection (the matrix in `skills/deft-directive-swarm/SKILL.md` Phase 3 Step 1, extended per #1342 slices 1-2 for `spawn_subagent` / "grok-build", per #1877 for Cursor as first-class Tier-1 tiers, and per #2876 for OpenClaw `sessions_spawn`). Probe the environment (tool set + env vars) to obtain the stable platform descriptor (`grok-build`, `warp-orchestrated`, `warp-manual`, `cursor-composer`, `cursor-cloud-agent`, `openclaw`, etc.) from the launch adapter / `get_platform_capabilities` and map the descriptor to the appropriate tier + dispatch primitive (`start_agent`, `spawn_subagent`, the Cursor `Task` tool, or OpenClaw `sessions_spawn`). The descriptor (not hard-coded tool presence) is the single source of truth for both launch and review monitoring.
333
+
334
+ - **Tier 1 (orchestrated sub-agent)** → Approach 1 (spawn review-monitor sub-agent via the primitive matching the descriptor: `start_agent`, `spawn_subagent`, the Cursor `Task` tool with `run_in_background: true`, or OpenClaw `sessions_spawn`)
335
+ - **Tier 2 (no sub-agent primitive, but scheduler/timer/auto-reinvocation)** → Approach 2 (yield-between-polls) — includes OpenClaw `cron` / host scheduler **only when** `sessions_spawn` is unavailable (#2876)
248
336
  - **Tier 3 (interactive session, nothing else)** → Approach 3 (blocking sleep loop as last resort)
249
337
 
250
- ! Detection: use the full runtime capability matrix (swarm Phase 3 + launch adapter from #1342 slice 2). The old single-probe for `start_agent` is superseded; the returned platform descriptor determines both the orchestration path and the MCP surface (see MCP probe below). If the descriptor is `grok-build` (spawn_subagent present, start_agent + WARP_* absent), treat as Tier 1 with the spawn_subagent poller path. If the descriptor is `cursor-composer` / `cursor-cloud-agent` (Cursor `Task` tool present, start_agent + WARP_* + spawn_subagent absent), treat as **Tier 1 with the backgrounded Cursor `Task` poller path** (#1877) — NOT Tier 3. Cursor's `Task` tool is a first-class sub-agent primitive; degrading a Cursor session to the Approach-3 blocking poll is the misclassification #1877 closes.
338
+ ! Detection: use the full runtime capability matrix (swarm Phase 3 + launch adapter from #1342 slice 2). The old single-probe for `start_agent` is superseded; the returned platform descriptor determines both the orchestration path and the MCP surface (see MCP probe below). If the descriptor is `grok-build` (spawn_subagent present, start_agent + WARP_* absent), treat as Tier 1 with the spawn_subagent poller path. If the descriptor is `cursor-composer` / `cursor-cloud-agent` (Cursor `Task` tool present, start_agent + WARP_* + spawn_subagent absent), treat as **Tier 1 with the backgrounded Cursor `Task` poller path** (#1877) — NOT Tier 3. Cursor's `Task` tool is a first-class sub-agent primitive; degrading a Cursor session to the Approach-3 blocking poll is the misclassification #1877 closes. If the descriptor is `openclaw` (`sessions_spawn` present), treat as **Tier 1 with the backgrounded `sessions_spawn` poller path** (#2876) — NOT Approach 2 cron and NOT main-session gh poll.
339
+
340
+ ! Swarm agents (whether launched via `start_agent`, `spawn_subagent`, or OpenClaw `sessions_spawn` per the platform descriptor) SHOULD prefer Approach 1 for their own review-monitor sub-agent. Approach 2's yield-between-polls is not self-sustaining for swarm agents (see warning below). Always include the canonical `templates/agent-prompt-preamble.md` (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates) when spawning a poller sub-agent.
251
341
 
252
- ! Swarm agents (whether launched via `start_agent` or `spawn_subagent` per the platform descriptor) SHOULD prefer Approach 1 for their own review-monitor sub-agent. Approach 2's yield-between-polls is not self-sustaining for swarm agents (see warning below). Always include the canonical `templates/agent-prompt-preamble.md` (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates) when spawning a poller sub-agent.
342
+ ! **Deterministic review-monitor gate (#2655 / #2814 / #2876 / #2893):** When Tier 1 is available **and** a dual-invoke probe succeeds for review-monitor verbs (`deft verify:review-monitor` / `deft review-monitor:register`, or `task deft:verify:review-monitor` / `task deft:review-monitor:register`), run that verify form before yielding, entering Approach 3, or claiming review monitoring started — CLI: `deft verify:review-monitor --pr <N> [--call-site solo]`; task: `task deft:verify:review-monitor -- --pr <N> [--call-site solo]`. After spawning Approach 1, claim the PR-anchored lease with the matching register form (CLI: `deft review-monitor:register --pr <N> --monitor-agent-id <id> --platform-primitive ...`; task: `task deft:review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive start_agent|spawn_subagent|cursor-task|sessions_spawn|openclaw-sessions-spawn`). Release with the matching release form (CLI: `deft review-monitor:release --pr <N>`; task: `task deft:review-monitor:release -- --pr <N>`) when done. Exit `0` ready / `1` not ready or held-by-other / `2` config. The sole source of truth is the sticky GitHub PR comment (`<!-- deft:review-owner -->`); legacy `.deft/review-monitor.json` is obsolete and ignored. On register conflict, attach to the existing owner or stop — do not parallel-fix.
253
343
 
254
- ! **Deterministic review-monitor gate (#2655 / #2814):** When Tier 1 is available, run `task verify:review-monitor -- --pr <N> [--call-site solo]` before yielding, entering Approach 3, or claiming review monitoring started. After spawning Approach 1, claim the PR-anchored lease with `task review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive start_agent|spawn_subagent|cursor-task`. Release with `task review-monitor:release -- --pr <N>` when done. Exit `0` ready / `1` not ready or held-by-other / `2` config. The sole source of truth is the sticky GitHub PR comment (`<!-- deft:review-owner -->`); legacy `.deft/review-monitor.json` is obsolete and ignored. On register conflict, attach to the existing owner or stop — do not parallel-fix.
344
+ ! **Missing review-monitor surface carve-out (#2878 / #2893):** When dual-invoke probes fail for `pr:watch` **and** `review-monitor:*` (no `deft` CLI, no `task deft:` include), do **not** invoke those gates and do **not** block Approach 1 on them. Fail-loud once with `missing-task: review-monitor` / `missing-task: pr:watch`, then:
345
+ 1. Still spawn Approach 1 with the official gh-only fallback when a sub-agent primitive exists.
346
+ 2. Post (or update) the sticky lease comment via raw `gh api` using the same `<!-- deft:review-owner -->` field shape the tasks would write — parent may yield after that claim succeeds — **or**, if the agent cannot write issue comments, keep ownership in the parent with the gh-only poll and document that lease tasks were unavailable.
347
+ 3. Never invent a local `.deft/review-monitor.json` as a substitute gate.
348
+ ⊗ Require successful review-monitor register/verify on a consumer where dual-invoke probes failed — that is the conf=3 / #2878 inconsistency Greptile flagged.
255
349
 
256
- ! **Regression trigger (#2797):** A leaf that claims a monitor is active without a preceding successful `task review-monitor:register` GitHub claim MUST fail the review-monitor checklist/eval; a backgrounded `task pr:watch` shell is insufficient.
350
+ ! **Regression trigger (#2797 / #2878):** A leaf that claims a monitor is active without a preceding successful **GitHub sticky lease claim** MUST fail the review-monitor checklist/eval; a backgrounded `pr:watch` shell is insufficient. When a dual-invoke probe finds `review-monitor:register`, that form is the required claim path. When the missing-task carve-out applies (#2878), a raw `gh api` post/update of the same `<!-- deft:review-owner -->` sticky comment satisfies the claim (or the parent keeps ownership and does not claim a separate monitor). The regression fails only on a claim with **no** sticky lease evidence — not on consumers that legitimately lack the gate surface.
257
351
 
258
352
 
259
353
 
260
354
  ! **CI-holdout carve-out (#2688):** When `task pr:watch --one-shot --json` reports `clean_gate_holdout=ci_failures` with Greptile fields otherwise satisfied on current HEAD, do **not** freeze on `verify:review-monitor` / spawn-monitor as if Greptile latency were the blocker. Fix CI first (same ownership as Greptile P0). Keep or register a review-monitor only while still waiting on Greptile latency; a `BLOCKED: ci_failures` DONE handback to the implementation owner is correct.
261
355
 
262
356
 
263
- ! **Cursor leaf boundary (#2797):** A Cursor `Task` leaf cannot reliably spawn another Cursor `Task`; nested Task (leaf spawning leaf) is unsupported for an Approach 1 review-monitor. A Cursor `drive-to: merge-ready` leaf MUST either keep ownership in the same agent by blocking on `task pr:watch -- <N>`, or its envelope MUST instead be `stop-at: pr-open` so the orchestrator can spawn and register a sibling review-monitor. A background shell `task pr:watch` is not a monitor and MUST NOT be claimed as one.
357
+ ! **Cursor leaf boundary (#2797 / #2893):** A Cursor `Task` leaf cannot reliably spawn another Cursor `Task`; nested Task (leaf spawning leaf) is unsupported for an Approach 1 review-monitor. A Cursor `drive-to: merge-ready` leaf MUST either keep ownership in the same agent by blocking on `deft pr:watch <N>` (or `task deft:pr:watch -- <N>` when include-present), or its envelope MUST instead be `stop-at: pr-open` so the orchestrator can spawn and register a sibling review-monitor. A background shell `pr:watch` is not a monitor and MUST NOT be claimed as one.
264
358
 
265
359
  **Approach 1 (preferred -- sub-agent orchestration available per platform descriptor):**
266
360
 
267
- ! **Background dispatch (#1880):** Spawn the review-monitor sub-agent via the matching primitive IN THE BACKGROUND (Cursor: Task `run_in_background: true`; Grok Build: `spawn_subagent` with parent yielding). The parent MUST remain interactive while the poller runs.
361
+ ! **Background dispatch (#1880 / #2876):** Spawn the review-monitor sub-agent via the matching primitive IN THE BACKGROUND (Cursor: Task `run_in_background: true`; Grok Build: `spawn_subagent` with parent yielding; OpenClaw: `sessions_spawn` with parent yielding). The parent MUST remain interactive while the poller runs — never block the parent OpenClaw/Cursor/Grok session for >~3 min of monitor ownership.
268
362
 
269
- ! **Heartbeat contract for Cursor pollers (#1877 / #1166):** A Cursor `Task` review-monitor poller whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`), same as the `spawn_subagent` path — emit periodic progress so the parent can distinguish a live poller from a hung one.
363
+ ! **Heartbeat contract for Cursor pollers (#1877 / #1166 / #2876):** OpenClaw sessions_spawn pollers share this contract. A Cursor `Task` or OpenClaw `sessions_spawn` review-monitor poller whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`), same as the `spawn_subagent` path — emit periodic progress so the parent can distinguish a live poller from a hung one.
364
+
365
+ ~ **Visible Control UI (OpenClaw):** When OpenClaw Control UI is the operator control plane, SHOULD spawn the review-monitor as a **visible** subagent so humans can inspect progress without attaching to the parent session.
270
366
 
271
367
  ! When the platform descriptor indicates Tier 1 (sub-agent support), spawn a review-monitor sub-agent using the primitive matching the descriptor:
272
368
 
273
- 1. ! Launch via the matching primitive: `start_agent` (Warp), `spawn_subagent` (grok-build / TUI / non-Warp), **or the Cursor `Task` tool with `run_in_background: true` (`cursor-composer` / `cursor-cloud-agent`, #1877)** with a prompt that instructs it to poll for Greptile completion. For `spawn_subagent` and the Cursor `Task` tool the prompt MUST reference the canonical poller template `templates/swarm-greptile-poller-prompt.md` (with placeholders filled) plus the agent preamble; the working directory / context must be the PR branch (worktree or equivalent for hybrid).
274
- 2. ! The sub-agent polls using the mechanism for its primitive: for `spawn_subagent` use `get_command_or_subagent_output` (adaptive cadence: ~20-30s first check after push, ~60s second, ~90s thereafter; Greptile typically lands in 3-7 min); for `start_agent` the native messaging path; for the Cursor `Task` tool the backgrounded-task completion-notification path. Front-load the first check to catch fast reviews.
275
- 3. ! When the exit condition is met (Greptile review current on the HEAD commit SHA, confidence > 3, no P0/P1 remaining), the sub-agent reports completion back to the parent (via `send_message_to_agent` or the spawn_subagent result channel).
369
+ 1. ! Launch via the matching primitive: `start_agent` (Warp), `spawn_subagent` (grok-build / TUI / non-Warp), the Cursor `Task` tool with `run_in_background: true` (`cursor-composer` / `cursor-cloud-agent`, #1877), **or OpenClaw `sessions_spawn` (`openclaw`, #2876)** with a prompt that instructs it to poll for Greptile completion. For `spawn_subagent`, Cursor `Task`, and OpenClaw `sessions_spawn` the prompt MUST reference the canonical poller template `templates/swarm-greptile-poller-prompt.md` (with placeholders filled) plus the agent preamble; the working directory / context must be the PR branch (worktree or equivalent for hybrid).
370
+ 2. ! The sub-agent polls using the mechanism for its primitive: for `spawn_subagent` use `get_command_or_subagent_output` (adaptive cadence: ~20-30s first check after push, ~60s second, ~90s thereafter; Greptile typically lands in 3-7 min); for `start_agent` the native messaging path; for the Cursor `Task` tool the backgrounded-task completion-notification path; for OpenClaw `sessions_spawn` the host session completion / messaging channel (prefer `task pr:watch` inside the child when available). Front-load the first check to catch fast reviews.
371
+ 3. ! When the exit condition is met (Greptile review current on the HEAD commit SHA, confidence > 3, no P0/P1 remaining), the sub-agent reports completion back to the parent (via `send_message_to_agent`, the spawn_subagent result channel, or the OpenClaw sessions completion channel).
276
372
  4. ! The main conversation pane stays fully interactive during monitoring -- the user (or parent monitor) can continue other work.
277
373
  5. ! On receiving the completion message / result, the parent re-fetches findings (both gh pr view --comments and the secondary source) and proceeds to Step 5.
278
374
 
375
+ ⊗ Use OpenClaw `cron` alone as Approach 1 when `sessions_spawn` is available — cron is Approach 2 scheduler fallback only (#2876).
376
+
279
377
  **Approach 2 (fallback -- no sub-agent primitive for the descriptor):**
280
378
 
281
379
  ! When the platform descriptor indicates no sub-agent orchestration (or the primitive is unavailable), use discrete tool calls with a yield between checks. For `grok-build` / spawn_subagent descriptor this path is normally avoided in favor of Approach 1; it exists for pure interactive or limited runtimes.
@@ -437,6 +535,12 @@ task lifecycle:event -- emit plan:approved \
437
535
  ## Anti-Patterns
438
536
 
439
537
  - ⊗ Route PR shepherding to Cursor global `babysit` on Deft-managed repos when `.deft/core/` is installed -- use this review-cycle skill instead (#2261)
538
+ - ⊗ Route OpenClaw babysit/shepherd/watch to main-session gh poll + cron when `sessions_spawn` is available -- use Approach 1 with `sessions_spawn` (#2876 / #2261)
539
+ - ⊗ Treat OpenClaw `cron` alone as Approach 1 — cron/timer is Approach 2 only if spawn is unavailable (#2876)
540
+ - ⊗ Expand active story scope past xBRIEF AC mid-babysit without follow-up issue or consented brief amend (#2881)
541
+ - ⊗ Treat confidence-only holds (0 P0/P1) as a mandate for unbounded redesign (#2881)
542
+ - ⊗ 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)
543
+ - ⊗ Treat bare `task pr:watch` as the only consumer gate form — probe `deft` then `task deft:` first (#2893)
440
544
  - ⊗ 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
441
545
  - ⊗ Push individual fix commits per finding
442
546
  - ⊗ Start fixing before analyzing ALL findings
@@ -363,15 +363,17 @@ git worktree add <path> -b <branch-name> <configured-base-branch>
363
363
  1. ! **Probe for `start_agent` tool** — check the available tool set for `start_agent` (or equivalent agent-orchestration tool). Its presence indicates a Warp environment with native orchestration support.
364
364
  2. ! **Probe for Warp environment** — if `start_agent` is not available, check for `WARP_*` environment variables (e.g. `WARP_TERMINAL_SESSION`, `WARP_IS_WARP_TERMINAL`). Their presence indicates Warp without orchestration.
365
365
  3. ! **Probe for the Cursor `Task` tool** — when neither `start_agent` nor `WARP_*` is present, check the tool set for the Cursor `Task` sub-agent tool (dispatchable in the background via `run_in_background: true`). Its presence indicates a Cursor environment with a **first-class Tier-1 sub-agent primitive** (#1877). Classify as `cursor-composer` for an interactive Composer session and `cursor-cloud-agent` for a Cursor cloud agent. Cursor is **Tier 1 → Approach 1** — do NOT let it fall through to `generic-terminal` / the Approach-3 blocking poll.
366
- 4. ! **Probe for `spawn_subagent` tool** — when none of `start_agent`, `WARP_*`, or the Cursor `Task` tool is present, check for `spawn_subagent` (Grok Build / non-Warp TUI launch adapter, #1342 slice 2). Its presence indicates the grok-build platform.
367
- 5. ! **Select launch path automatically** based on detection results do NOT present static options:
366
+ 4. ! **Probe for the OpenClaw `sessions_spawn` tool** — when none of `start_agent`, `WARP_*`, or the Cursor `Task` tool is present, check the tool set for OpenClaw `sessions_spawn` (optional `visible` flag). Its presence indicates an OpenClaw environment with a **first-class Tier-1 sub-agent primitive** (#2875). Classify as descriptor `openclaw`. OpenClaw is **Tier 1 → Approach 1** — do NOT misclassify it as `grok-build` (that uses `spawn_subagent`) or fall through to `generic-terminal`.
367
+ 5. ! **Probe for `spawn_subagent` tool** when none of `start_agent`, `WARP_*`, the Cursor `Task` tool, or OpenClaw `sessions_spawn` is present, check for `spawn_subagent` (Grok Build / non-Warp TUI launch adapter, #1342 slice 2). Its presence indicates the grok-build platform.
368
+ 6. ! **Select launch path automatically** based on detection results — do NOT present static options:
368
369
  - **`start_agent` available** → Orchestrated launch (Step 2a) — preferred path, fully automated, no manual tab management
369
370
  - **`start_agent` unavailable, Warp detected** → Interactive Warp tabs (Step 2b) — full MCP, global rules, warm index; requires manual tab management
370
371
  - **Cursor `Task` tool available (no `start_agent`, no `WARP_*`)** → Cursor sub-agent launch (Step 2e) via the `Task` tool with `run_in_background: true` (Tier 1 / Approach 1) — keeps the monitor pane interactive; descriptor is `cursor-composer` (interactive) or `cursor-cloud-agent` (cloud)
371
- - **`grok-build` (`spawn_subagent` available, no `start_agent`, no `WARP_*`, no Cursor `Task` tool)** → Grok Build launch (Step 2d) — first-class non-Warp path
372
+ - **OpenClaw `sessions_spawn` available (no `start_agent`, no `WARP_*`, no Cursor `Task` tool)** → OpenClaw launch (Step 2f) via `sessions_spawn` (Tier 1 / Approach 1) descriptor is `openclaw`
373
+ - **`grok-build` (`spawn_subagent` available, no `start_agent`, no `WARP_*`, no Cursor `Task` tool, no OpenClaw `sessions_spawn`)** → Grok Build launch (Step 2d) — first-class non-Warp path
372
374
  - **No orchestration primitive detected** → `generic-terminal` degraded launch. Offer a **Serial self-execution downgrade** first: with explicit operator consent, the monitor may execute the prepared worker prompts itself one story at a time from the isolated worktrees. This preserves forward progress but is not true concurrent swarm execution.
373
- 6. ! **Return a stable platform descriptor** for downstream phases — one of `warp-orchestrated` (start_agent available), `warp-manual` (Warp without start_agent), `cursor-composer` (Cursor `Task` tool, interactive Composer), `cursor-cloud-agent` (Cursor `Task` tool, cloud agent), `grok-build` (spawn_subagent available, non-Warp, non-Cursor), or `generic-terminal` (no orchestration primitives). The detection matrix MUST include explicit absence checks for `start_agent`, `WARP_*`, and the Cursor `Task` tool so the six descriptors are unambiguous. Phase 4 monitoring and Phase 6 sub-agent dispatch read this stable platform descriptor as a single source of truth instead of re-running detection per call.
374
- 7. ? **Cloud escape hatch** — use `oz agent run-cloud` (Step 2c) ONLY if the user explicitly requests cloud execution. Never default to cloud. (The Cursor `cursor-cloud-agent` descriptor above is distinct — it is a Cursor-native cloud agent detected via the `Task` tool, not the `oz` escape hatch.)
375
+ 7. ! **Return a stable platform descriptor** for downstream phases — one of `warp-orchestrated` (start_agent available), `warp-manual` (Warp without start_agent), `cursor-composer` (Cursor `Task` tool, interactive Composer), `cursor-cloud-agent` (Cursor `Task` tool, cloud agent), `openclaw` (`sessions_spawn` available, non-Warp, non-Cursor), `grok-build` (spawn_subagent available, non-Warp, non-Cursor, non-OpenClaw), or `generic-terminal` (no orchestration primitives). The detection matrix MUST include explicit absence checks for `start_agent`, `WARP_*`, the Cursor `Task` tool, and OpenClaw `sessions_spawn` so the seven descriptors are unambiguous. Phase 4 monitoring and Phase 6 sub-agent dispatch read this stable platform descriptor as a single source of truth instead of re-running detection per call.
376
+ 8. ? **Cloud escape hatch** — use `oz agent run-cloud` (Step 2c) ONLY if the user explicitly requests cloud execution. Never default to cloud. (The Cursor `cursor-cloud-agent` descriptor above is distinct — it is a Cursor-native cloud agent detected via the `Task` tool, not the `oz` escape hatch.)
375
377
 
376
378
  ! In `generic-terminal` mode, if the operator declines serial self-execution, the manual terminal prompt-paste fallback remains available: the user can paste each generated prompt into any terminal or agent interface with access to the matching worktree. Surface the tradeoff clearly: manual paste preserves user control but requires tab/process management and is still not automated orchestration.
377
379
 
@@ -455,13 +457,13 @@ Cross-references: `packages/core/src/swarm/routing.ts` (`SWARM_WORKER_ROLES`), `
455
457
 
456
458
  ! **Deliberate model routing before ANY dispatch:** Before launching ANY worker in this phase (cohort OR solo), run `task verify:routing` and resolve each `(dispatch_provider, worker_role)` via `task swarm:routing-set` / `.deft/routing.local.json`. Populate `## Worker metadata` per `templates/agent-prompt-preamble.md` §2.6 and pass `resolved_model` into the actual dispatch primitive when non-null. Never silently inherit the monitor's model. Deterministic gate enforcement is #1877; this rule is behavioral doctrine (#1880).
457
459
 
458
- ! **Cursor ownership split (#2797):** A Cursor `Task` implementation leaf MUST NOT launch a nested Cursor `Task` review-monitor: nested Task (leaf spawning leaf) is unsupported/unreliable. For Cursor, a `drive-to: merge-ready` leaf owns a blocking `task pr:watch -- <N>` in its own process, or the dispatcher uses `stop-at: pr-open` and itself launches a sibling monitor then runs `task review-monitor:register`. A leaf that backgrounds `task pr:watch` and exits MUST NOT claim monitoring is active; this is a review-monitor-gate failure.
460
+ ! **Cursor ownership split (#2797 / #2893):** A Cursor `Task` implementation leaf MUST NOT launch a nested Cursor `Task` review-monitor: nested Task (leaf spawning leaf) is unsupported/unreliable. For Cursor, a `drive-to: merge-ready` leaf owns a blocking dual-invoke `pr:watch` (`deft pr:watch <N>` first, else `task deft:pr:watch -- <N>`) in its own process, or the dispatcher uses `stop-at: pr-open` and itself launches a sibling monitor and dual-invoke `review-monitor:register`. A leaf that backgrounds `pr:watch` and exits MUST NOT claim monitoring is active; this is a review-monitor-gate failure.
459
461
 
460
462
  ! **Worker-owns-lifecycle (Gap C):** Every implementation-worker dispatch prompt MUST declare the unit-of-work boundary: `stop-at: pr-open` OR `drive-to: merge-ready` (default for story xBRIEF work). Workers scoped `drive-to: merge-ready` own pre-PR, push, PR open, Greptile review-cycle poll/fix, and the #1259 Step 6 fail-closed exit as ONE dispatch — they spawn their own review poller per `skills/deft-directive-review-cycle/SKILL.md` monitoring tiers. The monitor MUST NOT plan a separate post-PR review leaf for a worker already scoped merge-ready.
461
463
 
462
464
  ! **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.
463
465
 
464
- ! **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`) so the monitor conversation stays interactive. Foreground dispatch is for short tasks (<~3 min) only.
466
+ ! **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 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.
465
467
 
466
468
  ⊗ Hand back at PR-open and re-dispatch separate review-monitor or fix leaf agents for a worker whose envelope scoped `drive-to: merge-ready` (#1880 Gap C).
467
469
 
@@ -514,7 +516,7 @@ Agents execute on remote VMs without local MCP servers, codebase indexing, or Wa
514
516
 
515
517
  ### Step 2d: Grok Build Launch (spawn_subagent available)
516
518
 
517
- ! When the platform descriptor is `grok-build` (spawn_subagent detected, no start_agent, no WARP_*), dispatch each worker via `spawn_subagent` with:
519
+ ! When the platform descriptor is `grok-build` (spawn_subagent detected, no start_agent, no WARP_*, no Cursor `Task`, no OpenClaw `sessions_spawn`), dispatch each worker via `spawn_subagent` with:
518
520
  1. The canonical `templates/agent-prompt-preamble.md` content as the preamble
519
521
  2. The standard worktree prompt (STEP 1-6 from the Prompt Template below), adapted to use `get_command_or_subagent_output` for polling rather than `start_agent` lifecycle events
520
522
  3. The worktree path set to the agent's isolated git worktree
@@ -523,14 +525,30 @@ Agents execute on remote VMs without local MCP servers, codebase indexing, or Wa
523
525
 
524
526
  ### Step 2e: Cursor Launch (Task tool available) — #1877
525
527
 
526
- ! When the platform descriptor is `cursor-composer` or `cursor-cloud-agent` (Cursor `Task` tool detected, no `start_agent`, no `WARP_*`, no `spawn_subagent`), dispatch each worker via the Cursor `Task` tool with:
528
+ ! When the platform descriptor is `cursor-composer` or `cursor-cloud-agent` (Cursor `Task` tool detected, no `start_agent`, no `WARP_*`, no OpenClaw `sessions_spawn`, no `spawn_subagent`), dispatch each worker via the Cursor `Task` tool with:
527
529
  1. The canonical `templates/agent-prompt-preamble.md` content as the preamble (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates).
528
530
  2. The standard worktree prompt (STEP 1-6 from the Prompt Template below).
529
531
  3. The worktree path set to the agent's isolated git worktree.
530
532
  4. ! **`run_in_background: true`** for any worker or poller whose loop runs longer than a short task (~3 min) — implementation, fix, and review-cycle workers — so the monitor conversation pane stays interactive (#1880 Gap D). The parent is notified on completion.
531
533
  5. ! **Deliberate model routing (#1739):** pass the route's `resolved_model` (when non-null) as the Task tool's `model` argument — stamping the C2 manifest is prep; the recorded model MUST reach the actual spawn call.
532
534
 
533
- ~ This is the first-class Cursor path. It is **Tier 1 → Approach 1** (a backgroundable sub-agent primitive), equivalent in tier to `start_agent` / `spawn_subagent`; it MUST NOT be downgraded to a `generic-terminal` blocking poll. Cursor pollers whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`, #1166), same as the `spawn_subagent` path.
535
+ ~ This is the first-class Cursor path. It is **Tier 1 → Approach 1** (a backgroundable sub-agent primitive), equivalent in tier to `start_agent` / `spawn_subagent` / OpenClaw `sessions_spawn`; it MUST NOT be downgraded to a `generic-terminal` blocking poll. Cursor pollers whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`, #1166), same as the `spawn_subagent` path.
536
+
537
+ ### Step 2f: OpenClaw Launch (`sessions_spawn` available) — #2875
538
+
539
+ ! When the platform descriptor is `openclaw` (OpenClaw `sessions_spawn` detected, no `start_agent`, no `WARP_*`, no Cursor `Task` tool), dispatch each worker via OpenClaw `sessions_spawn` with:
540
+ 1. The canonical `templates/agent-prompt-preamble.md` content as the preamble (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates).
541
+ 2. The standard worktree prompt (STEP 1-6 from the Prompt Template below).
542
+ 3. The worktree path set to the agent's isolated git worktree.
543
+ 4. ! **Background / non-blocking spawn** for any worker or poller whose loop runs longer than a short task (~3 min) — implementation, fix, and review-cycle workers — so the monitor conversation stays interactive (#1880 Gap D). Prefer `sessions_spawn` with the host's background / non-blocking flags (including optional `visible` when the operator needs an on-screen subagent).
544
+ 5. ! **Deliberate model routing (#1739):** resolve `(dispatch_provider=openclaw, worker_role)` via `task verify:routing` / `task swarm:routing-set` and pass `resolved_model` into the spawn when non-null — stamping the C2 manifest is prep; the recorded model MUST reach the actual spawn call.
545
+ 6. ! **Completion channel:** OpenClaw workers complete by parent push / announce (completion message back to the parent session). Do NOT poll via Grok Build's `get_command_or_subagent_output` or Cursor Task-complete semantics — those are other descriptors' channels.
546
+
547
+ ! **OpenClaw nested-spawn boundary (#2875 / #2893, analogue of Cursor #2797):** An OpenClaw implementation leaf MUST NOT nested-spawn a second-level review-monitor via `sessions_spawn` when nested sessions are unsupported or unreliable on the host. Prefer either (a) a `drive-to: merge-ready` leaf that owns a blocking dual-invoke `pr:watch` (`deft pr:watch` then `task deft:pr:watch`) in its own process, or (b) `stop-at: pr-open` with the dispatcher launching a sibling monitor and registering it via dual-invoke `review-monitor:register`. A leaf that backgrounds a monitor and exits MUST NOT claim monitoring is active.
548
+
549
+ ~ This is the first-class OpenClaw path. It is **Tier 1 → Approach 1** (a backgroundable sub-agent primitive), equivalent in tier to `start_agent` / Cursor `Task` / `spawn_subagent`; it MUST NOT be misclassified as `grok-build` or downgraded to a `generic-terminal` blocking poll. OpenClaw pollers whose loop runs > ~3 min MUST honour the sub-agent heartbeat contract (`docs/subagent-heartbeat.md`, #1166) via on-disk heartbeats (completion is still parent-announce, not Grok Build poll output).
550
+
551
+ ⊗ Treat OpenClaw `sessions_spawn` as Grok Build `spawn_subagent` or as `generic-terminal` — the primitives and completion channels differ (#2875).
534
552
 
535
553
  ## Phase 4 — Monitor
536
554
 
@@ -574,7 +592,7 @@ Track each agent through these stages:
574
592
 
575
593
  ### Takeover Triggers
576
594
 
577
- ! **Pre-spawn verification:** Before spawning a replacement agent, verify the original is truly unresponsive by waiting for an idle/blocked lifecycle event — verified via worktree state (`git status`, `git log --oneline -3`) and sub-agent lifecycle signals showing no in-flight work (for grok-build / spawn_subagent agents: polling is via worktree state + `get_command_or_subagent_output` rather than tab observation). Do NOT spawn a replacement based solely on message timing, absence of recent commits, or a perceived delay — original agents (Warp tabs or spawn_subagent processes) can resume after apparent failure, and spawning a new agent creates two concurrent agents on the same worktree (see Duplicate-Tab Failure Mode below).
595
+ ! **Pre-spawn verification:** Before spawning a replacement agent, verify the original is truly unresponsive by waiting for an idle/blocked lifecycle event — verified via worktree state (`git status`, `git log --oneline -3`) and sub-agent lifecycle signals showing no in-flight work (for grok-build / spawn_subagent agents: polling is via worktree state + `get_command_or_subagent_output` rather than tab observation; for openclaw / sessions_spawn agents: worktree state + parent completion announce / heartbeat records, not Grok Build poll output). Do NOT spawn a replacement based solely on message timing, absence of recent commits, or a perceived delay — original agents (Warp tabs, spawn_subagent processes, or OpenClaw sessions) can resume after apparent failure, and spawning a new agent creates two concurrent agents on the same worktree (see Duplicate-Tab Failure Mode below).
578
596
 
579
597
  ! Take over an agent's workflow if ANY of these occur:
580
598
 
@@ -587,18 +605,18 @@ When taking over: read the agent's current state (git log, diff, PR comments), c
587
605
 
588
606
  ### Duplicate-Agent Failure Mode (a.k.a. Duplicate-Tab Failure Mode)
589
607
 
590
- ⚠️ **Root cause of #261 and #263 (generalized for #1342 slice 3):** This is the **Duplicate-Agent Failure Mode** -- it fires on every platform descriptor, not just Warp tabs. Original Warp agent tabs may resume after apparent failure (network hiccup, temporary Warp UI freeze, context window pressure); the same failure mode applies to `spawn_subagent`-launched grok-build sub-agents that appear stalled but later resume. If the monitor spawns a new agent for the same worktree, two concurrent agents execute on the same branch simultaneously. This corrupts the `tool_use`/`tool_result` message chain — both agents issue tool calls, but responses are interleaved unpredictably, causing one or both agents to act on stale or incorrect state.
608
+ ⚠️ **Root cause of #261 and #263 (generalized for #1342 slice 3 / #2875):** This is the **Duplicate-Agent Failure Mode** -- it fires on every platform descriptor, not just Warp tabs. Original Warp agent tabs may resume after apparent failure (network hiccup, temporary Warp UI freeze, context window pressure); the same failure mode applies to `spawn_subagent`-launched grok-build sub-agents and OpenClaw `sessions_spawn` workers that appear stalled but later resume. If the monitor spawns a new agent for the same worktree, two concurrent agents execute on the same branch simultaneously. This corrupts the `tool_use`/`tool_result` message chain — both agents issue tool calls, but responses are interleaved unpredictably, causing one or both agents to act on stale or incorrect state.
591
609
 
592
610
  **Recovery guidance:**
593
- - ! Keep original agents active until their PR is merged — do not terminate agent processes that appear stalled (for Warp tabs: keep the tab open; for grok-build / spawn_subagent agents: verify via `get_command_or_subagent_output` before replacing)
594
- - ! If an agent appears stalled, attempt to resume it in its original context (for Warp: go to the original Warp tab and say "continue from where you left off"; for grok-build: re-query via `get_command_or_subagent_output` or send a resume message) rather than spawning a replacement
595
- - ! If the original agent is truly unrecoverable (Warp crash, tab closed, or spawn_subagent process terminated), only then create a new agent — and first verify the worktree state (`git status`, `git log`, `gh pr list`) to avoid conflicting with any in-flight work
611
+ - ! Keep original agents active until their PR is merged — do not terminate agent processes that appear stalled (for Warp tabs: keep the tab open; for grok-build / spawn_subagent agents: verify via `get_command_or_subagent_output` before replacing; for openclaw / sessions_spawn: verify via heartbeat + absence of parent completion announce)
612
+ - ! If an agent appears stalled, attempt to resume it in its original context (for Warp: go to the original Warp tab and say "continue from where you left off"; for grok-build: re-query via `get_command_or_subagent_output` or send a resume message; for openclaw: re-announce / resume the same session rather than spawning a replacement) rather than spawning a replacement
613
+ - ! If the original agent is truly unrecoverable (Warp crash, tab closed, spawn_subagent process terminated, or OpenClaw session ended without recovery), only then create a new agent — and first verify the worktree state (`git status`, `git log`, `gh pr list`) to avoid conflicting with any in-flight work
596
614
 
597
615
  ### Context-Length Warning
598
616
 
599
617
  ! Long monitoring sessions accumulate large conversation history (hundreds of tool_use/tool_result pairs) and are susceptible to conversation corruption — the tool_use/tool_result mismatch observed in #263 occurred at approximately message 158 in a single monitor conversation. To mitigate:
600
618
 
601
- - ! Offload rebase, review-watch, and merge sub-tasks to ephemeral sub-agents using the tiered approach from `skills/deft-directive-review-cycle/SKILL.md` (spawn via the platform adapter's dispatch primitive when available (e.g. `spawn_subagent` for Grok Build), discrete tool calls with yield otherwise) — this keeps the monitor conversation shallow
619
+ - ! Offload rebase, review-watch, and merge sub-tasks to ephemeral sub-agents using the tiered approach from `skills/deft-directive-review-cycle/SKILL.md` (spawn via the platform adapter's dispatch primitive when available e.g. `spawn_subagent` for Grok Build, Cursor `Task`, or OpenClaw `sessions_spawn` for descriptor `openclaw` — discrete tool calls with yield otherwise) — this keeps the monitor conversation shallow
602
620
  - ~ Target <100 tool-call round-trips in any single monitor conversation before considering a fresh session handoff
603
621
  - ! If the monitor detects degraded output (repeated errors, inconsistent state references, tool call failures), stop and hand off to a fresh session with a state summary rather than continuing in a corrupted context
604
622
 
@@ -611,7 +629,16 @@ For each agent's PR:
611
629
  1. ! Check that Greptile has reviewed the latest commit (compare "Last reviewed commit" SHA to branch HEAD)
612
630
  2. ! Verify Greptile confidence score > 3
613
631
  3. ! Verify no P0 or P1 issues remain (P2 are non-blocking style suggestions)
614
- 4. ! **Worker-owns-lifecycle fallback (#1880):** Prefer workers scoped `drive-to: merge-ready` so this step is rare. When a worker exits at PR-open without reaching merge-ready, the monitor MAY run `skills/deft-directive-review-cycle/SKILL.md` itself or dispatch ONE review-cycle owner — but MUST NOT split review polling and fix batches across separate leaf agents for the same PR (#727 + #1880 Gap C).
632
+ 4. ! **Blocked-leaf continuation (#1880 / #2843):** Prefer workers scoped `drive-to: merge-ready` so this step is rare. When a leaf exits `BLOCKED` (or a false-terminal DONE-with-blockers see `templates/agent-prompt-preamble.md` §11) before merge-ready:
633
+ - **Tier 1 available** (`start_agent`, `spawn_subagent`, Cursor `Task`, OpenClaw `sessions_spawn`): the monitor MUST background-dispatch ONE continuation leaf (`drive-to: merge-ready`, same worktree) owning fix batches + blocking `task pr:watch` + merge readiness. The monitor MUST NOT run inline code edits or review-cycle fix batches in its own turn (#2843 monitor-as-implementer recurrence).
634
+ - **Tier 3 only** (no sub-agent primitive): the monitor MAY run `skills/deft-directive-review-cycle/SKILL.md` itself after explicit operator consent — or offer serial self-execution downgrade from Phase 3.
635
+ - ⊗ Split review polling and fix batches across separate leaf agents for the same PR (#727 + #1880 Gap C).
636
+
637
+ ! **Completion-notification decision tree (#2843):** When a background leaf completion notification arrives, parse the terminal message per preamble §11:
638
+ - `DONE` + merge-ready verified (`task pr:merge-ready -- <N>` exit 0): may proceed to merge / `task scope:complete` per Phase 5→6 / Phase 6.
639
+ - `BLOCKED` (+ optional `REDISPATCH_OK`): resume the same leaf if the host supports it, OR background-dispatch ONE continuation leaf with the cited PR/SHA/worktree — no monitor-inline fixes on Tier 1.
640
+ - `FAILED` / silent (no terminal message): run `task verify:subagent-alive`; on exit 1 print `REDISPATCH_OK` and background-dispatch ONE continuation leaf.
641
+ - ⊗ Treat `DONE` without merge-ready verification as success — that is the false-terminal pattern §11 closes.
615
642
 
616
643
  ### Complete xBRIEFs
617
644
 
@@ -632,13 +659,15 @@ All PRs meet ALL of:
632
659
 
633
660
  ! **Mandatory cohort verifier (#1364):** After every poller (Phase 6 review-cycle sub-agent) reports back, the monitor MUST run `task swarm:verify-review-clean -- <pr-numbers...>` and confirm exit 0 BEFORE evaluating the rest of the Exit Condition or surfacing the Phase 5 -> 6 gate. The verifier re-uses the Greptile rolling-summary parser from `task pr:merge-ready` so the per-PR merge gate and the cohort gate stay in lockstep (a parser fix lands in both surfaces at once). Exit codes: 0 (cohort CLEAN -- all PRs simultaneously have SHA match + confidence > 3 + zero P0/P1 + not errored on current HEAD); 1 (one or more PRs unclean with per-PR diagnostics -- re-dispatch the poller for the unclean PR or address findings, then re-run the verifier); 2 (config error -- empty cohort, malformed xBRIEF glob, gh missing). The verifier is the structural answer to the #1166 swarm execution recurrence where multiple pollers exited with `clean_gate_holdout=confidence` (confidence == 3) and the monitor still raised the Phase 5 -> 6 gate because the trigger keyed on "all pollers have reported back" rather than "every PR in the cohort is objectively CLEAN".
634
661
 
635
- ! **Deterministic PR-verdict wait (#1056):** When a Phase 5 monitor needs to wait on Greptile/SLizard for an in-flight PR (cascade rebase + re-review, late Greptile pass), use `task pr:watch -- <N> [--repo <owner>/<repo>]` as the canonical wait-until-verdict helper. Blocking-by-default poll to a terminal three-state verdict exit `0` CLEAN, `1` NEW_P0_P1, `2` ERRORED|STALL|TIMEOUT|config — with `--one-shot` for a single probe, `--json` for the structured shape, and `--max-wait-minutes` / `--poll-seconds` for the budget (defaults 30m / 90s). SHA-match gates the verdict to the current HEAD. For mergeable+merge cascade automation (not Greptile verdict alone), use `task pr:wait-mergeable-and-merge` (#1369); for adaptive merge-ready polling with layered `via` fallbacks, use `task pr:merge-ready` / `task pr:monitor` (#1368).
662
+ ! **Gates-surface dual invoke (#2893):** Deep-think gate verbs follow review-cycle probe order — `deft <verb>` / `directive <verb>` first, then `task deft:<verb>` when the root Taskfile includes `.deft/core/Taskfile.yml`, then #2878 gh-only fallback. Bare `task pr:watch` is not the sole consumer form (include key `deft:` namespaced tasks only).
663
+
664
+ ! **Deterministic PR-verdict wait (#1056 / #2893):** When a Phase 5 monitor needs to wait on Greptile/SLizard for an in-flight PR (cascade rebase + re-review, late Greptile pass), use dual-invoke `pr:watch` — `deft pr:watch <N> [--repo <owner>/<repo>]` first (no go-task bare `--`), else `task deft:pr:watch -- <N> [...]` — as the canonical wait-until-verdict helper. Blocking-by-default poll to a terminal three-state verdict — exit `0` CLEAN, `1` NEW_P0_P1, `2` ERRORED|STALL|TIMEOUT|config — with `--one-shot` for a single probe, `--json` for the structured shape, and `--max-wait-minutes` / `--poll-seconds` for the budget (defaults 30m / 90s). SHA-match gates the verdict to the current HEAD. For mergeable+merge cascade automation (not Greptile verdict alone), use dual-invoke `pr:wait-mergeable-and-merge` (#1369); for adaptive merge-ready polling with layered `via` fallbacks, use dual-invoke `pr:merge-ready` / `pr:monitor` (#1368).
636
665
 
637
- ! **Fallback-chain discriminator semantics (#1368):** `task pr:merge-ready -- <N> --json` ALWAYS emits a `via` discriminator on every response. `via="primary"` and `via="fallback1"` are authoritative -- a `merge_ready: true` verdict on either is CLEAN. `via="fallback2"` is the coarse PR-view + check-run last-resort signal: it surfaces the PR's `state` / `merged` / `mergeable` / flattened check-run summary so a monitor can keep stepping forward through transient gh failures, but it is NEVER CLEAN -- the failure list carries the sentinel `"fallback2 is a coarse signal, not a CLEAN verdict ..."` and the merge cascade MUST keep waiting for a primary/fallback1 CLEAN. `via="error"` (every layer failed) is also non-CLEAN; the response carries `error` (one-line summary) + `partial_data` (per-layer diagnostics) so the monitor can step forward without blinding. Both `task swarm:verify-review-clean` and `task pr:merge-ready` treat fallback2 and error as merge-blocked.
666
+ ! **Fallback-chain discriminator semantics (#1368):** dual-invoke `pr:merge-ready -- <N> --json` ALWAYS emits a `via` discriminator on every response. `via="primary"` and `via="fallback1"` are authoritative -- a `merge_ready: true` verdict on either is CLEAN. `via="fallback2"` is the coarse PR-view + check-run last-resort signal: it surfaces the PR's `state` / `merged` / `mergeable` / flattened check-run summary so a monitor can keep stepping forward through transient gh failures, but it is NEVER CLEAN -- the failure list carries the sentinel `"fallback2 is a coarse signal, not a CLEAN verdict ..."` and the merge cascade MUST keep waiting for a primary/fallback1 CLEAN. `via="error"` (every layer failed) is also non-CLEAN; the response carries `error` (one-line summary) + `partial_data` (per-layer diagnostics) so the monitor can step forward without blinding. Both `swarm:verify-review-clean` and `pr:merge-ready` treat fallback2 and error as merge-blocked.
638
667
 
639
- ⊗ Surface or discuss the Phase 5 -> 6 merge cascade gate while `task swarm:verify-review-clean` has not yet exited 0 on the current cohort (#1364). Keying the transition on poller lifecycle completion alone -- i.e. treating "every poller sub-agent returned a terminal message" as sufficient -- is the exact recurrence pattern this rule closes. The verifier is the only authoritative cohort-level CLEAN signal; a poller's `clean_gate_holdout=confidence` / `clean_gate_holdout=has_blocking` / `clean_gate_holdout=sha_match` / `clean_gate_holdout=errored` exit IS a non-CLEAN report and MUST hold the gate even if every sub-agent has technically returned.
668
+ ⊗ Surface or discuss the Phase 5 -> 6 merge cascade gate while `swarm:verify-review-clean` has not yet exited 0 on the current cohort (#1364). Keying the transition on poller lifecycle completion alone -- i.e. treating "every poller sub-agent returned a terminal message" as sufficient -- is the exact recurrence pattern this rule closes. The verifier is the only authoritative cohort-level CLEAN signal; a poller's `clean_gate_holdout=confidence` / `clean_gate_holdout=has_blocking` / `clean_gate_holdout=sha_match` / `clean_gate_holdout=errored` exit IS a non-CLEAN report and MUST hold the gate even if every sub-agent has technically returned.
640
669
 
641
- ! **Review-monitor gate (#2655 / #1386):** Before surfacing the Phase 5→6 merge gate (or yielding while implementers' PRs await Greptile), run `task verify:review-monitor -- --pr <N> [--call-site swarm-phase5-6]` for each in-flight PR when Tier 1 is available. Register monitors after spawning Approach 1 pollers via `task review-monitor:register`. Do not duplicate the monitoring matrix here — see `skills/deft-directive-review-cycle/SKILL.md` Review Monitoring + the verify verb.
670
+ ! **Review-monitor gate (#2655 / #1386 / #2893):** Before surfacing the Phase 5→6 merge gate (or yielding while implementers' PRs await Greptile), run dual-invoke `verify:review-monitor` for each in-flight PR when Tier 1 is available — CLI: `deft verify:review-monitor --pr <N> [--call-site swarm-phase5-6]`; task: `task deft:verify:review-monitor -- --pr <N> [--call-site swarm-phase5-6]`. Register monitors after spawning Approach 1 pollers via dual-invoke `review-monitor:register` (same CLI-without-`--` vs task-with-`--` rule). Do not duplicate the monitoring matrix here — see `skills/deft-directive-review-cycle/SKILL.md` Review Monitoring + gates-surface dual invoke.
642
671
 
643
672
  ⊗ Treat a `via="fallback2"` or `via="error"` response from `task pr:merge-ready` as CLEAN, regardless of the surrounding `merge_ready` field (#1368). Fallback2 is structurally never CLEAN -- the Greptile rolling-summary comment was unreachable on both the primary and fallback1 paths, so any merge taken on the basis of the coarse signal alone bypasses the SUCCESS-with-findings blind spot the per-PR gate was designed to close (#796 / #652). The merge cascade MUST keep waiting for a primary/fallback1 CLEAN.
644
673
 
@@ -681,7 +710,7 @@ All PRs meet ALL of:
681
710
 
682
711
  ! **Sub-agents MUST emit a heartbeat (#1365):** every long-running review-cycle / poller sub-agent dispatched under Phase 6 MUST write a heartbeat record to `.deft-scratch/subagent-status/<agent-id>.json` per the contract in `docs/subagent-heartbeat.md`. The canonical poller template (`templates/swarm-greptile-poller-prompt.md` bounded poll loop) already encodes the per-iteration heartbeat write and the final terminal heartbeat, and the canonical orchestrator preamble (`templates/agent-prompt-preamble.md` § 10.5) restates the contract for any non-poller long-running sub-agent. The monitor watches via `task agent:monitor` -- see Phase 4 Heartbeat liveness check. Without the heartbeat, a `spawn_subagent`-dispatched poller that stalls is indistinguishable from a healthy mid-poll one (the #1166 recurrence).
683
712
 
684
- ! **Post-PR monitoring runs in a fresh sub-agent (#727):** Post-PR monitoring (Greptile, CI checks, downloadCount drift, lifecycle events, etc.) MUST be done by spawning a fresh short-lived sub-agent via the platform adapter's dispatch primitive for the detected runtime (e.g. `spawn_subagent` when the Grok Build / non-Warp platform is active, `start_agent` for Warp-orchestrated environments). The parent yields with no tool calls and waits for the sub-agent's messages -- this preserves conversation steerability so the user can interrupt or redirect while the watch is pending. The platform adapter (introduced in slices 1-3 of #1342) supplies the appropriate async callback channel and spawn surface per the runtime capability detection matrix; every Taskfile / shell-sleep / `time.sleep` / synchronous tool-call alternative blocks the parent's turn for the duration of the watch.
713
+ ! **Post-PR monitoring runs in a fresh sub-agent (#727):** Post-PR monitoring (Greptile, CI checks, downloadCount drift, lifecycle events, etc.) MUST be done by spawning a fresh short-lived sub-agent via the platform adapter's dispatch primitive for the detected runtime (e.g. `spawn_subagent` when the Grok Build / non-Warp platform is active, `start_agent` for Warp-orchestrated environments, Cursor `Task` for Cursor, OpenClaw `sessions_spawn` when the platform descriptor is `openclaw` — #2875). The parent yields with no tool calls and waits for the sub-agent's messages / parent-announce completion -- this preserves conversation steerability so the user can interrupt or redirect while the watch is pending. The platform adapter (introduced in slices 1-3 of #1342; OpenClaw Tier-1 in #2875) supplies the appropriate async callback channel and spawn surface per the runtime capability detection matrix; every Taskfile / shell-sleep / `time.sleep` / synchronous tool-call alternative blocks the parent's turn for the duration of the watch.
685
714
 
686
715
  ! **Canonical poller template (#727):** When delegating to a poller / review-cycle sub-agent, MUST use the canonical poller-prompt template at `templates/swarm-greptile-poller-prompt.md` with placeholders (`{pr_number}`, `{repo}`, `{poll_interval_seconds}`, `{poll_cap_minutes}`, `{parent_agent_id}`) filled in. Do NOT hand-author per-watch prompts -- the template encodes parsing fixes (markdown-link `Last reviewed commit:` regex, badge-based / negation-aware P0/P1 detection) that hand-authored variants have repeatedly missed (Agent D, post-#721 swarm; #727 comment 2).
687
716
 
@@ -733,11 +762,11 @@ If any protected (umbrella / staying-OPEN) issue number appears in the output, t
733
762
 
734
763
  ! **Greptile re-review on rebase force-push:** Force-pushing a rebased branch triggers a **full** Greptile re-review (not an incremental diff), even if the rebase introduced no logic changes. Expected latency is ~2-5 minutes per PR in the cascade. Factor this into merge sequencing.
735
764
 
736
- ! **Autonomous re-review monitoring after force-push:** After each `--force-with-lease` push of a rebased branch in the cascade, the monitor MUST autonomously wait for the Greptile re-review to complete before proceeding to the next merge. Use the tiered monitoring approach defined in `skills/deft-directive-review-cycle/SKILL.md` Step 4 Review Monitoring (Approach 1: spawn sub-agent via the platform adapter's dispatch primitive (e.g. `spawn_subagent` or `start_agent`) to poll and report back; Approach 2 fallback: discrete `run_shell_command` wait-mode calls with yield between polls, adaptive cadence -- see deft-directive-review-cycle SKILL.md). Do NOT duplicate the full monitoring logic here -- follow the canonical skill.
765
+ ! **Autonomous re-review monitoring after force-push:** After each `--force-with-lease` push of a rebased branch in the cascade, the monitor MUST autonomously wait for the Greptile re-review to complete before proceeding to the next merge. Use the tiered monitoring approach defined in `skills/deft-directive-review-cycle/SKILL.md` Step 4 Review Monitoring (Approach 1: spawn sub-agent via the platform adapter's dispatch primitive (e.g. `spawn_subagent`, `start_agent`, Cursor `Task`, or OpenClaw `sessions_spawn`) to poll and report back; Approach 2 fallback: discrete `run_shell_command` wait-mode calls with yield between polls, adaptive cadence -- see deft-directive-review-cycle SKILL.md). Do NOT duplicate the full monitoring logic here -- follow the canonical skill.
737
766
 
738
- ! **Review-monitor gate after force-push (#2655 / #380):** After each cascade force-push, run `task verify:review-monitor -- --pr <N> --call-site swarm-phase6-cascade` before yielding for re-review when Tier 1 is available. Spawn/register Approach 1 pollers per review-cycle skill; do not yield idle without an active monitor record.
767
+ ! **Review-monitor gate after force-push (#2655 / #380 / #2893):** After each cascade force-push, run dual-invoke `verify:review-monitor` (CLI: `deft verify:review-monitor --pr <N> --call-site swarm-phase6-cascade`; task: `task deft:verify:review-monitor -- --pr <N> --call-site swarm-phase6-cascade`) before yielding for re-review when Tier 1 is available. Spawn/register Approach 1 pollers per review-cycle skill; do not yield idle without an active monitor record.
739
768
 
740
- ~ **In-cascade Greptile wait (#1056):** For the wait between a force-push and the next merge, poll the Greptile/SLizard verdict with `task pr:watch -- <N> [--repo <owner>/<repo>] [--max-wait-minutes <M>]` (exit `0` CLEAN / `1` NEW_P0_P1 / `2` ERRORED|STALL|TIMEOUT|config). Do not use `--cap-minutes` — that flag belongs to `task pr:monitor`, not `pr:watch`. For the composed wait-until-mergeable-then-merge path, use `task pr:wait-mergeable-and-merge` (#1369). Use these in place of hand-rolled polling loops in long-running cascade waits.
769
+ ~ **In-cascade Greptile wait (#1056 / #2893):** For the wait between a force-push and the next merge, poll the Greptile/SLizard verdict with dual-invoke `pr:watch` (`deft pr:watch <N> [...]` first, else `task deft:pr:watch -- <N> [--repo <owner>/<repo>] [--max-wait-minutes <M>]`) (exit `0` CLEAN / `1` NEW_P0_P1 / `2` ERRORED|STALL|TIMEOUT|config). Do not use `--cap-minutes` — that flag belongs to `pr:monitor`, not `pr:watch`. For the composed wait-until-mergeable-then-merge path, use dual-invoke `pr:wait-mergeable-and-merge` (#1369). Use these in place of hand-rolled polling loops in long-running cascade waits.
741
770
 
742
771
  ! **Cascade automation surface (#1369 / #2385):** The canonical one-verb compose-point for "wait until PR <N> is mergeable, then squash-merge with admin" is `task pr:wait-mergeable-and-merge -- <N> --repo <owner>/<repo>`. The helper runs the resilient wait loop (#1368) and the Layer-3 protected-issue link inspection (#701) AHEAD of any merge call, then invokes `gh pr merge <N> --squash --delete-branch --admin` only after the wait loop exits CLEAN on the current HEAD. Three-state exit (0 merged / 1 timeout-or-escalation / 2 config error) mirrors every other framework verb. Pass `--protected <issue-numbers>` for the Layer-3 chain when the PR is known to reference any umbrella / staying-OPEN issue -- the helper short-circuits with exit 1 BEFORE the merge call if a persistent `closingIssuesReferences` link is detected. For multi-PR merge cascades (Phase 6), pass --cascade so the helper refuses merge-tree-clean PRs whose base SHA is behind the current target branch HEAD (semantically stale pre-spine CI, #2385); after the first merge in a cascade, also pass --require-master-ci-green so the next merge waits until target-branch CI is green at the new HEAD. Rebase/update-branch onto the post-spine target before re-invoking with --cascade. The Wave-3 surface is the automated cascade wrapper; the per-PR atomic gate (`task pr:merge-ready -- <N> && gh pr merge <N>`) documented above remains the manual freshness-window-atomic check the monitor MUST use when running merges by hand. The two co-exist -- the cascade surface is the automation, the per-PR atomic gate is the manual fall-through. See AGENTS.md `## Cascade automation surface (#1369)`.
743
772
 
@@ -1023,4 +1052,6 @@ CONSTRAINTS:
1023
1052
  - ⊗ Assume parent-shell `gh auth status` proves a worker sandbox can authenticate or reach GitHub — always run `task verify:gh-auth` from the worker envelope and surface full-access execution, trusted `gh` allowlisting, or injected-token handoff when sandbox auth fails (#1557)
1024
1053
  - ⊗ Present Cursor sandbox UID 0 or sandbox-root cwd ownership as host-root access — `sandbox_uid_remap` means the sandbox identity is remapped to the host user, not real root (#1557)
1025
1054
  - ⊗ Fall through to the manual-terminal fallback (Step 2b) when spawn_subagent is available -- Step 2d is the first-class grok-build launch path; manual terminal is for environments with no orchestration primitive at all (#1331)
1055
+ - ⊗ Misclassify OpenClaw `sessions_spawn` as `grok-build` / `spawn_subagent` or fall through to `generic-terminal` when `sessions_spawn` is present — Step 2f is the first-class OpenClaw path and descriptor `openclaw` is Tier 1 (#2875)
1056
+ - ⊗ Hardcode Cursor/Warp/grok-only launch, monitor, or Phase 6 post-PR dispatch branches when the platform descriptor is `openclaw` — use `sessions_spawn` and the openclaw completion channel (#2875)
1026
1057
  - ⊗ Surface, propose, or discuss the Phase 5 -> 6 merge cascade gate while `task swarm:verify-review-clean -- <pr-numbers...>` has not yet exited 0 on the current cohort (#1364). Keying the transition on poller lifecycle completion alone -- i.e. treating "every poller sub-agent returned a terminal message" as sufficient to surface the merge gate -- is the recurrence pattern from the #1166 swarm execution where multiple pollers exited with `clean_gate_holdout=confidence` (confidence == 3) and the monitor still raised the Phase 5 -> 6 gate. The cohort verifier is the only authoritative CLEAN signal at the cohort level; a poller's `clean_gate_holdout=*` exit IS a non-CLEAN report and MUST hold the gate even when every sub-agent has technically returned