@deftai/directive-content 0.91.0 → 0.92.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.
@@ -55,7 +55,7 @@ On repos with `.deft/core/` installed, **PR shepherding intent** routes here --
55
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
56
 
57
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.
58
+ - ! Prefer a **visible** Control UI subagent (`visible:true` when the tool surface allows) when OpenClaw Control UI is the operator control plane so humans can inspect the monitor (#3044; invisible empty settles are higher FC04 residual risk).
59
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
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
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.
@@ -362,7 +362,7 @@ Remediation:
362
362
 
363
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
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.
365
+ ~ **Visible Control UI (OpenClaw / #3044):** When OpenClaw Control UI is the operator control plane, SHOULD spawn the review-monitor with `visible:true` when the tool surface allows so humans can inspect progress without attaching to the parent session; invisible empty settles are higher FC04 residual risk.
366
366
 
367
367
  ! When the platform descriptor indicates Tier 1 (sub-agent support), spawn a review-monitor sub-agent using the primitive matching the descriptor:
368
368
 
@@ -374,6 +374,51 @@ Remediation:
374
374
 
375
375
  ⊗ Use OpenClaw `cron` alone as Approach 1 when `sessions_spawn` is available — cron is Approach 2 scheduler fallback only (#2876).
376
376
 
377
+ ### Empty announce ≠ done (parent DoD) (#3044 / FC04 residual)
378
+
379
+ ! When a review-monitor settle arrives with **empty body**, **missing `STATUS:` line**, or **status unknown** (including host `(no output)` / empty `subagent_announce`):
380
+
381
+ 1. ! The parent MUST run **same-turn ground truth** before any DONE / CLEAN / merge-ready claim: at least `gh pr view <N>` (or REST `pulls/<N>`), `gh pr checks <N>`, and current HEAD SHA (`gh api repos/<owner>/<repo>/pulls/<N> -q .head.sha`).
382
+ 2. ! Classify the settle as **FC04 residual** (empty babysit ≠ done) until ground truth shows a terminal merge/close outcome **or** an explicit structured `BLOCKED` / `FAILED` handback.
383
+ 3. ⊗ Treat empty / unknown settle as `DONE`, `CLEAN`, merge-ready, or batch-complete.
384
+ 4. ⊗ Spawn a second review-monitor solely because the first settle was empty/unknown without completing the ground-truth batch first (#3044 dual-lease recurrence).
385
+
386
+ ~ Recurrence: enterprize PR #43 (2026-08-02) — first monitor polled live, host settled empty/unknown; parent spawned a second same-`taskName` monitor; dual lease collision while PR stayed open. See also `meta/lessons.md` and FC04 / growth friction R1 + R10.
387
+
388
+ ### Single review-monitor lease (#3044 / #2814)
389
+
390
+ ! **One sticky lease per PR:** ownership is the single sticky GitHub PR comment `<!-- deft:review-owner -->` (or the dual-invoke `review-monitor:register` form that writes it). Parallel ownership is forbidden.
391
+
392
+ ! **Pre-spawn check:** before launching another Approach 1 review-monitor (`sessions_spawn`, `spawn_subagent`, Cursor `Task`, `start_agent`):
393
+
394
+ 1. ! Read the sticky lease (dual-invoke `verify:review-monitor` when available, else `gh api` issues comments for `<!-- deft:review-owner -->`).
395
+ 2. ! List active same-PR / same-`taskName` subagents when the host exposes that surface (OpenClaw `subagents list` or equivalent).
396
+ 3. ⊗ Spawn a second monitor while a prior owner is **running**.
397
+ 4. ⊗ Spawn a second monitor when the last settle was **empty/unknown** and ground truth has **not** shown a terminal merge/close (or explicit structured handback that releases ownership).
398
+ 5. ! If the prior owner is **dead** (liveness fail / `REDISPATCH_OK` / `verify:subagent-alive` exit 1) and the PR is still open: spawn **one** replacement monitor and re-claim the lease with **`--force`** (CLI: `deft review-monitor:register --pr <N> --monitor-agent-id <id> --force` / task: `task review-monitor:register -- --pr <N> --monitor-agent-id <id> --force`, or host equivalent force takeover) so a non-expired foreign lease does not block replacement — then **update** the sticky lease comment to the new owner. Never silent dual ownership.
399
+ 6. ! On register conflict when the prior owner is **still alive**: attach to the existing owner or stop — do not parallel-fix.
400
+ 7. ⊗ Refuse replacement of a dead owner solely because the 30-minute lease has not expired without attempting force takeover (#3044).
401
+
402
+ ### Required non-empty monitor handback (#3044)
403
+
404
+ ! Approach 1 review-monitor prompts (including `templates/swarm-greptile-poller-prompt.md` and any host-filled spawn prompt) MUST require a **non-empty** final handback with these fields:
405
+
406
+ ```text
407
+ STATUS: DONE|BLOCKED|FAILED
408
+ HEAD: <sha>
409
+ CHECKS: <summary>
410
+ MERGE: <url|error|n/a>
411
+ ISSUE: <closed|open|n/a>
412
+ NOTES: <short>
413
+ ```
414
+
415
+ ⊗ Empty final assistant message from a review-monitor.
416
+ ⊗ Parent treating a settle that lacks `STATUS:` as success.
417
+
418
+ ~ **Visible Control UI risk (#3044):** When OpenClaw Control UI is the operator plane, prefer `visible:true` on the review-monitor spawn; invisible empty settles are higher risk for FC04 misclassification. Cross-link: `skills/deft-directive-swarm/references/host-openclaw.md` Babysit / review-monitor residual.
419
+
420
+
421
+
377
422
  **Approach 2 (fallback -- no sub-agent primitive for the descriptor):**
378
423
 
379
424
  ! 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.
@@ -566,3 +611,6 @@ task lifecycle:event -- emit plan:approved \
566
611
  - ⊗ Activate Approach 3 (blocking `Start-Sleep` loop) without first warning the user that it will lock the conversation pane and receiving confirmation
567
612
  - ⊗ Exit the review loop on a Greptile confidence number alone while the check run is non-terminal -- a confidence score is NOT a verdict without a terminal check-run (`completed` + `{success, neutral}`) AND a HEAD-matching `Last reviewed commit:` completion marker (#1259)
568
613
  - ⊗ Call `gh pr merge` on cached/earlier review state without an immediately-preceding pre-merge re-poll that re-satisfies the Step 6 fail-closed all-of (#1259)
614
+ - ⊗ Treat empty/unknown review-monitor settle as DONE/CLEAN/merge-ready without same-turn ground truth (#3044 / FC04 residual)
615
+ - ⊗ Spawn a second review-monitor while prior owner is running or last settle was empty/unknown without terminal ground truth (#3044)
616
+ - ⊗ Accept empty review-monitor final message missing STATUS/HEAD/CHECKS/MERGE handback (#3044)
@@ -23,6 +23,7 @@ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
23
23
  - User says "set up deft", "configure deft", or "bootstrap my project"
24
24
  - User asks to create USER.md, PROJECT-DEFINITION.xbrief.json, or a specification
25
25
  - User clones a deft-enabled repo for the first time with no config
26
+ - User says "revisit experimental rules", "toggle experimental meta", "enable SOUL", "disable morals", or wants to change Experimental Rules after bootstrap (#46)
26
27
 
27
28
  ## Opt-out flag (`.no-deft-directive`) (#2926)
28
29
 
@@ -194,12 +195,28 @@ VBA (Excel macros), VHDL, Visual Basic (.NET), Zig, 6502-DASM
194
195
  2. ! If `deft_version` is present but **differs from the current framework version** (0.20.0): check whether any expected fields are missing from the USER.md
195
196
  3. ! If fields are missing: query the user for each missing field individually -- do NOT re-run the full Phase 1 interview
196
197
  4. ! After completing any field queries (even if none were needed), write the current `deft_version` (0.20.0) to USER.md
197
- 5. ~ If `deft_version` matches the current version and all expected fields are present: no action needed (USER.md is fresh)
198
+ 5. ~ If `deft_version` matches the current version and all expected fields are present: USER.md is fresh — do **not** re-run Phase 1. ! Still offer the **Returning-user re-entry** menu below so the operator can revisit Experimental Rules or continue to Phase 2 without a full re-interview (#46).
198
199
 
199
200
  Expected USER.md fields: **Name**, **Custom Rules**, **Default Strategy**, and optionally **Coverage** and **Experimental Rules**.
200
201
 
201
202
  ⊗ Re-run the full Phase 1 interview when only individual fields are missing from a stale USER.md -- query missing fields individually instead.
202
203
 
204
+ ### Returning-user re-entry (#46)
205
+
206
+ ! When USER.md already exists (fresh or after individual missing-field fill), present a deterministic numbered menu before assuming Phase 1 is "done and silent":
207
+
208
+ > "USER.md is in place. What next?"
209
+ > 1. Continue to Phase 2 (project configuration) ★ (recommended when project config is still missing)
210
+ > 2. **Revisit experimental rules** — enable/disable SOUL / morals / code-field without hand-editing schema
211
+ > 3. Not now (exit setup)
212
+ > 4. Discuss
213
+ > 5. Back
214
+
215
+ - ! Final two numbered options MUST be `Discuss` and `Back` per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md)
216
+ - ! On option 2, enter **Revisit experimental rules** (next section) — not a full Phase 1 re-interview
217
+ - ⊗ Silently skip past a complete USER.md with no re-entry offer when the operator entered setup (or asked to configure preferences)
218
+ - ⊗ Invent a `deft config` / `task config:*` verb family for this slice — setup skill re-entry is the product surface (#46)
219
+
203
220
  ### Interview Rules
204
221
 
205
222
  ! This phase follows the deterministic interview loop defined in `skills/deft-directive-interview/SKILL.md`. The core rules (one question per turn, numbered options with stated default, explicit "other" escape, depth gate, default acceptance, confirmation gate, structured handoff) apply here. Key points repeated for emphasis:
@@ -307,6 +324,89 @@ for project-scoped settings (strategy, coverage).
307
324
 
308
325
  ---
309
326
 
327
+ ## Revisit experimental rules (#46)
328
+
329
+ **Goal:** Guided enable/disable of USER.md **Experimental Rules** entries that *reference* framework deposit meta files (`meta/SOUL.md`, `meta/morals.md`, `meta/code-field.md`). This is a post-bootstrap return path — not Phase 1 bootstrap, not a general preferences UI, and not an editor for framework meta file bodies.
330
+
331
+ ### When to enter
332
+
333
+ - Returning-user re-entry option **Revisit experimental rules**
334
+ - Direct user ask: "revisit experimental rules", "toggle experimental meta", "turn on SOUL", "disable code-field", etc.
335
+ - USER.md exists and is complete enough to edit (Name present); missing non-meta fields still use Freshness Detection individual queries first
336
+
337
+ ### Out of scope
338
+
339
+ - ⊗ General preferences UI / rewriting Personal or Defaults sections as part of this path
340
+ - ⊗ Editing framework `meta/*.md` content (deposit owns SOUL / morals / code-field bodies; `directive update` refreshes deposit)
341
+ - ⊗ Deposit layout changes
342
+ - ⊗ Inventing a full `deft config` mega-surface or new `task config:*` verb family for this slice
343
+ - ⊗ Re-building USER.md bootstrap / non-overwrite semantics
344
+ - ⊗ Treating Experimental Rules lines as project-local copies of meta files — they are **references** only
345
+
346
+ ### Flow
347
+
348
+ ! **Each message MUST contain exactly ONE question** (same interview rule as Phase 1).
349
+
350
+ 1. ! Resolve USER.md via Platform Detection (`$DEFT_USER_PATH` → platform path). Read the file as **UTF-8**.
351
+ 2. ! Parse current Experimental Rules state (on/off) for the three paths:
352
+ - `meta/SOUL.md`
353
+ - `meta/morals.md`
354
+ - `meta/code-field.md`
355
+ - Detection: any line containing that path counts as **on** (custom wording still counts).
356
+ 3. ! Show a **current state** summary (table or short list), for example:
357
+
358
+ | Entry | State | Role |
359
+ |-------|-------|------|
360
+ | SOUL.md | on/off | Results-first agent persona |
361
+ | morals.md | on/off | Epistemic honesty |
362
+ | code-field.md | on/off | Pre-code assumption protocol |
363
+
364
+ 4. ! Ask which entry to change with a deterministic numbered menu (one question). Options MUST include each of the three entries as toggle targets, plus **Done (save)** / **Done (discard)**, and final two options `Discuss` and `Back`:
365
+
366
+ > "Toggle which experimental meta entry? (current state shown above)"
367
+ > 1. SOUL.md — currently {on|off}
368
+ > 2. morals.md — currently {on|off}
369
+ > 3. code-field.md — currently {on|off}
370
+ > 4. Done — save changes
371
+ > 5. Done — discard changes
372
+ > 6. Discuss
373
+ > 7. Back
374
+
375
+ 5. ! When the user picks an entry (1–3), optionally show the short Phase 1 explainer (steps **5a–5c** copy below), then confirm the new on/off value with a Y/n or numbered keep/flip menu. Update the **in-memory** desired state; do not write yet. Return to the toggle menu (step 4) until Done.
376
+ 6. ! On **Done — save**: show a confirmation summary of the three final on/off values and require explicit affirmative (`yes` / `confirmed` / `approve`) before write — same Post-Interview Confirmation Gate strictness.
377
+ 7. ! On **Done — discard** or **Back** without save: leave USER.md unchanged and return to the Returning-user re-entry menu (or exit if invoked directly).
378
+
379
+ ### Explainers (reuse Phase 1 steps 5a–5c)
380
+
381
+ - **SOUL.md** — Results-first agent persona (inspired by Winston Wolf). Enforces assess-before-acting, finish-what-you-start, right-tool-for-the-job, and play-the-long-game. Keeps the AI decisive and concise. Includes a named persona ('Vinston') — drop if you prefer to define your own agent personality.
382
+ - **morals.md** — Epistemic honesty rules. No presenting speculation as fact, label unverified claims, self-correct when wrong. Foundational trust rules for any AI agent. Strongly recommended.
383
+ - **code-field.md** — Pre-code assumption protocol. Requires stating assumptions and naming failure modes before writing a single line. Fights the 'it compiles, ship it' instinct. Based on NeoVertex1 context-field.
384
+
385
+ ### Safe write rules (non-clobber)
386
+
387
+ ! When persisting toggles to USER.md:
388
+
389
+ 1. ! Write **UTF-8** (no BOM). Create parent directories only if the resolved path's parent is missing — never relocate USER.md.
390
+ 2. ! Change **only** the `## Experimental Rules` section (add the section if enabling when absent; remove the section when all three are off and no custom bullets remain).
391
+ 3. ! Canonical enable lines (match Phase 1 template):
392
+ - `- ! Use meta/SOUL.md for strategic context and purpose-driven guidance`
393
+ - `- ! Use meta/morals.md for ethical AI development principles`
394
+ - `- ~ Use meta/code-field.md for advanced architecture patterns`
395
+ 4. ! Disable = remove lines that mention that path. Preserve any **custom** non-meta bullets under Experimental Rules.
396
+ 5. ! **Personal** and **Defaults** section bodies MUST remain byte-identical to the pre-write file (non-clobber).
397
+ 6. ~ Prefer the pure helper `applyExperimentalRulesState` / `setExperimentalRule` from `@deftai/directive-core` `userConfig` (`packages/core/src/user-config/experimental-rules.ts`) when the package is importable (framework checkout, tests, or a thin local script). When editing by hand as an agent, apply the same rules: section-only edit, UTF-8, path-based match, canonical enable lines.
398
+ 7. ! After write, re-read USER.md and show the final on/off state to the user.
399
+
400
+ ⊗ Rewrite the whole USER.md from the Phase 1 template when only Experimental Rules changed
401
+ ⊗ Clobber or reformat **Personal** / **Defaults** content while toggling experimental meta
402
+ ⊗ Hand-edit framework `meta/SOUL.md`, `meta/morals.md`, or `meta/code-field.md` bodies as part of this path
403
+ ⊗ Invent `deft config` / `task config:experimental-*` for this product slice when setup re-entry suffices
404
+
405
+ ### Then
406
+
407
+ - ! After a successful save (or discard), re-offer the Returning-user re-entry menu (Continue to Phase 2 / Revisit again / Exit / Discuss / Back) unless the user asked only for the toggle and is done.
408
+ - ~ If Phase 2 is already complete, prefer Exit over Continue unless the user wants project reconfiguration.
409
+
310
410
  ## Phase 2 — Project Configuration (PROJECT-DEFINITION.xbrief.json)
311
411
 
312
412
  **Goal:** Project-specific configuration — tech stack, type, quality standards — written as a xBRIEF file at `./xbrief/PROJECT-DEFINITION.xbrief.json`.
@@ -741,3 +841,6 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
741
841
  - ⊗ Present choices through a host UI that replaces the canonical numbers with alphabetic affordances or unlabeled buttons
742
842
  - ⊗ Resolve paths relative to the skill file, AGENTS.md, or framework directory instead of the user's pwd at skill entry
743
843
  - ⊗ Generate an authoritative PRD.md — PRD.md is a read-only export via `task prd:render`, never a source of truth
844
+ - ⊗ Skip the Returning-user re-entry / Revisit experimental rules path when USER.md exists and the operator entered setup to change experimental meta (#46)
845
+ - ⊗ Clobber Personal or Defaults while toggling Experimental Rules (#46)
846
+ - ⊗ Invent a full `deft config` verb family for experimental meta when setup re-entry suffices (#46)
@@ -92,6 +92,7 @@ CONSTRAINTS:
92
92
 
93
93
  ## Anti-Patterns
94
94
 
95
+ - ⊗ Parent conversation implements or babysits product fix/CI loops for **through merge** / **drive-to: merge-ready** story work when background subagent/worktree dispatch is available — even if cohort size is 1; use the swarm/solo-worker launch path (#3032 / #1880 Gap C)
95
96
  - ⊗ Start prompts with context or description instead of an imperative TASK directive
96
97
  - ⊗ Use `--mcp` with Warp MCP server UUIDs from standalone (non-Warp) terminals
97
98
  - ⊗ Assign overlapping files to multiple agents
@@ -4,6 +4,12 @@
4
4
 
5
5
  ! Before assigning work to agents, build the cohort from the triage queue (queue-driven per #1142 / N2; see Step 0 below), then read project state and plan allocation against the activated cohort.
6
6
 
7
+ ### Through-merge / N=1 still uses the launch path (#3032)
8
+
9
+ ! When operator intent is **through merge**, **drive to merge**, **land/ship issue**, or explicit **drive-to: merge-ready** for story work, the parent (monitor) conversation MUST NOT implement product code or own the implementation PR as the leaf. Parent MUST run this skill's launch path: worktree isolation when available, worker envelope with `drive-to: merge-ready`, xBRIEF preflight, pre-pr + review-cycle, then merge/`scope:complete` per #1880 Gap C.
10
+ ! **Cohort size N=1 is still a cohort for dispatch.** Solo through-merge uses the same swarm/solo-worker launch path as multi-story (`dispatch_kind: solo` or a one-story swarm-cohort). Do not treat "only one issue" as permission for the parent to code.
11
+ ⊗ Parent implements, babysits product fix loops, or skips worktree + worker dispatch for through-merge / drive-to:merge-ready work when background subagent/worktree dispatch is available (#3032).
12
+
7
13
  ### Headless cohort fast-path: low-ceremony launch (C1 / #1387)
8
14
 
9
15
  ! 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.
@@ -73,6 +73,16 @@ Package install alone does not put always-pins into `~/.openclaw/workspace/skill
73
73
  ! Babysit / PR shepherd on OpenClaw remains **Approach 1** via `sessions_spawn` (`skills/deft-directive-review-cycle/SKILL.md`). Cron alone is not Approach 1 (#2874 / #2876).
74
74
  ⊗ Regress babysit to main-session `gh` poll + cron when `sessions_spawn` is available.
75
75
 
76
+ ### Empty announce ≠ done + single lease residual (#3044)
77
+
78
+ Skill residual of #2874 / #2876 (spawn routing fixed; post-spawn ownership still thrashed). Canonical MUST language lives in `skills/deft-directive-review-cycle/SKILL.md` (`### Empty announce ≠ done`, `### Single review-monitor lease`, `### Required non-empty monitor handback`).
79
+
80
+ ! On empty body / missing `STATUS:` / status-unknown review-monitor settle (`subagent_announce` with `(no output)` included): parent MUST same-turn ground truth (`gh pr view` + `gh pr checks` + HEAD) and MUST NOT treat the settle as DONE/CLEAN/merge-ready — **FC04 residual**.
81
+ ! One sticky `<!-- deft:review-owner -->` lease per PR. Pre-spawn: list active same-`taskName` / lease holder. ⊗ Second monitor while prior owner is running **or** last settle was empty/unknown without terminal ground truth. Dead owner + open PR → one replacement + lease update only.
82
+ ! Monitor handback MUST be non-empty with `STATUS` / `HEAD` / `CHECKS` / `MERGE` (see review-cycle skill + `templates/swarm-greptile-poller-prompt.md`).
83
+ ~ Prefer `visible:true` when Control UI is the operator plane; invisible empty settles raise FC04 misclassification risk.
84
+ ~ Recurrence: enterprize PR #43 (2026-08-02) dual-monitor + empty settle.
85
+
76
86
  ## Monitor / completion channel
77
87
 
78
88
  ! Completion is parent push / announce. Do not poll via Grok Build `get_command_or_subagent_output` or Cursor Task-complete semantics.
@@ -543,9 +543,12 @@ Every worker MUST send a final status message before exiting its tool loop, rega
543
543
 
544
544
  ! **Thin DONE is not success (#2943):** A terminal message that lacks PR URL / merge evidence (no `PR #N`, no PR URL, no merge confirmation) is a **thin DONE** / failed-leaf signal for the parent monitor — re-dispatch or take over after ground truth. Prefer structured completion fields when the host supplies them (`prUrl`, `mergeStatus`, `emptyDiff`). Workers MUST NOT exit with mid-edit prose and call it `DONE` when the envelope required a PR or merge-ready outcome.
545
545
 
546
+ ! **Empty announce ≠ done / single review-monitor lease (#3044 / FC04 residual):** An empty settle, missing `STATUS:` line, or `status: unknown` from a review-monitor (`subagent_announce` with `(no output)` included) is **not** DONE/CLEAN/merge-ready. Parent MUST same-turn ground truth (`gh pr view` + checks + HEAD) and MUST NOT spawn a second monitor while the prior owner is running or only falsely settled. Prefer one sticky `<!-- deft:review-owner -->` lease and a non-empty `STATUS`/`HEAD`/`CHECKS`/`MERGE` handback. Full MUST language: `skills/deft-directive-review-cycle/SKILL.md` + OpenClaw host adapter residual.
547
+
546
548
  ! **Parent tool-first after leaf completion (#2943):** When a parent / monitor receives a leaf completion event (`subagent_announce`, parent-push, or host completion notify), its **first response** MUST be a **tool-first** ground-truth batch (`gh` / `git` / worktree or file status) **or** a host **yield** (`sessions_yield` on OpenClaw, or equivalent). ⊗ Multi-sentence progress-only first response with zero tools / yield — the OpenClaw text-repetition hang class (#2943).
547
549
 
548
550
  ⊗ Treat thin DONE (no PR URL / merge evidence) as success (#2943).
551
+ ⊗ Treat empty/unknown review-monitor settle as DONE without same-turn ground truth, or dual-spawn a second monitor while the first lease is live (#3044).
549
552
 
550
553
  Per-step acks during the run are noise. ONE start message, ONE final message; intermediate messages only on `BLOCKED` / `FAILED`. The final message lets the dispatcher distinguish a clean exit from a silent timeout when the lifecycle event arrives.
551
554
 
@@ -5,6 +5,11 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
5
5
 
6
6
  ! If any .deft/core/.agents/skills/ path referenced in this file cannot be read (missing file, stale path from a previous framework version, or a deprecation redirect stub), read .deft/core/QUICK-START.md instead and follow it. QUICK-START refreshes this section idempotently for the current framework version.
7
7
 
8
+ ## Temporary test kill-switch (#3039)
9
+
10
+ ! Before further Directive process load, check root `.deft-directive-disable` (presence = flag). If present → stop DD load; recovery = delete file + NEW agent session. Deposit OK; not `.no-deft-directive` (#2926). Docs: `.deft/core/docs/deft-directive-disable.md`.
11
+ ⊗ Claim full operation while the flag exists or after delete without a NEW agent session.
12
+
8
13
  ## Session routing (#2176)
9
14
 
10
15
  ! **Read-only default** until mutation intent: load AGENTS.md / main.md / USER.md / `xbrief/PROJECT-DEFINITION.xbrief.json`; resolve USER.md via `deft session:start` (`USER.md resolved …`; win32 `%APPDATA%\deft\USER.md`; unix `~/.config/deft/USER.md`; ⊗ invent `~/.config/deft` on Windows #2544); confirm Deft alignment + addressing-name; ⊗ no mutable `deft session:start` / triage welcome / sync / branch-policy unless asked or implementation-ready (#2176) — `.deft/core/commands.md` § Session routing. Bootstrap: cold-start → README § Cold-start (#2273) ⊗ never `.deft/core/`; pre-cutover → setup Pre-Cutover (#2068); missing USER.md / PROJECT-DEFINITION → setup Phase 1/2 (#1813) ⊗ before answering; else main → USER → PROJECT-DEFINITION; ~ sync. Mutation → `deft session:start` then `deft verify:session-ritual -- --tier=gated` (#1149). ? `deft session:start -- --read-only` (#2176).
@@ -63,6 +68,11 @@ Legacy `vbrief/` read-accepted; `deft migrate:xbrief` for `xbrief/` (v0.6→v0.8
63
68
  ! **Default always-pins:** `deft-directive-build`, `deft-directive-pre-pr`, `deft-directive-review-cycle`, `deft-directive-swarm` — read each `SKILL.md` when that work type starts.
64
69
  ⊗ Pin entire language packs, deployment docs, or framework bulk into AGENTS.md — pins are for false-negative-sensitive process gates only (#2508).
65
70
 
71
+ ## Through-merge worker dispatch (#3032)
72
+
73
+ ! On **through merge** / **drive to merge** / land-ship / **drive-to: merge-ready** story intent: parent MUST dispatch a `drive-to: merge-ready` worker (worktree, preflight, pre-pr, review-cycle, merge/`scope:complete`) via the **swarm/solo-worker launch path** even if **cohort size is 1** — parent MUST NOT implement as the leaf. Depth: swarm Phase 0 + skill-pin-policy (#3032 / #1880 Gap C).
74
+ ⊗ Parent conversation implements or babysits product fix/CI loops for drive-to:merge-ready work when background subagent/worktree dispatch is available (#3032).
75
+
66
76
  ## Review-surface precedence (#2308)
67
77
 
68
78
  ! Route PR shepherding / review work through `deft-directive-review-cycle` — `.deft/core/.agents/skills/deft-directive-review-cycle/SKILL.md`; host `babysit` / `bugbot` / `security-review` advisory-only (#2308 / #2261).
@@ -426,10 +426,14 @@ Send to parent:
426
426
 
427
427
  Subject: PR #{pr_number} CLEAN -- ready for merge
428
428
  Body:
429
- Greptile review on HEAD <sha> is clean.
429
+ STATUS: DONE
430
+ HEAD: <sha>
431
+ CHECKS: <list of CheckRun statuses>
432
+ MERGE: n/a
433
+ ISSUE: open
434
+ NOTES: Greptile CLEAN confidence <N>/5; ready for merge
430
435
  Confidence: <N>/5
431
436
  Findings: P0=0, P1=0
432
- CI: <list of CheckRun statuses>
433
437
  Last reviewed commit: <sha>
434
438
  -- no more polling, exiting now
435
439
 
@@ -445,9 +449,13 @@ If the same review surfaces 3 consecutive review cycles (push -> review -> still
445
449
 
446
450
  Subject: PR #{pr_number} escalation -- 3 review cycles still surfacing P0/P1
447
451
  Body:
448
- Three consecutive review cycles after push still surfaced P0/P1 findings.
452
+ STATUS: BLOCKED
453
+ HEAD: <sha>
454
+ CHECKS: see latest findings
455
+ MERGE: n/a
456
+ ISSUE: open
457
+ NOTES: 3 review cycles still surfacing P0/P1; <summary>
449
458
  Latest findings: <summary>
450
- Latest HEAD: <sha>
451
459
  -- no more polling, exiting now
452
460
 
453
461
  ### (3) ERRORED
@@ -458,7 +466,12 @@ Retry ONCE: post `@greptileai review` as a PR comment via `gh pr comment {pr_num
458
466
 
459
467
  Subject: PR #{pr_number} Greptile errored -- escalation required
460
468
  Body:
461
- Greptile errored on HEAD <sha>; retry via @greptileai also errored.
469
+ STATUS: FAILED
470
+ HEAD: <sha>
471
+ CHECKS: Greptile errored (retry also errored)
472
+ MERGE: n/a
473
+ ISSUE: open
474
+ NOTES: escalate per swarm Phase 6 Step 1 (wait / empty retrigger / override)
462
475
  Parent should escalate to user with the three-way choice per
463
476
  skills/deft-directive-swarm/SKILL.md Phase 6 Step 1:
464
477
  (a) wait longer (~15-20 min)
@@ -474,6 +487,12 @@ Send:
474
487
 
475
488
  Subject: PR #{pr_number} poll cap exceeded -- parent should escalate
476
489
  Body:
490
+ STATUS: BLOCKED
491
+ HEAD: <sha>
492
+ CHECKS: <statuses>
493
+ MERGE: n/a
494
+ ISSUE: open
495
+ NOTES: poll cap exceeded; holdout=<which-of-the-five-conditions-failed>
477
496
  {poll_cap_minutes}-minute poll cap exceeded.
478
497
  Latest state:
479
498
  last_reviewed_sha: <sha or "unparsed">
@@ -494,6 +513,12 @@ Increment the `stall_streak` counter introduced under `## CLEAN gate evaluation,
494
513
 
495
514
  Subject: PR #{pr_number} poll loop wedged -- terminal-condition detection failure
496
515
  Body:
516
+ STATUS: BLOCKED
517
+ HEAD: <sha>
518
+ CHECKS: holdout=<which-of-the-five-conditions-failed>
519
+ MERGE: n/a
520
+ ISSUE: open
521
+ NOTES: STALL — detector cannot reach CLEAN or P0/P1; diagnose instrumentation
497
522
  Detector cannot reach CLEAN or NEW P0/P1 FINDINGS but no blocking signals
498
523
  are visible. Likely terminal-condition detection gap on this PR's review surface.
499
524
  Latest state:
@@ -515,6 +540,12 @@ Send:
515
540
 
516
541
  Subject: PR #{pr_number} informal-clean missing canonical fields -- recovery required
517
542
  Body:
543
+ STATUS: BLOCKED
544
+ HEAD: <sha>
545
+ CHECKS: informal-clean missing canonical fields
546
+ MERGE: n/a
547
+ ISSUE: open
548
+ NOTES: #1543 informal-clean; recovery @greptileai or override
518
549
  Greptile informal-clean missing-canonical-fields state (#1543).
519
550
  Latest Greptile comment says the diff is clean / prior issues resolved,
520
551
  but lacks canonical `Last reviewed commit:` and `Confidence Score: X/5`.
@@ -542,6 +573,18 @@ Send:
542
573
  - ! Use Python scripts (single `run_shell_command` call) for the poll loop, NEVER shell `Start-Sleep` + repeated tool calls. The Python script handles `time.sleep({poll_interval_seconds})` between polls and exits when a terminal condition fires.
543
574
  - ! Always pass `do_not_summarize_output: true` semantics when fetching `gh pr view --comments` -- summarizers silently drop the Outside-Diff section.
544
575
  - ! Send a status message to `{parent_agent_id}` at start (acknowledging the task) and at every terminal exit (CLEAN / NEW P0/P1 FINDINGS escalation / ERRORED / TIMEOUT / STALL / INFORMAL-CLEAN). Route it through the host completion channel for your primitive (see Role posture -- OpenClaw `sessions_spawn` uses parent push / announce). Do NOT silently complete.
576
+ - ! **Required non-empty monitor handback (#3044):** every terminal exit message MUST be non-empty and include these structured fields (map CLEAN → `STATUS: DONE`, NEW P0/P1 / INFORMAL-CLEAN / TIMEOUT / STALL → `STATUS: BLOCKED`, ERRORED → `STATUS: FAILED` unless a hard failure):
577
+
578
+ ```text
579
+ STATUS: DONE|BLOCKED|FAILED
580
+ HEAD: <sha>
581
+ CHECKS: <summary>
582
+ MERGE: <url|error|n/a>
583
+ ISSUE: <closed|open|n/a>
584
+ NOTES: <short>
585
+ ```
586
+
587
+ ⊗ Empty final assistant message / empty `subagent_announce` body. Parents treat empty or missing-`STATUS` settles as FC04 residual, not success (`skills/deft-directive-review-cycle/SKILL.md` Empty announce ≠ done).
545
588
 
546
589
  ## Implementation Notes
547
590