@deftai/directive-content 0.93.0 → 0.95.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.
@@ -1,12 +1,15 @@
1
1
  ---
2
2
  name: deft-directive-sync
3
3
  description: >-
4
- Session-start framework sync skill. Pulls latest deft submodule, validates
5
- xBRIEF lifecycle structure, checks folder/status consistency, detects stale
6
- origins (RFC D12), and summarizes changes.
4
+ Session-start framework sync and upgrade handoff. Refreshes deposit via npm
5
+ + directive/deft update, validates xBRIEF lifecycle, detects stale origins
6
+ (RFC D12), and finishes SCM release handoff in released | pr-open |
7
+ blocked:<reason> (#1604).
7
8
  triggers:
8
9
  - good morning
9
10
  - update deft
11
+ - update directive
12
+ - upgrade framework
10
13
  - update xbrief
11
14
  - sync frameworks
12
15
  ---
@@ -18,23 +21,34 @@ triggers:
18
21
 
19
22
  # Deft Directive Sync
20
23
 
21
- Session-start framework sync -- pull latest deft submodule updates, validate xBRIEF lifecycle structure, and detect stale origins.
24
+ Session-start framework sync and upgrade handoff -- refresh the framework deposit via npm + `directive update` / `deft update`, validate xBRIEF lifecycle structure, detect stale origins (RFC D12), then finish SCM release handoff in a named terminal state (#1604).
22
25
 
23
- > **Canonical bootstrap / update path (#761 npm cutover):** Install and upgrade via npm: `npm i -g @deftai/directive` (install) or `npm i -g @deftai/directive@latest` (upgrade); Node >= 20 is required. For machines without Node, the frozen legacy Go installer (`deft-install` / platform-specific `install-*` from GitHub Releases) is a no-Node bootstrap bridge (#1912) -- migrate to npm once Node is available. After a session start the canonical `scripts/doctor.py --session --json` (`deft doctor` / `task doctor`) reports install + payload state and, when the manifest sha shows the payload is stale, recommends `npm i -g @deftai/directive@latest`. Legacy `run upgrade` / `task upgrade` are metadata-only acknowledgment (they do NOT replace the payload), and git-submodule / `task framework:doctor` paths are back-compat only -- the submodule sync in Phases 1-2 below is the legacy update flow, de-emphasized in UPGRADING.md / README. See UPGRADING.md and #761 / #1912.
26
+ > **Canonical bootstrap / update path (#761 / #1604):** Install and upgrade via npm: `npm i -g @deftai/directive` (install) or `npm i -g @deftai/directive@latest` (upgrade); Node >= 20 is required. Then from the project root run `directive update` (or `deft update`) to refresh `.deft/core/`, optionally `deft migrate` for npm provenance, and `directive doctor` / `deft doctor` / `task doctor` to confirm deposit health. For machines without Node, the frozen legacy Go installer (`deft-install` / platform-specific `install-*` from GitHub Releases) is a no-Node bootstrap bridge (#1912) -- migrate to npm once Node is available. Legacy `run upgrade` / `task upgrade` are metadata-only acknowledgment (they do NOT replace the payload). **Git-submodule / `task framework:doctor` paths are back-compat only** -- Phases 1-2 below are the legacy update flow, de-emphasized in UPGRADING.md / README. Deposit success is not upgrade released; Phase 8 records one terminal state: `released` | `pr-open` | `blocked:<reason>`. See UPGRADING.md and #761 / #1912 / #1604.
24
27
 
25
28
  Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
26
29
 
27
30
  ## Platform Requirements
28
31
 
29
- ! This skill requires **GitHub** as the SCM platform and the **GitHub CLI (`gh`)** to be installed and authenticated. Origin freshness checks (Phase 5) fetch issue data via `gh issue view`.
32
+ ! This skill requires **GitHub** as the SCM platform and the **GitHub CLI (`gh`)** to be installed and authenticated for origin freshness (Phase 5) and for the PR path of Phase 8 SCM release handoff. Origin freshness checks fetch issue data via REST-equivalent `gh` surfaces (prefer `gh api repos/<owner>/<repo>/issues/<N>` over GraphQL-heavy forms when under rate pressure; #954).
30
33
 
31
34
  ## When to Use
32
35
 
33
- - User says "good morning", "update deft", "update xbrief", or "sync frameworks"
36
+ - User says "good morning", "update deft", "update directive", "upgrade framework", "update xbrief", or "sync frameworks"
34
37
  - Beginning of a new session where framework updates may be available
35
- - After a known upstream deft release
38
+ - After a known upstream deft / `@deftai/directive` release
39
+ - After a successful local deposit when the default branch still lacks the framework update
36
40
 
41
+ ## Missing CLI / PATH remediation
37
42
 
43
+ ! When `directive`, `deft`, or the global npm bin is missing from PATH (or `npm i -g @deftai/directive@latest` has not been run), surface actionable install remediation first:
44
+
45
+ ```bash
46
+ npm i -g @deftai/directive@latest
47
+ ```
48
+
49
+ (or the pnpm equivalent: `pnpm add -g @deftai/directive@latest`). Then re-run `directive update` / `deft update` and `directive doctor`.
50
+
51
+ ⊗ Send the operator to manual GitHub release-asset archaeology or Go installer discovery as the happy path when Node is available -- npm is the primary remediation (#761 / #1604).
38
52
 
39
53
  ## Session orientation — unmanaged header (#2065)
40
54
 
@@ -65,7 +79,7 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
65
79
 
66
80
  ### Action on Detection
67
81
 
68
- ! If pre-cutover state is detected, display the actionable migration message, then **skip Phases 1-6** and proceed directly to Phase 7 with the Document Model line set to "pre-v0.20 (legacy)":
82
+ ! If pre-cutover state is detected, display the actionable migration message, then **skip Phases 0-6** and proceed directly to Phase 7 with the Document Model line set to "pre-v0.20 (legacy)". Phase 8 still applies if a local migration/framework change must land on the default branch after the frozen migrator path:
69
83
 
70
84
  > "This project uses the pre-v0.20 document model. Current npm releases no longer ship in-product `task migrate:vbrief` (#2068). Follow UPGRADING.md § Frozen pre-v0.20 document-model migration: pin framework v0.59.0, install Python 3.11+ and uv, run `task migrate:vbrief` once from that payload, then upgrade to current npm."
71
85
 
@@ -88,12 +102,77 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
88
102
  ⊗ Skip model state detection during sync -- always report the document model state.
89
103
  ⊗ Silently ignore pre-cutover artifacts -- the user must be informed with an actionable command to fix the state.
90
104
 
91
- ## Phase 1 -- Pre-flight
105
+ ## Phase 0 -- Primary upgrade (npm deposit) (#761 / #1604)
106
+
107
+ ! Treat npm + `directive update` / `deft update` as the **primary** consumer upgrade path when an upgrade is authorized. Do not lead with submodule update when Node is available.
108
+
109
+ ### 0a: When mutation is authorized
110
+
111
+ ! **Mutating** engine install / deposit refresh is authorized only when at least one of:
112
+
113
+ 1. The operator used an **explicit upgrade** trigger: `update deft`, `update directive`, `upgrade framework`, or equivalent ("upgrade Directive", "run update").
114
+ 2. Doctor / payload-staleness already reports the deposit is **behind** and the operator confirmed the upgrade (or autonomous upgrade was pre-approved).
115
+ 3. CLI is **missing** from PATH -- then Missing CLI remediation may install the global package so doctor/update can run.
116
+
117
+ ! For routine session orientation triggers (`good morning`, `sync frameworks`, plain `update xbrief` without upgrade language):
118
+
119
+ 1. ! Run **read-only** checks: CLI present?, `directive doctor` / `deft doctor` / `task doctor` when available, structure validation (Phases 3+).
120
+ 2. ! If doctor reports a stale deposit or available upgrade, **report** the recommended command and ask for consent before mutating.
121
+ 3. ⊗ Run `npm i -g @deftai/directive@latest` or `directive update` / `deft update` on a routine "good morning" without staleness evidence **and** operator consent (or pre-approved autonomous upgrade).
122
+
123
+ ### 0b: Consumer worktree isolation before deposit
124
+
125
+ ! Before any mutating deposit that will be handed off in Phase 8:
126
+
127
+ 1. ! Run `git status --porcelain` at the **project root** (not only the legacy submodule).
128
+ 2. ! If the worktree or index has non-framework product changes (or any unexpected staged paths), **stop** and either:
129
+ - ask the operator to stash / commit product work first, or
130
+ - record `blocked:dirty-worktree` and skip deposit mutation,
131
+ - or, with explicit consent, isolate product changes (stash including index) so the deposit cannot mix with them.
132
+ 3. ! After deposit, stage **only** framework-managed paths for the upgrade commit (e.g. `.deft/core/`, managed AGENTS section, hooks, VERSION / marker files). Reconstruct a clean index if needed rather than `git add -A`.
133
+ 4. ⊗ Create a framework-only commit or PR from a mixed worktree/index that still carries product feature paths.
134
+
135
+ ### 0c: Engine + deposit (when authorized)
136
+
137
+ 1. ! Confirm the global CLI is available (`directive --version` or `deft --version`). If missing, run Missing CLI / PATH remediation above, then continue.
138
+ 2. ! Upgrade the global engine only when mutation is authorized (0a):
139
+
140
+ ```bash
141
+ npm i -g @deftai/directive@latest
142
+ ```
143
+
144
+ 3. ! From the **project root**, after worktree isolation (0b), refresh the deposit:
145
+
146
+ ```bash
147
+ directive update
148
+ # or: deft update
149
+ ```
150
+
151
+ 4. ~ Optionally stamp npm provenance (idempotent): `directive migrate` / `deft migrate`.
152
+ 5. ! Verify deposit health:
153
+
154
+ ```bash
155
+ directive doctor
156
+ # or: deft doctor / task doctor
157
+ ```
158
+
159
+ 6. ! Record whether the working tree now has **framework-only** changes under `.deft/core/`, managed AGENTS section, hooks, or related managed files that need SCM release.
160
+
161
+ ### 0d: Framework-only change-set discipline
162
+
163
+ ! Keep upgrade commits/PRs **framework-only** -- do not mix product feature work into the same commit or PR as the deposit refresh.
164
+
165
+ ⊗ Treat a successful deposit alone as `released` -- the default branch must carry the update (or a PR must be open) before the operator goal is complete (#1604).
166
+ ⊗ Force a global CLI upgrade or deposit mutation on routine session sync without consent or staleness evidence.
167
+
168
+ ## Phase 1 -- Pre-flight (legacy submodule path)
169
+
170
+ ! **Legacy / back-compat only.** Run Phases 1-2 only when the consumer still uses a `deft/` git submodule layout and cannot use the npm deposit path. Prefer Phase 0 for all npm-managed installs.
92
171
 
93
172
  ! Check that the deft/ submodule working tree is clean before attempting any update.
94
173
 
95
174
  1. ! Run `git -C deft status --porcelain`
96
- 2. ! If output is non-empty (dirty working tree): **stop** and ask user whether to stash (`git -C deft stash`) or abort the sync entirely. Do NOT proceed with a dirty submodule.
175
+ 2. ! If output is non-empty (dirty working tree): **stop** and ask user whether to stash (`git -C deft stash`) or abort the sync entirely. Do NOT proceed with a dirty submodule. Record terminal state `blocked:dirty-submodule` if the operator aborts.
97
176
  3. ! Record the current DEFT commit for later comparison:
98
177
  ```
99
178
  git -C deft log --oneline -1
@@ -103,7 +182,9 @@ A project is **pre-cutover** if ANY of the following are true. This prose mirror
103
182
  - Clean/dirty status
104
183
  - Confirmation that pre-flight passed (or the blocker if dirty)
105
184
 
106
- ## Phase 2 -- Update DEFT Submodule
185
+ ## Phase 2 -- Update DEFT Submodule (legacy / back-compat)
186
+
187
+ ! **Legacy / back-compat only** -- not the primary consumer upgrade path (#1604). Submodule update does not replace Phase 0 for npm installs.
107
188
 
108
189
  1. ! Run the submodule update:
109
190
  ```
@@ -214,7 +295,7 @@ After structure validation, sync framework-level assets.
214
295
 
215
296
  ### 6a: Check AGENTS.md freshness
216
297
 
217
- ~ Compare the project's `AGENTS.md` against the deft template (if a template exists in the updated `deft/` submodule):
298
+ ~ Compare the project's `AGENTS.md` against the deft template (if a template exists in the updated deposit / `.deft/core/` or legacy `deft/` submodule):
218
299
 
219
300
  1. ~ Diff the structure (section headings, key rules) rather than expecting byte-identical content
220
301
  2. ~ Report any new sections or rules added upstream that are missing locally
@@ -230,7 +311,7 @@ After structure validation, sync framework-level assets.
230
311
 
231
312
  ### 6c: List new skills
232
313
 
233
- ! Compare the `skills/` directory before and after the update:
314
+ ! Compare the `skills/` directory (or deposited `.deft/core/` skills) before and after the update:
234
315
 
235
316
  1. ! List any new skill directories added in the update
236
317
  2. ~ For each new skill, read its frontmatter `description` field and present a one-liner
@@ -282,29 +363,103 @@ Doc sprawl is a project-health concern, not just a human-experience one: a lean,
282
363
 
283
364
  ! Present a consolidated summary to the user covering:
284
365
 
285
- 1. **DEFT version change**: old commit -> new commit (or "already up to date")
286
- 2. **Structure validation**: lifecycle folders status (all present / missing folders listed)
287
- 3. **PROJECT-DEFINITION status**: valid / missing / stale (with freshness details)
288
- 4. **xBRIEF validation results**: pass/fail per file, with details on any failures
289
- 5. **Lifecycle consistency**: all consistent / N mismatches found (with details)
290
- 6. **Origin freshness**: N stale / N externally-closed / N current (with details)
291
- 7. **Document Model**: pre-v0.20 (legacy) / v0.20+ (xBRIEF-centric) OK / v0.20+ with warnings (see Pre-Cutover Detection Guard)
292
- 8. **AGENTS.md status**: current / has upstream changes / needs review
293
- 9. **Codebase MAP status**: current / stale / absent / not configured (advisory)
294
- 10. **New skills**: list any newly added skills with descriptions
366
+ 1. **Upgrade path used**: npm deposit (Phase 0) / legacy submodule (Phases 1-2) / already up to date
367
+ 2. **DEFT / deposit version change**: old version or commit -> new (or "already up to date")
368
+ 3. **Structure validation**: lifecycle folders status (all present / missing folders listed)
369
+ 4. **PROJECT-DEFINITION status**: valid / missing / stale (with freshness details)
370
+ 5. **xBRIEF validation results**: pass/fail per file, with details on any failures
371
+ 6. **Lifecycle consistency**: all consistent / N mismatches found (with details)
372
+ 7. **Origin freshness**: N stale / N externally-closed / N current (with details)
373
+ 8. **Document Model**: pre-v0.20 (legacy) / v0.20+ (xBRIEF-centric) OK / v0.20+ with warnings (see Pre-Cutover Detection Guard)
374
+ 9. **AGENTS.md status**: current / has upstream changes / needs review
375
+ 10. **Codebase MAP status**: current / stale / absent / not configured (advisory)
376
+ 11. **New skills**: list any newly added skills with descriptions
377
+ 12. **Pending SCM release**: whether framework-only changes still need commit/push/PR/merge (Phase 8)
295
378
 
296
- ! Ask the user: "Shall I commit the submodule update?" -- do NOT auto-commit.
379
+ ! After a successful deposit (or submodule bump), **do not stop at the local change set**. Proceed to Phase 8 SCM release handoff. If there is nothing to release (already on default branch / no local framework delta), record terminal state `released` when the default branch already carries the current framework update; otherwise name the next release step.
380
+
381
+ ? For the legacy submodule path only, if a bump is ready and the operator has not yet approved a commit, ask: "Shall I commit the submodule update and continue SCM release handoff?" -- do NOT auto-commit without approval. Prefer message:
297
382
 
298
- ? If the user confirms, commit with message:
299
383
  ```
300
384
  chore(deft): update deft submodule to <short-hash>
301
385
  ```
302
386
 
387
+ For npm deposit changes, prefer a framework-only commit message such as:
388
+
389
+ ```
390
+ chore(deft): refresh framework deposit to <version>
391
+ ```
392
+
393
+ ## Phase 8 -- SCM release handoff (#1604)
394
+
395
+ ! After a successful framework deposit (Phase 0) or legacy submodule bump (Phases 1-2), carry the update through consumer SCM release. Installer/update success is not upgrade released.
396
+
397
+ ! Record **exactly one** terminal state when this skill exits after a deposit-related run:
398
+
399
+ | Terminal state | Meaning |
400
+ | --- | --- |
401
+ | `released` | Default branch carries the framework update (merged or committed directly under policy). |
402
+ | `pr-open` | Framework-only branch pushed and PR opened; awaiting review/merge per policy. |
403
+ | `blocked:<reason>` | Explicit blocker (examples: `blocked:dirty-worktree`, `blocked:auth`, `blocked:branch-protection`, `blocked:human-merge-gate`, `blocked:ci`, `blocked:operator-declined`). |
404
+
405
+ ### 8a: Policy detection
406
+
407
+ 1. ! Read consumer branch policy: `plan.policy.allowDirectCommitsToMaster`, `plan.policy.requireHumanMerge`, and any known branch-protection / default-branch rules (`deft policy:show` when available).
408
+ 2. ! Classify the path:
409
+ - **PR path (default when protected or human-merge):** branch protection enabled, or `requireHumanMerge` is true, or direct commits to default branch are disallowed.
410
+ - **Direct-commit path:** `allowDirectCommitsToMaster` (or equivalent) is true **and** human-merge is not required **and** branch protection does not forbid the commit.
411
+
412
+ ### 8b: PR-oriented path (branch-protected / human-merge)
413
+
414
+ 1. ! With operator consent (or autonomous consent when the operator already approved upgrade handoff), create a **framework-only** branch (e.g. `chore/deft-update-<version>`), commit framework deposit files only, push, and open a PR targeting the default branch.
415
+ 2. ! Stop at terminal state **`pr-open`** once the PR URL is available -- unless policy explicitly allows bot merge **and** the operator directed merge.
416
+ 3. ⊗ Auto-merge past `requireHumanMerge` / the human merge gate (#1193). Agents may open PRs; they do not merge when policy forbids it.
417
+ 4. ⊗ Claim `released` when the PR is only open or only locally committed.
418
+
419
+ ### 8c: Direct-commit-enabled path
420
+
421
+ 1. ! Present an **explicit** default-branch path with confirmation (do not silently commit to master/main).
422
+ 2. ! On confirmation, commit framework-only changes on the default branch (or merge the framework branch) and push so the default branch carries the update.
423
+ 3. ! Record terminal state **`released`** only after the default branch ref includes the framework update.
424
+
425
+ ### 8d: Stop-after-commit is a failure mode
426
+
427
+ ! A local framework-only commit without push/PR/merge **and** without naming the next release step is a **failure mode** of this skill (#1604 historical class).
428
+
429
+ - ! If the workflow must pause after a local commit, name the next step explicitly (push + open PR, or confirm direct-commit + push) and record `blocked:<reason>` or continue until `pr-open` / `released`.
430
+ - ⊗ End the skill at "local framework-only commit done" without a terminal state line.
431
+ - ⊗ Report `released` when only a local commit exists and the default branch does not yet carry the update.
432
+
433
+ ### 8e: Terminal state line
434
+
435
+ ! End the skill output with a single machine-readable line operators and agents can grep:
436
+
437
+ ```text
438
+ upgrade-handoff: released
439
+ upgrade-handoff: pr-open
440
+ upgrade-handoff: blocked:<reason>
441
+ ```
442
+
443
+ Include the PR URL when state is `pr-open`, and the merge/default-branch SHA when state is `released`.
444
+
445
+ ### 8f: Framework-only path allowlist
446
+
447
+ ! When committing for handoff, include only framework deposit artifacts (managed `.deft/core/`, AGENTS managed section, hooks, VERSION/marker files, and other paths the deposit itself refreshed). Exclude product source, tests, and unrelated staged files. If isolation was used in 0b, restore the operator's product stash only **after** the framework commit is complete (or on a separate branch).
448
+
303
449
  ## Anti-Patterns
304
450
 
305
451
  - ⊗ Auto-commit submodule changes without user approval
452
+ - ⊗ Auto-commit or auto-push framework deposit changes without the Phase 8 policy path and consent rules
453
+ - ⊗ Stop after a local framework-only commit without naming the next release step or recording a terminal state (#1604)
454
+ - ⊗ Claim terminal state `released` when the update is only local or only on an open PR
455
+ - ⊗ Auto-merge when `requireHumanMerge` is true or branch protection forbids bot merge (#1193)
456
+ - ⊗ Treat git submodule update as the primary consumer upgrade path when npm + `directive update` / `deft update` is available
457
+ - ⊗ Send operators to manual GitHub release-asset archaeology when `npm i -g @deftai/directive@latest` is the correct remediation
306
458
  - ⊗ Overwrite project-level `./xbrief/*.xbrief.json` files -- those are project data
307
459
  - ⊗ Skip the pre-flight dirty check -- a dirty submodule can cause merge conflicts or data loss
308
460
  - ⊗ Include a separate fetch of the xBRIEF schema from upstream deftai/xBRIEF -- that is a CI concern (see #128), not a user sync task
309
461
  - ⊗ Auto-move xBRIEFs to fix folder/status mismatches -- report only; never auto-fix
310
462
  - ⊗ Auto-update xBRIEFs based on origin freshness -- report only; user decides during refinement
463
+ - ⊗ Mix product feature work into a framework-only upgrade commit or PR
464
+ - ⊗ Force `npm i -g @deftai/directive@latest` or deposit mutation on routine session sync without staleness evidence and operator consent
465
+ - ⊗ Run Phase 8 framework-only commit from a mixed product+framework worktree/index without isolation
@@ -78,7 +78,7 @@ Directive does not guess your mix: **ordered plan** (`task plan-sequence:*`) whe
78
78
 
79
79
  ! Walk per-item decisions through the canonical `task triage:*` verbs (tasks own audit-log append / schema / `xbrief/proposed/` write).
80
80
 
81
- ! **Operator brief (same turn as menu) (#2890):** Before every per-item decision menu, present an operator brief in the **same operator-visible message/surface** as the menu, containing at least: issue `#N` + title + link; labels (or explicit none); 2–5 line problem/context summary; AC bullets or explicit "thin body / no AC"; agent **lean** + one-line why (Accept / Defer / Reject / Needs-AC / …). ~ Prefer `task triage:show --format=operator <N>` as the brief backbone; agent still owns lean. ⊗ Menu-only or chip-only Phase 3 turns without that brief. ⊗ Brief-only turn followed by a later chip/menu-only turn that does not restate the brief.
81
+ ! **Operator brief (same turn as menu) (#2890 / #3116):** Before every per-item decision menu, present an operator brief in the **same operator-visible message/surface** as the menu, containing at least: **URL-first** lead (canonical issue URL as the first line for that item, or `#N title` + URL); labels (or explicit none); **current-state validity** (`still-open` | `partial` | `likely-shipped` | `needs-re-scope`) + one-line evidence (linked closed PR, code path, or "no evidence of fix"); 2–5 line problem/context summary; AC bullets or explicit "thin body / no AC"; agent **lean** + one-line why (Accept / Defer / Reject / Needs-AC / …). ~ Prefer `task triage:show --format=operator <N>` as the brief backbone (URL-first + validity placeholder); agent still owns validity verdict and lean. ⊗ Menu-only or chip-only Phase 3 turns without that brief. ⊗ Brief-only turn followed by a later chip/menu-only turn that does not restate the brief. ⊗ Body-only summary without validity check against current master, closed children, or linked PRs.
82
82
 
83
83
  ! **Host structured-question adapter:** On chips / `ask_user` / similar UIs (e.g. OpenClaw `ask_user`), keep the prose brief in chat; structured options are **actions only** (Accept / Defer / Reject / Needs-AC / Mark duplicate / Discuss / Back). Option labels ≉ substitute for the brief.
84
84
 
@@ -120,7 +120,7 @@ What would you like to do with this candidate?
120
120
 
121
121
  - ⊗ Recommend work without `task triage:queue` (#1149).
122
122
  - ⊗ Conclude "nothing to do" from folder scans or live GitHub alone (#2576).
123
- - ⊗ Stale-cache walk; reimplement audit/`proposed/` writes; treat defer/needs-ac as terminal; edit candidates.jsonl; menu-only Phase 3 without operator brief (#2890).
123
+ - ⊗ Stale-cache walk; reimplement audit/`proposed/` writes; treat defer/needs-ac as terminal; edit candidates.jsonl; menu-only Phase 3 without operator brief (#2890); body-only brief without URL-first or current-state validity (#3116).
124
124
 
125
125
  ## EXIT
126
126
 
@@ -128,5 +128,5 @@ What would you like to do with this candidate?
128
128
 
129
129
  ## References
130
130
 
131
- - #1119 D6; #1128 D11 (`triage:queue` / `show` / `audit`); #2890 Phase 3 operator brief; #1122 / #1123 / #1127 / #1129 / #1131
131
+ - #1119 D6; #1128 D11 (`triage:queue` / `show` / `audit`); #2890 Phase 3 operator brief; #3116 validity + URL-first; #1122 / #1123 / #1127 / #1129 / #1131
132
132
  - Siblings: `deft-directive-refinement`, `deft-directive-swarm`, `deft-directive-sync`
@@ -22,6 +22,27 @@ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
22
22
  - ~ When the feature involves libraries or APIs the agent hasn't used in this project
23
23
  - ? Skip for well-understood domains where the agent has strong existing context
24
24
 
25
+ ## Scope Confirmation Gate (#1273)
26
+
27
+ ! Before autonomous research begins, present one blocking scope-confirmation prompt and wait for the user's selection. Use the deterministic question contract: the final two numbered options MUST be `Discuss` and `Back`.
28
+
29
+ Prompt:
30
+ > "What should this research focus on before I investigate autonomously?"
31
+
32
+ 1. Confirm the inferred feature/domain scope (Recommended)
33
+ 2. Refine the feature boundary or priority areas
34
+ 3. Provide sample data, artifacts, constraints, or sensitive areas to account for
35
+ 4. Discuss
36
+ 5. Back
37
+
38
+ - ! **Confirmed-scope postcondition (required before survey):** research MUST NOT start the survey until a confirmed research scope is recorded in notes. Confirmation is achieved by **any** of: option **1** (accept inferred scope as-is), or option **2**/**3** after free-form capture (the free-form answer **is** the confirmation of scope — it replaces option-1 confirmation; do not re-open option 1 after capture).
39
+ - ! On option **1** (confirm inferred scope): record the inferred feature/domain as the confirmed research scope and proceed to the survey step.
40
+ - ! On option **2** (refine boundary): ask a **follow-up free-form question** in the next message (one question only) to capture the refined feature boundary or priority areas; wait for the user's answer; record that free-form text as the **confirmed** research scope; then proceed to survey. ⊗ Proceed to survey after option 2 without collecting free-form refinement text. ⊗ Leave research blocked after option 2 with no follow-up path.
41
+ - ! On option **3** (artifacts/constraints/sensitivity): ask a **follow-up free-form question** in the next message (one question only) for sample data paths, artifacts to analyze, constraints, or sensitive areas; wait for the user's answer; record provided artifacts/constraints/sensitivity flags **and** treat the current feature/domain (plus those inputs) as the **confirmed** research scope; then proceed to survey. ⊗ Proceed to survey after option 3 without collecting free-form artifact/constraint input. ⊗ Leave research blocked after option 3 with no follow-up path.
42
+ - ! If the user declines free-form input after option 2 or 3 (empty answer / "skip" / "none"): re-present the Scope Confirmation Gate once; if they pick option **1**, confirm inferred scope and proceed; if they again decline capture without confirming, stop research and return to the chaining gate or invoking menu — do not survey on unconfirmed scope.
43
+ - ! Record the confirmed scope, any provided artifacts, and any sensitivity flags in the research notes before the survey step.
44
+ - ⊗ Start the survey from project description alone without a confirmed research scope (option 1 acceptance or option 2/3 free-form confirmation).
45
+
25
46
  ## Output
26
47
 
27
48
  ! Before writing output artifacts, follow the [Preparatory Guard](./artifact-guards.md#preparatory-guard-light).
@@ -127,9 +148,12 @@ so the user can run additional preparatory strategies or proceed to spec generat
127
148
  append artifact path (`vbrief/proposed/{feature}-research.vbrief.json`)
128
149
  - Append the path to the flat `artifacts` array
129
150
  - ! Return to [interview.md Chaining Gate](./interview.md#chaining-gate)
151
+ - ! Present the chaining gate as a blocking question and wait for a user selection before any spec generation or additional scope vBRIEF generation.
152
+ - ! Explain at handoff that `completedStrategies` records that research ran, while `vbrief/proposed/{feature}-research.vbrief.json` remains a planning artifact in the scope lifecycle until a later strategy promotes or consumes it.
130
153
  - ! The research findings MUST inform subsequent strategies and spec generation:
131
154
  - "Don't Hand-Roll" items become constraints in the specification
132
155
  - "Common Pitfalls" become acceptance criteria or NFRs
156
+ - ⊗ Generate implementation scope vBRIEFs directly from research findings or proceed to spec generation before the user chooses from the chaining gate.
133
157
  - ⊗ End the session after research without returning to the chaining gate
134
158
  or the invoking strategy's next-step menu
135
159
 
@@ -141,7 +165,7 @@ so the user can run additional preparatory strategies or proceed to spec generat
141
165
 
142
166
  ## Workflow
143
167
 
144
- 1. **Scope** -- Identify the domain and feature boundaries for research
168
+ 1. **Scope confirmation** -- Ask the blocking scope-confirmation prompt, wait for the user, and record scope/artifact/sensitivity inputs
145
169
  2. **Survey** -- Check existing project dependencies, official docs, and known pitfalls
146
170
  3. **Document** -- Produce `vbrief/proposed/{feature}-research.vbrief.json` with `DontHandRoll` and `CommonPitfalls` narratives
147
171
  4. **Chain** -- Return to [interview.md Chaining Gate](./interview.md#chaining-gate), or -- if invoked from a standalone strategy (e.g. map's standalone next-step menu) -- return to the invoking strategy's menu per the [standalone-context rule](#then-chaining-gate) above
@@ -150,6 +174,7 @@ so the user can run additional preparatory strategies or proceed to spec generat
150
174
 
151
175
  - ⊗ Building custom solutions for solved problems
152
176
  - ⊗ Skipping research for unfamiliar domains ("how hard can auth be?")
177
+ - ⊗ Starting autonomous research before the Scope Confirmation Gate has captured or explicitly skipped user-provided artifacts/constraints
153
178
  - ⊗ Research that produces a reading list instead of actionable guidance
154
179
  - ⊗ Research that doesn't flow into planning (written and never referenced)
155
180
  - ⊗ Ending after research without chaining into specification generation (chained mode; in standalone context, returning to the invoking strategy's menu satisfies the completion requirement per the [standalone-context rule](#then-chaining-gate))
@@ -22,7 +22,7 @@ vars:
22
22
 
23
23
  tasks:
24
24
  classify:
25
- desc: "Inspect / validate plan.policy.triageAutoClassify[] + triageHoldMarkers[] (#1129 / D10). -- task triage:classify -- [--list | --validate]"
25
+ desc: "Inspect / validate triageAutoClassify + triageLabelMirror; Tier-1 SCM label mirror (#1129 / #1423). -- task triage:classify -- [--list | --validate | --mirror [--apply]]"
26
26
  internal: true
27
27
  deps: [":engine:_ts-build"]
28
28
  dir: '{{.USER_WORKING_DIR}}'
package/tasks/verify.yml CHANGED
@@ -496,6 +496,16 @@ tasks:
496
496
  vars:
497
497
  ENGINE_CMD: 'verify-review-monitor {{.CLI_ARGS}}'
498
498
 
499
+ l4-owner:
500
+ desc: "Owner Continuity / L4 owner gate (#3090): exit 0 only if sticky review-owner lease is fresh or --review-cycle done (forbid freeform started/pending). Three-state exit (0 ready / 1 silent hold / 2 config)."
501
+ dir: '{{.USER_WORKING_DIR}}'
502
+ deps:
503
+ - task: :engine:_ts-build
504
+ cmds:
505
+ - task: :engine:invoke
506
+ vars:
507
+ ENGINE_CMD: 'verify-l4-owner {{.CLI_ARGS}}'
508
+
499
509
  subagent-alive:
500
510
  desc: "Fail-closed worker liveness gate (#2824): missing/STALE heartbeats for in-flight drive-to:merge* workers exit 1 with REDISPATCH_OK. Three-state exit (0 alive / 1 stale-or-missing / 2 config error)."
501
511
  dir: '{{.USER_WORKING_DIR}}'
@@ -545,13 +545,65 @@ Every worker MUST send a final status message before exiting its tool loop, rega
545
545
 
546
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
547
 
548
+ ! **`review_cycle` evidence enum (#3090):** Handoffs, swarm finish messages, and L4 process claims MUST use only `done` | `in_progress:<pr>#<monitor_or_lease_ref>` | `skipped:<reason>` | `n/a`. Freeform `started` / `pending` / `initiated` is forbidden. L4 `status: pass` is illegal unless `review_cycle: done` (Step 6 fail-closed on HEAD) or `review_cycle: in_progress:…` with a verifiable sticky lease / parent-retained ownership. After a drive-to:merge-ready / babysit / shepherd claim, the same turn MUST end in Owner Continuity Gate A/B/C (monitor+lease, parent-retained next dual-source action, or explicit BLOCKED/FAILED finish) — never silent hold. Optional machine gate: `deft verify:l4-owner --pr <N>` / `task verify:l4-owner -- --pr <N>`. Full MUST language: `skills/deft-directive-review-cycle/SKILL.md` Owner Continuity Gate.
549
+
550
+ ! **Bound proof for remote artifact claims / invented-done (#3120):** Handoff evidence MUST distinguish at least three axes and a binding state:
551
+
552
+ | Axis / field | Meaning |
553
+ |---|---|
554
+ | **work** | Local changes (edits, tests, commits on the branch) |
555
+ | **ship** | Pushed branch / PR exists on the forge |
556
+ | **gate** | Checks / review verdict on the claimed HEAD |
557
+ | **`proof_status`** | `bound` \| `unbound` \| `n/a-no-remote-claim` |
558
+
559
+ - ! **`proof_status` enum:** `bound` (same-turn probes bind every remote claim) \| `unbound` (remote claims present without probes — illegal under `status: pass`) \| `n/a-no-remote-claim` (no PR URL / PR number / SHA / CI-green / review-score fields filled).
560
+ - ! **`status: pass` is forbidden** when any remote artifact is claimed (PR URL/number, commit/HEAD SHA, CI green/success, review score) unless `proof_status` is `bound` **and** each claim has a same-turn probe (`command` + short raw `snippet` from that command's stdout). Unbound remote claims → **invalid evidence (fail)**, not pass-with-notes.
561
+ - ! **Binding = probe-then-fill (MUST):** run `git` / forge probe first (`git rev-parse HEAD`, `gh api repos/<o>/<r>/pulls/<N>`, `task pr:watch -- <N> --one-shot`, checks API), then **copy** IDs/URLs/SHAs/scores from the probe JSON/text into the evidence block. ⊗ Fill PR/SHA/CI/review fields from recollection, narration, or prior-turn memory.
562
+ - ! **Fail ranking:** **invented-done** (false or unbound remote artifacts under pass) is **stricter** than **empty-done** (pass with no work/ship/gate substance and no remote claims). Empty returns are incomplete; invented complete returns are worse and MUST fail closed.
563
+ - ! **Legal partial:** local work `done` + ship `not_started` / `blocked` **without** PR/SHA/CI/review fields and `proof_status: n/a-no-remote-claim` (or non-pass `status: partial`) is valid — do not invent ship state.
564
+ - Machine check (library): `validateHandoffEvidence` in `@deftai/directive-core` `handoff-evidence` (`packages/core/src/handoff-evidence/`). Skills: build / pre-pr / review-cycle final checklist.
565
+
548
566
  ! **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).
549
567
 
550
568
  ⊗ Treat thin DONE (no PR URL / merge evidence) as success (#2943).
551
569
  ⊗ 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).
570
+ ⊗ Emit freeform `review_cycle: started` / `pending` / `initiated` or L4 `status: pass` without `done` or verifiable `in_progress:<pr>#…` (#3090).
571
+ ⊗ Claim `status: pass` (or equivalent process-green handoff) with PR URL / SHA / CI green / review score filled from memory without same-turn probe binding — **invented-done** (#3120).
572
+ ⊗ Set `proof_status: n/a-no-remote-claim` while remote PR/SHA/CI/review fields are non-empty (#3120).
573
+ ⊗ Mark ship/gate `done` or fill PR fields when only local work completed — legal partial omits remote fields (#3120).
552
574
 
553
575
  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.
554
576
 
577
+ ## 11.5 Completion latch — one consolidate per runId (#3092)
578
+
579
+ Multi-agent **orchestrators** (OpenClaw parent seats, Cursor Task parents, grok-build swarm monitors, any parent that receives child settle / completion events) MUST apply a portable **completion latch**. Host-level announce dedupe is complementary and imperfect; this is the **agent-side** default when the same settled batch is re-delivered.
580
+
581
+ ### Completion latch (MUST)
582
+
583
+ 1. **One user- or caller-visible consolidate per child `runId` / settle batch** (or the explicit equivalent batch key the harness provides — e.g. spawn id, task id, announce id). Accept or reject for that batch still counts as the one consolidate.
584
+ 2. After that consolidate is emitted, **identical or equivalent completion replay** for the same key ⇒ **silent**: no tools, no re-QC, no second final answer. When the host defines a silent token (example: OpenClaw `NO_REPLY`), use it; otherwise emit no outbound user/caller message.
585
+ 3. **Re-open only when:**
586
+ - new `runId` / new child batch key, **or**
587
+ - caller / principal **explicit** steer to reopen, **or**
588
+ - the completion payload carries **materially new** evidence (new HEAD, new blocker class, new PR URL / merge state) — not a re-paste or fat re-embedding of the same rollup / full task text.
589
+ 4. If the harness **storms** replays with no new key: **at most one** fail-loud note to the caller (`completion replay storm; ignoring`), then silent. ⊗ Infinite consolidate loops.
590
+ 5. Fat completion payloads that re-embed full task text, prior prompts, or prior consolidate prose **MUST NOT** be treated as a new mission or as material new evidence.
591
+
592
+ ### Eval checklist (second settle same runId)
593
+
594
+ Given: parent already emitted a consolidate for `runId=R` (or harness batch key `R`).
595
+ Second settle event for `R` arrives with the same claims / equivalent rollup.
596
+ **Expect:** silent / host silent-token path — **not** a new investigation narrative, dual-source re-fetch, or second user-visible final.
597
+
598
+ ### Normative anti-patterns
599
+
600
+ - ⊗ Second+ user-visible "final" for the same settled `runId` without new evidence or explicit reopen
601
+ - ⊗ Full dual-source / full test re-run solely because the settle event was delivered again
602
+ - ⊗ Treating "send consolidated final **now**" wording on a **replay** as authorization to undo a prior consolidate for that batch
603
+ - ⊗ Treating fat prompt / task-text re-embeds in completion payloads as a new mission (#3092)
604
+
605
+ Cross-links: swarm Phase 5 completion-notification / parent handback (`skills/deft-directive-swarm/references/core-phase-5-6.md`); review-monitor empty-settle DoD remains #3044 (empty ≠ done) and is orthogonal — empty is not a latch hit; identical non-empty replay after a prior consolidate **is** a latch hit.
606
+
555
607
  ## 12. Session ritual + `task verify:cache-fresh` gates before `start_agent` (#1348 / #1127)
556
608
 
557
609
  Dispatchers (this orchestrator, swarm Phase 4 dispatch, monitor agents, scheduled / cloud runs) run in a headless worker context and MUST set `DEFT_SESSION_RITUAL_SKIP=1` for dispatched implementation workers. The interactive parent session remains responsible for `task session:start`; worker processes bypass the local `.deft/ritual-state.json` gate explicitly so they do not need per-clone interactive ritual state. When the bypass would hide a stale/missing ritual state, `task verify:session-ritual` prints a warning to stderr; preserve that warning in the dispatch log.
@@ -280,7 +280,7 @@ if m is None:
280
280
  confidence = int(m.group(1)) if m else None
281
281
  ```
282
282
 
283
- The clean threshold is `confidence > 3`, i.e. 4/5 or 5/5. Lower scores indicate Greptile is uncertain -- do NOT exit clean.
283
+ The clean threshold is `confidence >= min_confidence`, where `min_confidence` is the resolved floor from `plan.policy.review.minGreptileConfidence` (#3095): typed project policy > framework dogfood detect (framework source → **5**) > consumer default (**4**, legacy `confidence > 3` / 4/5+). Inspect with `task policy:show --field=minGreptileConfidence`. Lower scores indicate Greptile is uncertain -- do NOT exit clean. Directive dogfood MUST NOT exit CLEAN on 4/5.
284
284
 
285
285
  ### Informal-clean missing canonical fields (#1543)
286
286
 
@@ -333,6 +333,7 @@ def evaluate_clean_gate(
333
333
  ci_failures,
334
334
  errored,
335
335
  terminal_check_run,
336
+ min_confidence=4,
336
337
  ):
337
338
  """Return (is_clean, clean_gate_holdout) per the (6)-condition AND gate.
338
339
 
@@ -347,21 +348,23 @@ def evaluate_clean_gate(
347
348
  non-terminal Greptile conclusion (`queued` / `in_progress` /
348
349
  `cancelled` / `timed_out` / `stale` / `action_required` / `failure`)
349
350
  is NOT clean even when the rolling summary already parses clean (SHA
350
- matches HEAD, confidence > 3, no P0/P1). This is the INCOMPLETE_BUT_RATED
351
- scenario from `skills/deft-directive-review-cycle/SKILL.md` Step 6:
352
- without (6), all five legacy conditions pass and the poller exits CLEAN
353
- prematurely. `ci_failures` (condition 4) is scoped to `CI / *` checks
354
- ONLY -- it does NOT cover the Greptile Review check-run -- so the
355
- terminal Greptile conclusion is a DISTINCT condition that `ci_failures`
356
- cannot stand in for. Mirrors the SKILL.md Step 6 fail-closed all-of's
357
- terminal-check-run field so the swarm-dispatched poller path enforces
358
- the same gate as the one-shot review-cycle entry.
351
+ matches HEAD, confidence >= min_confidence, no P0/P1). This is the
352
+ INCOMPLETE_BUT_RATED scenario from
353
+ `skills/deft-directive-review-cycle/SKILL.md` Step 6: without (6), all
354
+ five legacy conditions pass and the poller exits CLEAN prematurely.
355
+ `ci_failures` (condition 4) is scoped to `CI / *` checks ONLY -- it does
356
+ NOT cover the Greptile Review check-run -- so the terminal Greptile
357
+ conclusion is a DISTINCT condition that `ci_failures` cannot stand in
358
+ for. Mirrors the SKILL.md Step 6 fail-closed all-of's terminal-check-run
359
+ field so the swarm-dispatched poller path enforces the same gate as the
360
+ one-shot review-cycle entry. `min_confidence` defaults to the consumer
361
+ bar (4); resolve via project policy / dogfood (#3095).
359
362
  """
360
363
  if last_reviewed_sha is None or last_reviewed_sha != head_sha:
361
364
  return False, "sha_match"
362
365
  if has_blocking:
363
366
  return False, "has_blocking"
364
- if confidence is None or confidence <= 3:
367
+ if confidence is None or confidence < min_confidence:
365
368
  return False, "confidence"
366
369
  if ci_failures > 0:
367
370
  return False, "ci_failures"
@@ -417,10 +420,10 @@ When ANY of the six conditions below fires, send the corresponding message to `{
417
420
  ALL of:
418
421
  - `last_reviewed_sha` parsed and matches the current PR HEAD SHA (compare via `gh pr view {pr_number} --repo {repo} --json headRefOid --jq .headRefOid`).
419
422
  - `has_blocking` is False (no P0 / P1 findings).
420
- - `confidence > 3` (i.e. 4/5 or 5/5 -- a `confidence == 3` parse is NOT clean; the gate names `clean_gate_holdout="confidence"` and you stay in the loop, you do NOT send the CLEAN message).
423
+ - `confidence >= min_confidence` where `min_confidence` is the resolved policy floor (#3095; consumer default 4 / dogfood 5 -- a score below the floor is NOT clean; the gate names `clean_gate_holdout="confidence"` and you stay in the loop, you do NOT send the CLEAN message).
421
424
  - `gh pr checks {pr_number}` shows no `failure` status on `CI / *` checks.
422
425
  - The Greptile rolling-summary comment body does NOT equal `Greptile encountered an error while reviewing this PR` (errored sentinel; #526).
423
- - `terminal_check_run` is True: the `Greptile Review` check-run on the current HEAD is terminal -- `status == "completed"` AND `conclusion` in `{{success, neutral}}` (#1259). A non-terminal Greptile conclusion (`queued` / `in_progress` / `cancelled` / `timed_out` / `stale` / `action_required` / `failure`) is NOT clean even when the rolling summary already parses clean (the INCOMPLETE_BUT_RATED scenario -- rolling summary posted, SHA matches, confidence > 3, no P0/P1, but the check-run has not terminally landed). This is DISTINCT from the `CI / *` `failure` bullet above: `ci_failures` is scoped to `CI / *` checks only and does NOT cover the Greptile Review check-run, so a non-terminal Greptile conclusion would otherwise slip through. The gate names `clean_gate_holdout="terminal_check_run"` and you stay in the loop.
426
+ - `terminal_check_run` is True: the `Greptile Review` check-run on the current HEAD is terminal -- `status == "completed"` AND `conclusion` in `{{success, neutral}}` (#1259). A non-terminal Greptile conclusion (`queued` / `in_progress` / `cancelled` / `timed_out` / `stale` / `action_required` / `failure`) is NOT clean even when the rolling summary already parses clean (the INCOMPLETE_BUT_RATED scenario -- rolling summary posted, SHA matches, confidence meets min, no P0/P1, but the check-run has not terminally landed). This is DISTINCT from the `CI / *` `failure` bullet above: `ci_failures` is scoped to `CI / *` checks only and does NOT cover the Greptile Review check-run, so a non-terminal Greptile conclusion would otherwise slip through. The gate names `clean_gate_holdout="terminal_check_run"` and you stay in the loop.
424
427
 
425
428
  Send to parent:
426
429
 
@@ -437,7 +440,7 @@ Send to parent:
437
440
  Last reviewed commit: <sha>
438
441
  -- no more polling, exiting now
439
442
 
440
- **Swarm-orchestrated terminal contract (#1364):** when this poller is dispatched as part of a swarm cohort (parent monitor is running `skills/deft-directive-swarm/SKILL.md` Phase 6), this exact subject line -- `PR #{pr_number} CLEAN -- ready for merge` -- with `confidence > 3` recorded on the **current HEAD** is the ONLY acceptable "review complete" signal the swarm monitor accepts toward the Phase 5 -> 6 merge-gate transition. The five other terminal exits below ((2) NEW P0/P1 FINDINGS escalation, (3) ERRORED, (4) TIMEOUT, (5) STALL, (6) INFORMAL-CLEAN) are NOT "review complete" signals for swarm purposes: each one MUST force either fresh poller re-dispatch on the same PR or explicit user escalation BEFORE the monitor surfaces the Phase 5 -> 6 gate. The monitor enforces this structurally via `task swarm:verify-review-clean` (#1364); see `skills/deft-directive-swarm/SKILL.md` Phase 5 Exit Condition for the cohort verifier mandate. A poller that has terminated lifecycle-clean (i.e. the sub-agent process exited normally) but with `clean_gate_holdout != None` HAS NOT "reported review-clean" for swarm-cycle purposes -- the verifier picks the gap up and the monitor re-dispatches.
443
+ **Swarm-orchestrated terminal contract (#1364):** when this poller is dispatched as part of a swarm cohort (parent monitor is running `skills/deft-directive-swarm/SKILL.md` Phase 6), this exact subject line -- `PR #{pr_number} CLEAN -- ready for merge` -- with `confidence >= min_confidence` recorded on the **current HEAD** is the ONLY acceptable "review complete" signal the swarm monitor accepts toward the Phase 5 -> 6 merge-gate transition. The five other terminal exits below ((2) NEW P0/P1 FINDINGS escalation, (3) ERRORED, (4) TIMEOUT, (5) STALL, (6) INFORMAL-CLEAN) are NOT "review complete" signals for swarm purposes: each one MUST force either fresh poller re-dispatch on the same PR or explicit user escalation BEFORE the monitor surfaces the Phase 5 -> 6 gate. The monitor enforces this structurally via `task swarm:verify-review-clean` (#1364); see `skills/deft-directive-swarm/SKILL.md` Phase 5 Exit Condition for the cohort verifier mandate. A poller that has terminated lifecycle-clean (i.e. the sub-agent process exited normally) but with `clean_gate_holdout != None` HAS NOT "reported review-clean" for swarm-cycle purposes -- the verifier picks the gap up and the monitor re-dispatches.
441
444
 
442
445
  ### (2) NEW P0/P1 FINDINGS
443
446
 
@@ -604,5 +607,5 @@ Dogfood lessons captured during the #727 self-review cycle. The template body ab
604
607
  - `meta/lessons.md` `## Orchestrator Role Separation + Canonical Poller Template (2026-04)` -- short cross-reference; the rule body lives in the skills above (per `main.md` Rule Authority [AXIOM]).
605
608
  - #727 -- this template's acceptance issue and the full anti-pattern record (rm-chaining, parsing-bug recurrence, role-conflation in implementation-agent prompts).
606
609
  - #1039 -- (5) STALL terminal exit + Tier 1 instrumentation + Tier 3 per-condition fail-loud (`clean_gate_holdout`); the third recurrence in this template's detector-gap chain after #910 (triple-tier) and #1035 (Tier 2.5 + confidence-heading).
607
- - #1364 -- cohort-level CLEAN verification gate (`task swarm:verify-review-clean`, `scripts/swarm_verify_review_clean.py`). The (1) CLEAN section's swarm-orchestrated terminal contract block declares that only the exact `PR #{pr_number} CLEAN -- ready for merge` subject with `confidence > 3` on current HEAD is an acceptable "review complete" signal for the swarm monitor's Phase 5 -> 6 transition; the cohort verifier picks up any other terminal exit ((2) NEW P0/P1 FINDINGS escalation, (3) ERRORED, (4) TIMEOUT, (5) STALL) and holds the merge gate until fresh poller re-dispatch or explicit user escalation resolves it. Recurrence record: #1166 swarm execution 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".
610
+ - #1364 -- cohort-level CLEAN verification gate (`task swarm:verify-review-clean`, `scripts/swarm_verify_review_clean.py`). The (1) CLEAN section's swarm-orchestrated terminal contract block declares that only the exact `PR #{pr_number} CLEAN -- ready for merge` subject with `confidence >= min_confidence` on current HEAD is an acceptable "review complete" signal for the swarm monitor's Phase 5 -> 6 transition; the cohort verifier picks up any other terminal exit ((2) NEW P0/P1 FINDINGS escalation, (3) ERRORED, (4) TIMEOUT, (5) STALL) and holds the merge gate until fresh poller re-dispatch or explicit user escalation resolves it. Recurrence record: #1166 swarm execution 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". #3095 raises the dogfood floor to 5 via policy.
608
611
  - #2879 -- OpenClaw `sessions_spawn` + parent push/announce completion channel named in Role posture (alongside Warp `start_agent` and grok-build `spawn_subagent`); heartbeat mapping in `docs/subagent-heartbeat.md` and preamble §10.5. Epic #2874.
package/tools/greptile.md CHANGED
@@ -124,7 +124,7 @@ The check run name is `"Greptile Review"` — this must match the context name i
124
124
 
125
125
  1. Check the `deft-directive-review-cycle` skill's Pre-Flight Check section
126
126
  2. Verify `triggerOnUpdates` is enabled — without it, Greptile never produces a follow-up review
127
- 3. Verify the confidence score section is enabled in dashboard settings — the exit condition requires confidence >3
127
+ 3. Verify the confidence score section is enabled in dashboard settings — the exit condition requires confidence >= the resolved floor (`plan.policy.review.minGreptileConfidence`; consumer default 4 / legacy >3; directive dogfood 5 — `task policy:show --field=minGreptileConfidence`, #3095)
128
128
 
129
129
  ## Anti-Patterns
130
130