@deftai/directive-content 0.84.0 → 0.86.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)
@@ -239,6 +239,8 @@ Both commands extract the "Comments Outside Diff" section with surrounding conte
239
239
 
240
240
  ! **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
241
 
242
+ ! **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).
243
+
242
244
 
243
245
 
244
246
  ! 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.
@@ -251,11 +253,17 @@ Both commands extract the "Comments Outside Diff" section with surrounding conte
251
253
 
252
254
  ! 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.
253
255
 
254
- ! **Deterministic review-monitor gate (#2655):** 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, register with `task review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive start_agent|spawn_subagent|cursor-task`. Exit `0` ready / `1` not ready / `2` config. Approach 3 on Tier 1 is a gate failure use `--approach3 --approach3-warned` only on Tier 3 after the user warning.
256
+ ! **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.
257
+
258
+ ! **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.
259
+
260
+
255
261
 
256
262
  ! **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.
257
263
 
258
264
 
265
+ ! **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.
266
+
259
267
  **Approach 1 (preferred -- sub-agent orchestration available per platform descriptor):**
260
268
 
261
269
  ! **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.
@@ -455,6 +455,8 @@ Cross-references: `packages/core/src/swarm/routing.ts` (`SWARM_WORKER_ROLES`), `
455
455
 
456
456
  ! **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
457
 
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.
459
+
458
460
  ! **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.
459
461
 
460
462
  ! **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.
@@ -609,7 +611,16 @@ For each agent's PR:
609
611
  1. ! Check that Greptile has reviewed the latest commit (compare "Last reviewed commit" SHA to branch HEAD)
610
612
  2. ! Verify Greptile confidence score > 3
611
613
  3. ! Verify no P0 or P1 issues remain (P2 are non-blocking style suggestions)
612
- 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).
614
+ 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:
615
+ - **Tier 1 available** (`start_agent`, `spawn_subagent`, Cursor `Task`): 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).
616
+ - **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.
617
+ - ⊗ Split review polling and fix batches across separate leaf agents for the same PR (#727 + #1880 Gap C).
618
+
619
+ ! **Completion-notification decision tree (#2843):** When a background leaf completion notification arrives, parse the terminal message per preamble §11:
620
+ - `DONE` + merge-ready verified (`task pr:merge-ready -- <N>` exit 0): may proceed to merge / `task scope:complete` per Phase 5→6 / Phase 6.
621
+ - `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.
622
+ - `FAILED` / silent (no terminal message): run `task verify:subagent-alive`; on exit 1 print `REDISPATCH_OK` and background-dispatch ONE continuation leaf.
623
+ - ⊗ Treat `DONE` without merge-ready verification as success — that is the false-terminal pattern §11 closes.
613
624
 
614
625
  ### Complete xBRIEFs
615
626
 
@@ -0,0 +1,15 @@
1
+ version: '3'
2
+
3
+ vars:
4
+ DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
5
+
6
+ tasks:
7
+ monitor:
8
+ desc: "Sub-agent heartbeat sweep (#1365 / #2824). Three-state exit (0 ok / 1 stale-or-malformed / 2 config). Alias for the raw subagent-monitor engine."
9
+ dir: '{{.USER_WORKING_DIR}}'
10
+ deps:
11
+ - task: :engine:_ts-build
12
+ cmds:
13
+ - task: :engine:invoke
14
+ vars:
15
+ ENGINE_CMD: 'subagent-monitor {{.CLI_ARGS}}'
package/tasks/docs.yml ADDED
@@ -0,0 +1,37 @@
1
+ version: '3'
2
+
3
+ # Maintainer documentation tasks.
4
+ #
5
+ # docs:rule-map renders the Rule Map: a maintainer-facing view of how the
6
+ # framework's rules are layered and grouped. Source of truth is content/ +
7
+ # tasks/ + the packs; the map is a derived view, so regenerate after changing
8
+ # rules rather than hand-editing the outputs.
9
+ #
10
+ # docs/RULE-MAP.md committed, diff-friendly Markdown (no timestamps)
11
+ # docs/rule-map/index.html gitignored, self-contained interactive explorer
12
+ #
13
+ # Implemented as the `rule-map` engine verb (packages/core/src/render/rule-map.ts),
14
+ # dispatched through the TS engine like the other render gates. No Python, no
15
+ # external dependencies, no network.
16
+
17
+ tasks:
18
+
19
+ rule-map:
20
+ desc: "Build the maintainer Rule Map (docs/RULE-MAP.md + gitignored docs/rule-map/index.html)"
21
+ dir: '{{.USER_WORKING_DIR}}'
22
+ deps:
23
+ - task: :engine:_ts-build
24
+ cmds:
25
+ - task: :engine:invoke
26
+ vars:
27
+ ENGINE_CMD: 'rule-map --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
28
+
29
+ rule-map:check:
30
+ desc: "Fail if committed docs/RULE-MAP.md is out of date (for CI / pre-commit gating)"
31
+ dir: '{{.USER_WORKING_DIR}}'
32
+ deps:
33
+ - task: :engine:_ts-build
34
+ cmds:
35
+ - task: :engine:invoke
36
+ vars:
37
+ ENGINE_CMD: 'rule-map --project-root "{{.USER_WORKING_DIR}}" --check'
package/tasks/policy.yml CHANGED
@@ -62,6 +62,16 @@ tasks:
62
62
  vars:
63
63
  ENGINE_CMD: 'policy enable-value-feedback --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
64
64
 
65
+ clear-value-feedback:
66
+ desc: "Remove typed plan.policy.valueFeedback so trusted-org repos return to org-auto resolution (#2822). -- task policy:clear-value-feedback"
67
+ dir: '{{.USER_WORKING_DIR}}'
68
+ deps:
69
+ - task: :engine:_ts-build
70
+ cmds:
71
+ - task: :engine:invoke
72
+ vars:
73
+ ENGINE_CMD: 'policy clear-value-feedback --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
74
+
65
75
  wip-cap:
66
76
  desc: "Set plan.policy.wipCap=N (#1124 / D4 of #1119). Requires --set N --confirm. Default cap is 20 (#2319; raised from the original 10 per umbrella #1119 Current Shape v3)."
67
77
  dir: '{{.USER_WORKING_DIR}}'
@@ -5,7 +5,7 @@ vars:
5
5
 
6
6
  tasks:
7
7
  register:
8
- desc: "Record an active Approach 1 review-monitor after spawn (#2655). Writes .deft/review-monitor.json at the main worktree root."
8
+ desc: "Claim PR-anchored review-owner lease via sticky GitHub comment (#2814). Does not write local JSON."
9
9
  dir: '{{.USER_WORKING_DIR}}'
10
10
  deps:
11
11
  - task: :engine:_ts-build
@@ -13,3 +13,13 @@ tasks:
13
13
  - task: :engine:invoke
14
14
  vars:
15
15
  ENGINE_CMD: 'review-monitor-register {{.CLI_ARGS}}'
16
+
17
+ release:
18
+ desc: "Release PR-anchored review-owner lease by editing the sticky GitHub comment (#2814)."
19
+ dir: '{{.USER_WORKING_DIR}}'
20
+ deps:
21
+ - task: :engine:_ts-build
22
+ cmds:
23
+ - task: :engine:invoke
24
+ vars:
25
+ ENGINE_CMD: 'review-monitor-release {{.CLI_ARGS}}'
package/tasks/verify.yml CHANGED
@@ -466,3 +466,13 @@ tasks:
466
466
  - task: :engine:invoke
467
467
  vars:
468
468
  ENGINE_CMD: 'verify-review-monitor {{.CLI_ARGS}}'
469
+
470
+ subagent-alive:
471
+ 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)."
472
+ dir: '{{.USER_WORKING_DIR}}'
473
+ deps:
474
+ - task: :engine:_ts-build
475
+ cmds:
476
+ - task: :engine:invoke
477
+ vars:
478
+ ENGINE_CMD: 'verify-subagent-alive {{.CLI_ARGS}}'
@@ -449,6 +449,8 @@ These rules bind **orchestrators** dispatching implementation, fix, or review-cy
449
449
  **Worker-owns-lifecycle (Gap C):**
450
450
 
451
451
  - ! When dispatching an implementation worker, the dispatch envelope MUST declare the unit-of-work boundary explicitly: `stop-at: pr-open` (worker opens PR and exits) OR `drive-to: merge-ready` (worker owns PR + Greptile review cycle + fix batches through merge-ready as ONE unit of work, spawning its own review poller per `skills/deft-directive-review-cycle/SKILL.md` monitoring tiers). Default for story implementation dispatches is `drive-to: merge-ready`.
452
+ - ! **Cursor Task ownership split (#2797 / #2814):** A Cursor `Task` implementation leaf MUST NOT spawn another Cursor `Task` review-monitor: nested Task (leaf spawning leaf) is unsupported/unreliable. A Cursor `drive-to: merge-ready` leaf instead owns a blocking `task pr:watch -- <N>` in its own process. To use an Approach 1 monitor, scope the leaf `stop-at: pr-open`; the orchestrator that owns the Task primitive then launches the sibling monitor and runs `task review-monitor:register -- --pr <N> --monitor-agent-id <id> --platform-primitive cursor-task` (GitHub sticky `<!-- deft:review-owner -->` lease — not local JSON).
453
+ - ⊗ Let a Cursor leaf background `task pr:watch` and claim review monitoring is active. The process dies with the leaf and has no GitHub review-owner lease; treat that claim as a regression/eval failure and let `task verify:review-monitor -- --pr <N>` fail closed.
452
454
  - ! **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 **orchestrator** (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).
453
455
  - ! Workers scoped `drive-to: merge-ready` MUST drive to merge-ready in their own tool loop — pre-PR, push, PR open, review-cycle poll/fix loop, and the #1259 Step 6 fail-closed exit — without handing back at PR-open for the orchestrator to re-dispatch separate leaf agents for review or fixes.
454
456
  - ⊗ Re-dispatch a separate review-monitor or fix agent after an implementation worker exits at PR-open when the original envelope scoped `drive-to: merge-ready` — that split recreates cross-agent state-handoff hazards and terminal lifecycle gaps (#1878 / Gap C).
@@ -502,6 +504,11 @@ The contract in one paragraph:
502
504
 
503
505
  The parent monitor watches the heartbeat file directly (three-state exit 0 ok / 1 stale-or-malformed / 2 config error). Skipping the heartbeat is a hard `⊗` for any long-running sub-agent: a stalled agent with no heartbeat surface is the exact #1166 failure mode this contract closes.
504
506
 
507
+ ! **Cursor false-alive / REDISPATCH_OK (#2824):** On the Cursor `Task` path, the host may report a leaf as "still running" after it has gone silent (empty transcript, no heartbeats, no DONE/FAILED). When `task verify:subagent-alive` exits `1` for a registered in-flight `drive-to: merge*` worker — missing heartbeat, STALE heartbeat, or no recent git/PR activity — the monitor MUST treat the worker as dead and print `REDISPATCH_OK` to authorize takeover re-dispatch. Do NOT block on host resume when the liveness gate has failed closed.
508
+
509
+ - Monitors run `task verify:subagent-alive -- --require-agent <agent-id> [--scratch-dir <worktree>/.deft-scratch/subagent-status]` each poll iteration.
510
+ - Workers run `task agent:monitor` (raw sweep) or the gate verb above; both wrap `subagent-monitor` (#1365).
511
+
505
512
  ## 11. Mandatory DONE message even on early exit
506
513
 
507
514
  Every worker MUST send a final status message before exiting its tool loop, regardless of outcome:
@@ -511,6 +518,12 @@ Every worker MUST send a final status message before exiting its tool loop, rega
511
518
  - Failure: `FAILED: <reason> + recovery hint`
512
519
  - Stand-down: `STOOD-DOWN: <reason>` (e.g. user said "wait" with no follow-up dispatch)
513
520
 
521
+ ! **`drive-to: merge-ready` DONE reservation (#2843):** When the dispatch envelope scoped `drive-to: merge-ready` (or `drive-to: merge`), `DONE` is reserved for merge-ready completion — `task pr:merge-ready -- <N>` exit 0 on current HEAD, or merge + `task scope:complete` when the envelope included merge authority. Greptile P0/P1 outstanding, CI failure, branch behind, review-cycle cap, or any other merge blocker MUST NOT exit as `DONE`.
522
+
523
+ ! **Mid-cycle BLOCKED contract (#2843):** A `drive-to: merge-ready` worker that must exit before merge-ready (blocker, cap, context limit, host turn budget) MUST emit `BLOCKED:` (never `DONE`) with: PR number (or `no-pr`), HEAD SHA, blocker class (`greptile_p0_p1` / `ci_failures` / `behind_base` / `review_cycle_cap` / `context_limit` / other), worktree path, and `REDISPATCH_OK` when a continuation leaf should take over. Example: `BLOCKED: Greptile P1 on HEAD abc1234 (PR #2842, blocker greptile_p0_p1, worktree .deft-scratch/worktrees/2839-appsec, REDISPATCH_OK)`.
524
+
525
+ ⊗ Emit `DONE` from a `drive-to: merge-ready` worker while merge-ready is false — a false-terminal `DONE` pulls the cohort monitor into inline Greptile fixes and violates Gap D (#2843 monitor-as-implementer recurrence).
526
+
514
527
  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.
515
528
 
516
529
  ## 12. Session ritual + `task verify:cache-fresh` gates before `start_agent` (#1348 / #1127)
@@ -13,7 +13,8 @@ Directive runs against arbitrary repositories, including private monorepos with
13
13
  ## Rules
14
14
 
15
15
  - ! Read-only, session-start, and session-ritual flows (`deft session:start`, `deft verify:session-ritual`, `deft verify:tools`) MUST perform no npm/pnpm registry access. Tool-presence probes MUST use PATH lookups (`which`/`accessSync`) or `--version` checks, never a subcommand that can resolve dependencies or query a registry.
16
- - ! `deft doctor` MUST default to an OFFLINE tier: no check in the default run may contact an npm/pnpm registry. The one check that can (`payload-staleness`, which uses `git ls-remote` to verify the installed pin and `npm view <package> version` to compare a release-tag install with the latest stable package) is gated behind the explicit `--network` flag and is skipped by default with a pointer to that flag.
16
+ - ! `npm config get @deftai:registry` and `npm config get registry` are offline configuration reads, not registry access. `deft doctor` MAY use them in its default tier to identify effective routing, but MUST NOT print the raw values because registry URLs can contain internal hostnames or credentials.
17
+ - ! `deft doctor` MUST default to an OFFLINE tier: no check in the default run may contact an npm/pnpm registry. The one check that can (`payload-staleness`, which uses `git ls-remote` to verify the installed pin and `npm view <package> version --registry=https://registry.npmjs.org/ --ignore-scripts` to compare a release-tag install with the latest stable package) is gated behind the explicit `--network` flag and is skipped by default with a pointer to that flag.
17
18
  - ! Before a network-gated check runs, `deft doctor --network` MUST print a disclosure line naming the tool and registry class it may contact (for example, "may contact your git remote and the npm registry") BEFORE any network call is attempted.
18
19
  - ! Any future doctor check, session step, or read-only command that needs to invoke `npm`/`pnpm` in a way that can reach a registry MUST follow the same pattern: explicit flag or subcommand, disclosed registry class before the call, and offline by default.
19
20
  - ~ Where a package-manager operation is unavoidable in an explicitly-invoked flow (e.g. a release or install workflow that legitimately needs to fetch packages), prefer offline/frozen modes (`--offline`, `--prefer-offline`, `--frozen-lockfile`) when the operation only needs to validate local state rather than resolve fresh metadata.
@@ -26,4 +27,4 @@ This does not ban dependency installation or registry verification from explicit
26
27
 
27
28
  ## Reference implementation
28
29
 
29
- `packages/core/src/doctor/payload-staleness.ts` is the only code path in the TS engine that shells out to `npm` (`npm view`) or performs a git-remote network call for framework-currency checks; `packages/core/src/doctor/main.ts` gates it behind `--network` and prints the disclosure line first. `packages/core/src/session/session-start.ts` and `packages/core/src/verify-env/verify-tools.ts` perform no package-manager network access at all -- tool presence is resolved via PATH probing only.
30
+ `packages/core/src/doctor/npm-registry.ts` performs only the two offline `npm config get` reads above and redacts their values from findings. `packages/core/src/doctor/payload-staleness.ts` owns the network-capable doctor probes (`git ls-remote` and `npm view`); `packages/core/src/doctor/main.ts` gates them behind `--network` and prints the disclosure line first. The npm release lookup pins `--registry=https://registry.npmjs.org/` and `--ignore-scripts`, so a configured mirror cannot silently report an old latest release. `packages/core/src/session/session-start.ts` and `packages/core/src/verify-env/verify-tools.ts` perform no package-manager network access at all -- tool presence is resolved via PATH probing only.