@deftai/directive-content 0.113.2 → 0.115.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.
- package/commands.md +6 -2
- package/contracts/design-critique.md +44 -32
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +5 -5
- package/scm/github.md +32 -0
- package/skills/deft-directive-build/SKILL.md +3 -1
- package/skills/deft-directive-design-critique/SKILL.md +2 -1
- package/skills/deft-directive-pre-pr/SKILL.md +12 -5
- package/skills/deft-directive-review-cycle/SKILL.md +8 -2
- package/skills/deft-directive-setup/SKILL.md +4 -4
- package/skills/deft-directive-swarm/references/core-phase-0.md +1 -1
- package/skills/deft-directive-swarm/references/core-phase-3.md +1 -1
- package/skills/deft-directive-swarm/references/host-cursor.md +34 -14
- package/skills/deft-directive-swarm/references/host-grok-build.md +12 -0
- package/tasks/scm.yml +1 -1
- package/tasks/verify.yml +10 -0
- package/templates/agent-prompt-preamble.md +9 -2
- package/templates/agents-entry.md +7 -3
- package/templates/design-critique-brief.md +1 -1
- package/templates/swarm-greptile-poller-prompt.md +77 -1
package/scm/github.md
CHANGED
|
@@ -38,6 +38,37 @@ Rules that apply to every `gh` invocation, regardless of context.
|
|
|
38
38
|
- ⊗ Construct Markdown-rich `gh api -f body="..."` or `gh issue comment --body "..."` commands when the body contains backticks, dollar signs, quotes, or fenced code blocks -- use a body file and the `scm:body:*` wrapper instead
|
|
39
39
|
- ⊗ Write `--body-file` temp files inside the worktree or repository directory -- always use the OS temp directory (`$env:TEMP` on PowerShell, `$TMPDIR` or `/tmp` on Unix)
|
|
40
40
|
|
|
41
|
+
### Explicit PR bodies skip the GitHub template (#4293)
|
|
42
|
+
|
|
43
|
+
`gh pr create --body-file`, `--body`, and `--fill` replace `.github/PULL_REQUEST_TEMPLATE.md`. They do not fill it. Leftover-complete and `swarm:finalize-cohort` openers use an explicit body.
|
|
44
|
+
|
|
45
|
+
- ! Compose the template `Documentation impact` block (`change_class` / `surfaces` / quoted `rationale`) into the body-file or `--body` payload before create or edit
|
|
46
|
+
- ! Run `task verify:docs-impact -- --body-file <path>` on that same file object, then pass `--body-file <path>` to `gh pr create` / `gh pr edit`. The verified bytes are the uploaded bytes
|
|
47
|
+
- ⊗ Treat a custom `--body-file` as an exemption from the declaration
|
|
48
|
+
- ⊗ Verify file A then upload file B
|
|
49
|
+
- ⊗ Treat naming the check in pre-pr / review-cycle / swarm story-open as the leftover-complete or finalize-cohort remedy
|
|
50
|
+
- ⊗ Invent `scm:pr:create` -- `tasks/scm.yml` has `body:pr:edit` only; create stays `gh pr create --body-file`
|
|
51
|
+
|
|
52
|
+
**PowerShell (PR open, leftover-complete included):**
|
|
53
|
+
|
|
54
|
+
```powershell
|
|
55
|
+
$bodyFile = [System.IO.Path]::GetTempFileName()
|
|
56
|
+
# $content already includes the template Documentation impact block
|
|
57
|
+
[System.IO.File]::WriteAllText($bodyFile, $content, [System.Text.UTF8Encoding]::new($false))
|
|
58
|
+
task verify:docs-impact -- --body-file $bodyFile
|
|
59
|
+
gh pr create --title "feat: example" --body-file $bodyFile
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Unix (bash/zsh):**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
bodyFile=$(mktemp)
|
|
66
|
+
# $content already includes the template Documentation impact block
|
|
67
|
+
printf "%s" "$content" > "$bodyFile"
|
|
68
|
+
task verify:docs-impact -- --body-file "$bodyFile"
|
|
69
|
+
gh pr create --title "feat: example" --body-file "$bodyFile"
|
|
70
|
+
```
|
|
71
|
+
|
|
41
72
|
## Safe Markdown Body Posting (#1555)
|
|
42
73
|
|
|
43
74
|
Use `task scm:body:*` (`scm:body:comment:create`, `scm:body:issue:edit`, `scm:body:pr:edit`) whenever an agent needs to post or edit Markdown-rich GitHub text. The helper accepts `--body-file <path>`, wraps the body as JSON, calls `gh api --input -` with explicit UTF-8 encoding, and prints the live read-back object returned by `gh`.
|
|
@@ -214,6 +245,7 @@ On Windows PowerShell (5.1 and often `pwsh` when commands are not routed through
|
|
|
214
245
|
$bodyFile = [System.IO.Path]::GetTempFileName()
|
|
215
246
|
[System.IO.File]::WriteAllText($bodyFile, $prBody, [System.Text.UTF8Encoding]::new($false))
|
|
216
247
|
git commit -F $bodyFile
|
|
248
|
+
task verify:docs-impact -- --body-file $bodyFile
|
|
217
249
|
gh pr create --title "feat: example" --body-file $bodyFile
|
|
218
250
|
```
|
|
219
251
|
|
|
@@ -277,7 +277,9 @@ Multi-iteration implement-fix and pre-PR polish loops MUST carry **both** a succ
|
|
|
277
277
|
|------------|--------------|----------------------|
|
|
278
278
|
| Implement / quality fix (tests, lint, typecheck, coverage, AC) | Affected/static gates green for the change; AC met | **max 5** fix iterations **or** **3** consecutive identical outcomes (same failing command + same primary error class) with no material code/config change |
|
|
279
279
|
| Pre-PR polish (`deft-directive-pre-pr` Read-Write-Lint-Diff) | Full pass with zero further edits | **max 3** polish passes **or** **2** consecutive no-diff / same-diff outcomes |
|
|
280
|
-
| Full `task check` re-run after a red merge chokepoint
|
|
280
|
+
| Full `task check` re-run | `task check` green after a red merge chokepoint or a new commit | Counts toward the implement/quality fix envelope above (do not open a separate unbounded check-retry loop) |
|
|
281
|
+
|
|
282
|
+
- ! Re-run full `task check` only after a red merge chokepoint or a new commit.
|
|
281
283
|
|
|
282
284
|
**On failure stop:**
|
|
283
285
|
|
|
@@ -45,12 +45,13 @@ Comment lead (model then role): Stop 3 — Critic envelope.
|
|
|
45
45
|
Operator-gated loop. Successor lean. Parent-side substantiation. Operator verbs. Dual stop. Halt line. Bind after accepted synthesis.
|
|
46
46
|
After this round's siblings are posted: successor lean, then verbs.
|
|
47
47
|
Auto-stamp after operator confirm; not while same-round siblings outstanding.
|
|
48
|
+
Yolo standing confirm of a posted all-accept map: Operator verbs. Confirm conjunct only. Not ingest.
|
|
48
49
|
Walk / walk all. Auto-stamp when agents agree: Operator verbs.
|
|
49
50
|
Parent chip write: scm:issue:design-critique-chip.
|
|
50
51
|
Chip apply miss is non-blocking convenience; do not halt. Ingest waits on the completed-arc record, not a catalog chip.
|
|
51
52
|
Run posture: parse closed tokens; else ask. Field lives in the contract.
|
|
52
53
|
Grok-bot detect default and widget apply-set live in the contract. Consume parseOperatorRunPosture.
|
|
53
|
-
Widgets: numbered Discuss and Back. Plain English first in main-chat.
|
|
54
|
+
Widgets: numbered Discuss and Back. Plain English first in main-chat. `## Plain-language summary`.
|
|
54
55
|
|
|
55
56
|
Each critic dispatch EXITs after posting.
|
|
56
57
|
|
|
@@ -64,11 +64,12 @@ task verify:plan-sequence -- --target-kind <entry-kind> --target <entry-id>
|
|
|
64
64
|
|
|
65
65
|
> **Invariant:** every change MUST pass the full gate at least once before merge. Pre-PR is the merge chokepoint — NOT every iteration commit.
|
|
66
66
|
|
|
67
|
-
- ! **Iteration lane (Phases 2–3 loop):** use affected/static gates on changed paths — `vitest run --coverage <paths>`, relevant `verify:*` on touched files, `task coverage:hotspots` — instead of full `task check` on every pre-PR iteration.
|
|
68
|
-
- ! **Merge chokepoint (
|
|
67
|
+
- ! **Iteration lane (Phases 2–3 loop):** use affected/static gates on changed paths — `vitest run --coverage <paths>`, relevant `verify:*` on touched files, `task coverage:hotspots` — instead of full `task check` on every pre-PR iteration. Phase 3 sits inside this loop, so it uses the iteration lane, not a full suite.
|
|
68
|
+
- ! **Merge chokepoint (once after the loop, before push/PR):** run full `task check` once before push/PR. This is a #1704 revision of the prior Phase 3 Lint exit + final confirm (two runs, one inside every iteration). The escape-rate guard below still applies; do not invent a separate surface.
|
|
69
69
|
- ! **Escape-rate safety (#1703 Tier-1):** before recommending fleet-wide fast-lane tightening, cite `#1703` Tier-1 telemetry (`helped/crud-metrics.jsonl`) and `task eval:health` — do NOT invent a separate escape-rate surface.
|
|
70
70
|
- ~ **In-engine incrementality (#1713):** content-hash cache + runner-delegated affected selection are sibling work (#1713).
|
|
71
71
|
- ⊗ Treat Phase 3c targeted coverage alone as PR-ready without full `task check` at the merge chokepoint.
|
|
72
|
+
- ⊗ Run full `task check` inside every pre-PR Phase 3 iteration — Phase 3 is inside the loop; the chokepoint is once after exit.
|
|
72
73
|
|
|
73
74
|
## When to Use
|
|
74
75
|
|
|
@@ -90,6 +91,7 @@ Each iteration proceeds through all phases in order. Do NOT skip phases or reord
|
|
|
90
91
|
- ~ If changed files include `xbrief/PROJECT-DEFINITION.xbrief.json`, a configured `codebase-map` provider artifact, or `.planning/codebase/MAP.md`, read the MAP and canonical metadata together. The MAP is orientation; `plan.architecture.codeStructure` and provider artifacts remain authoritative.
|
|
91
92
|
- ! When adding a `!` or `⊗` rule that prohibits a specific command, pattern, or behavior, search the same file for any `~`, `≉`, or prose that recommends or permits the same command/pattern -- resolve all contradictions in the same commit before pushing
|
|
92
93
|
- ! When strengthening a rule (e.g. upgrading `~` to `!`), grep for the term in the full file and verify no weaker-strength duplicate remains
|
|
94
|
+
- ! When adding a weaker rule (`~`, `≉`, or prose that recommends or permits a command/pattern) beside an existing `!` or `⊗` for the same command/pattern in the same file, resolve the contradiction in the same commit — weaken-beside-a-MUST is the same-commit reconcile as adding or strengthening a MUST (#4135 / #4324)
|
|
93
95
|
- ~ Note any inconsistencies, missing RFC2119 markers, stale cross-references, or incomplete sections
|
|
94
96
|
- ~ Check that CHANGELOG.md entries match the actual changes made
|
|
95
97
|
- ! If the change alters **user-visible behavior**, apply [coding/docs.md](../../coding/docs.md) (#447): update the matching user-facing surface (CHANGELOG when user/operator-visible, CLI help / commands.md for new or changed verbs/flags, README/getting-started for install/first-run, skill/strategy triggers when entry points change) in this PR
|
|
@@ -108,9 +110,9 @@ Each iteration proceeds through all phases in order. Do NOT skip phases or reord
|
|
|
108
110
|
|
|
109
111
|
### Phase 3 -- Lint
|
|
110
112
|
|
|
111
|
-
! Run the
|
|
113
|
+
! Run the iteration-lane gates and fix any failures (#1704). Full `task check` is the post-loop merge chokepoint, not this per-iteration phase.
|
|
112
114
|
|
|
113
|
-
- ! Run
|
|
115
|
+
- ! Run affected/static gates on changed paths (`vitest run --coverage <paths>`, relevant `verify:*`, `task coverage:hotspots`) — not full `task check` inside the loop
|
|
114
116
|
- ! Fix all failures before proceeding to Phase 3b
|
|
115
117
|
- ~ If a lint fix requires changing a file, that counts as a change for the Loop phase
|
|
116
118
|
|
|
@@ -210,7 +212,10 @@ A red product verification may be resolved only by a product change or an indepe
|
|
|
210
212
|
! Exit when a complete Read-Write-Lint-Diff cycle produces **zero changes** -- no file edits in Write, no lint fixes in Lint, and no scope issues in Diff.
|
|
211
213
|
|
|
212
214
|
After exiting:
|
|
213
|
-
- ! Run `task check`
|
|
215
|
+
- ! Run full `task check` once — the merge chokepoint. Phase 3 used the iteration lane, so this is the first full suite in the loop, not a second run.
|
|
216
|
+
- ! If that post-loop `task check` is red and the fix changes files, restart from Phase 1 (Read). Do not only re-run the gate — those edits must pass Read and Diff (#4324).
|
|
217
|
+
- ! After that restart exits with zero changes, run full `task check` once again (recovery after a red merge chokepoint).
|
|
218
|
+
- ! Re-run the full gate only after a red merge chokepoint or a new commit.
|
|
214
219
|
- ~ The branch is now ready for push and PR creation
|
|
215
220
|
|
|
216
221
|
|
|
@@ -233,6 +238,8 @@ Docs: `docs/decision-log.md`.
|
|
|
233
238
|
- ⊗ Make out-of-scope fixes during Write -- this introduces scope creep that Diff will flag, forcing another iteration
|
|
234
239
|
- ⊗ Ignore the iteration count -- more than 3 iterations usually indicates oscillating fixes or an unclear spec task
|
|
235
240
|
- ⊗ Add a prohibition (`!` or `⊗`) without scanning the same file for conflicting softer-strength rules (`~`, `≉`) that reference the same term
|
|
241
|
+
- ⊗ Add a weaker rule (`~` / `≉`) beside an existing `!` / `⊗` for the same command/pattern without reconciling in the same commit
|
|
242
|
+
- ⊗ After a red post-loop `task check`, fix files and re-run only the gate without restarting Read-Write-Lint-Diff
|
|
236
243
|
- ⊗ Skip `task pr:check-closing-keywords` (#737) before pushing a PR. Intent mode (#3015) also refuses bare/conditional real `Closes #N` without `--allow-close`. The negation-context substring match is the Layer 0 (prevention) gate that prevents the recurring auto-close of umbrella / staying-OPEN issues observed in #697 (closed #642), #401 (closed #642), #700 (closed #233), and #735 (closed #734) -- each incident required manual reopen and downstream cleanup. The lint's three-state exit (0 clean / 1 hits found / 2 config error) MUST be treated as a hard refusal: rewrite the PR body / commit messages until clean, OR pass `--allow-known-false-positives` ONLY for legitimately-quoted occurrences (test fixtures, documentation that discusses the trigger token literally). See `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 1 for the corresponding Layer 3 (recovery) `pr:check-protected-issues` rule (#701)
|
|
237
244
|
- ⊗ Invent remote PR/SHA/CI/review claims in handoff evidence without same-turn probe binding — invented-done (#3120)
|
|
238
245
|
- ⊗ Fill remote ship/gate fields from memory when only local work completed; legal partial omits PR fields (#3120)
|
|
@@ -494,7 +494,7 @@ Workflow failover arming (Blacksmith cancelled → GH-hosted lane) is sibling is
|
|
|
494
494
|
|
|
495
495
|
! Auto-restart detection -- when the polling loop observes a NEW `startedAt` (Greptile dropped its prior check run and started a fresh one without any push from the agent, e.g. service-side restart), the agent MUST reset its elapsed-time clock to the new `startedAt` AND notify the user that an auto-restart was detected. Resetting the clock without notifying is forbidden -- the user needs to know the cycle effectively re-started.
|
|
496
496
|
|
|
497
|
-
! **`INCOMPLETE_BUT_RATED` stall signature (#1259):** when a poll observes a parsed `Confidence Score: X/5` number BUT no terminal check-run (no `completed` status with a `{success, neutral}` conclusion) AND/OR no HEAD-matching `Last reviewed commit:` completion marker, classify the state as **`INCOMPLETE_BUT_RATED`** — Greptile has emitted a confidence rating against a review that has NOT terminally landed on the current HEAD. This is NOT an exit condition (the Step 6 fail-closed all-of resolves the missing fields to `unknown`); treat it as a stall signature and keep polling, escalating per the 10-minute threshold above if it persists. A confidence number is the single most common false-positive for a premature exit — `INCOMPLETE_BUT_RATED` names the trap so the agent does not mistake a rating for a verdict.
|
|
497
|
+
! **`INCOMPLETE_BUT_RATED` stall signature (#1259):** when a poll observes a parsed `Confidence Score: X/5` number BUT no terminal check-run (no `completed` status with a `{success, neutral}` conclusion) AND/OR no HEAD-matching `Last reviewed commit:` completion marker, classify the state as **`INCOMPLETE_BUT_RATED`** — Greptile has emitted a confidence rating against a review that has NOT terminally landed on the current HEAD. This is NOT an exit condition (the Step 6 fail-closed all-of resolves the missing fields to `unknown`); treat it as a stall signature and keep polling, escalating per the 10-minute threshold above if it persists. A confidence number is the single most common false-positive for a premature exit. Thin HTML `<!-- greptile_summary -->` with confidence and no Last reviewed commit is the #4289 named state, not INCOMPLETE_BUT_RATED — `INCOMPLETE_BUT_RATED` names the trap so the agent does not mistake a rating for a verdict.
|
|
498
498
|
|
|
499
499
|
⊗ Auto-retrigger Greptile (empty commits, force-pushes, agent-posted `@greptileai` comments, status-check rebuilds) without explicit user approval. The escalation menu's option 2 is the ONLY supported re-trigger path, and even that requires the user to pick it.
|
|
500
500
|
|
|
@@ -778,8 +778,13 @@ NOTES: <short>
|
|
|
778
778
|
```
|
|
779
779
|
|
|
780
780
|
A missing or non-matching completion marker is `unknown`. See [`../../templates/swarm-greptile-poller-prompt.md`](../../templates/swarm-greptile-poller-prompt.md) `### Last reviewed commit:` for the canonical regex shared with the push-driven poller loop.
|
|
781
|
+
|
|
782
|
+
! **Thin HTML named state (#4289):** when the rolling summary is `<!-- greptile_summary -->` with a parsed `Confidence Score` and **no** `Last reviewed commit:` line, this is **not** `INCOMPLETE_BUT_RATED` and **not** #1543 informal-clean. Pin HEAD via the already-fetched `Greptile Review` check-run on current HEAD (`completed` + `{success,neutral}`), not `pending_required`. Name both SHA gates (`evaluateCleanGate` and `evaluateGates` / `findLastReviewedCommitSha`). Body SHA remains preferred when present. Findings for this shape come from REST `pulls/<N>/comments` and/or check-run `N comments added` text -- vacuous `detect()` zeros are not a findings pin. Missing findings channel fail-closes (do not CLEAN on confidence plus terminal check-run plus detect zeros). Dirty REST P0/P1 is NEW_P0_P1 without a body SHA.
|
|
783
|
+
|
|
784
|
+
Open-PR symptom if that pin or findings channel is missing (do **not** bind every-consumer-until-TIMEOUT): blocking `pr:watch` waits to cap TIMEOUT; `--one-shot` is PENDING; `pr:merge-ready` is a parse fail; swarm poller STALLs; this Step 6 field stays `unknown`. Keep #4288 as the merged/closed terminal.
|
|
785
|
+
|
|
781
786
|
4. ! **Confidence meets resolved min (#3095)** — the parsed `Confidence Score: X/5` is **>=** the resolved floor from `plan.policy.review.minGreptileConfidence` (inspect: `task policy:show --field=minGreptileConfidence`; `pr:watch` / `pr:merge-ready` share this SoT). Resolution order: typed project policy > framework dogfood detect (framework source → **5**) > consumer default (**4**, legacy confidence > 3 / 4/5+). A score below the floor, an unparsed confidence, or an absent confidence is `unknown`. Directive dogfood MUST NOT exit CLEAN on 4/5.
|
|
782
|
-
5. ! **No P0/P1 findings** — the triple-tier (+ Tier 2.5) detector reports zero P0 and zero P1 findings (P2 issues are non-blocking style suggestions and do not gate the loop).
|
|
787
|
+
5. ! **No P0/P1 findings** (thin HTML #4289: REST pulls comments and/or check-run comments-added, not rolling-summary detect zeros) — the triple-tier (+ Tier 2.5) detector reports zero P0 and zero P1 findings (P2 issues are non-blocking style suggestions and do not gate the loop).
|
|
783
788
|
|
|
784
789
|
! All five fields MUST hold on the SAME single fresh fetch. The agent MUST NOT assemble a "pass" by combining a terminal check-run observed on one poll with a confidence parsed on an earlier poll — the read is atomic per the SHA-pinned-AT-READ-TIME rule above.
|
|
785
790
|
|
|
@@ -962,6 +967,7 @@ task lifecycle:event -- emit plan:approved \
|
|
|
962
967
|
- ⊗ Run a partial test suite instead of `task check` without documenting the pre-existing failure reason and open issue number in the PR body
|
|
963
968
|
- ⊗ Create a PR without running `skills/deft-directive-pre-pr/SKILL.md` first -- the pre-PR quality loop catches issues before they reach the reviewer
|
|
964
969
|
- ⊗ Activate Approach 3 (blocking `Start-Sleep` loop) without first warning the user that it will lock the conversation pane and receiving confirmation
|
|
970
|
+
- ⊗ CLEAN thin HTML on parsed confidence plus a terminal Greptile Review check-run plus vacuous detect() zeros -- findings come from REST pulls comments and/or comments-added (#4289)
|
|
965
971
|
- ⊗ 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)
|
|
966
972
|
- ⊗ 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)
|
|
967
973
|
- ⊗ Merge on mechanical Ready-to-merge / green checks while bot comment prose records should-not-merge or confidence below `minGreptileConfidence` (#3225 / #3095)
|
|
@@ -607,8 +607,7 @@ omit = [
|
|
|
607
607
|
"Strategy": "Use {strategy name} for this project",
|
|
608
608
|
"Quality": "Run task check before every commit. Achieve >= {coverage}% coverage overall + per-module. Store secrets in secrets/ dir.",
|
|
609
609
|
"ProjectRules": "{Any rules the user specified, or 'No project-specific rules defined.'}",
|
|
610
|
-
"Branching": "{If confirmed trunk-based: 'Trunk-based workflow', otherwise 'Branch-based workflow (default)'}"
|
|
611
|
-
"DeftVersion": "0.20.0"
|
|
610
|
+
"Branching": "{If confirmed trunk-based: 'Trunk-based workflow', otherwise 'Branch-based workflow (default)'}"
|
|
612
611
|
},
|
|
613
612
|
"items": []
|
|
614
613
|
}
|
|
@@ -871,8 +870,9 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
871
870
|
|
|
872
871
|
## Anti-Patterns
|
|
873
872
|
|
|
874
|
-
- ! When deft-directive-setup generates or updates USER.md
|
|
875
|
-
- ⊗ Generate a USER.md
|
|
873
|
+
- ! When deft-directive-setup generates or updates USER.md, the `deft_version` field MUST be set to the current framework version. USER.md is the only artifact that carries this field.
|
|
874
|
+
- ⊗ Generate a USER.md without including the `deft_version` field
|
|
875
|
+
- ⊗ Write `deft_version` or `DeftVersion` into PROJECT-DEFINITION, specification, or plan xBRIEFs. Those stamps are retired (HASH4271). Specification `deft_version` has no framework seeding path; Pass 1 absence locks are the only control.
|
|
876
876
|
- ⊗ Explore codebase before Phase 1 questions
|
|
877
877
|
- ⊗ Read framework files before first question
|
|
878
878
|
- ⊗ Batch multiple questions into one message — ask one at a time, interview style
|
|
@@ -46,7 +46,7 @@ Cross-links: Phase 3 Worker-owns-lifecycle (`references/core-phase-3.md`), revie
|
|
|
46
46
|
### Headless cohort fast-path: low-ceremony launch (C1 / #1387)
|
|
47
47
|
|
|
48
48
|
! `task swarm:launch` claims this worktree occupancy lease (`intent: swarm`) before emitting the manifest (#3433). A live foreign occupant fails closed.
|
|
49
|
-
! **Spawned mutating workers take their own worktree (#4066 / #4215).** Phase 2/3 must put each implement/review/fix leaf on a uniquely reserved linked worktree (C3 worktree-map or `git worktree add`) *before* occupancy claim. Sharing the primary checkout with a live occupant is refuse, not grant-across-host. Grok `spawn_subagent` implement dest is `cwd` only. `isolation=worktree` /
|
|
49
|
+
! **Spawned mutating workers take their own worktree (#4066 / #4215 / #4295).** Phase 2/3 must put each implement/review/fix leaf on a uniquely reserved linked worktree (C3 worktree-map or `git worktree add`) *before* occupancy claim. Sharing the primary checkout with a live occupant is refuse, not grant-across-host. Grok `spawn_subagent` implement dest is `cwd` only. Claude/Codex keep `isolation=worktree` / path keys. Cursor Task has no local dest field — local implement is dest-placing (nursery inherit on a dest-rooted window, or dest-rooted `@cursor/sdk` `Agent.create` cwd), not Task dest keys. Do not advertise `worktree_path` for Grok or Task dest keys for Cursor. Terminal release is dispatcher-owned (`phase: terminal` + incarnation); do not tell a refused Grok child to steal master.
|
|
50
50
|
! 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.
|
|
51
51
|
! The **C1** signature is `task swarm:launch -- --stories <ids|paths> [--group <label>] [--worktree-map <path>] [--base-branch <branch>] [--autonomous]`. `--stories` names the pre-approved story ids or xBRIEF paths; `--group` is an optional cohort label; `--worktree-map` points at the pre-created **C3** worktree-map JSON consumed in Phase 2; `--base-branch` overrides the default `master`; `--autonomous` runs without the interactive launch confirmation.
|
|
52
52
|
! The SINGLE consent is the #1378 `## Allocation context` token with `dispatch_kind: swarm-cohort` and a NON-NULL `allocation_plan_id` AND `batching_rationale` (the recognition contract in `templates/agent-prompt-preamble.md` § 2.5). That token IS the batched approval for the whole cohort -- the deterministic-question gates the interactive path runs (per [`../../contracts/deterministic-questions.md`](../../contracts/deterministic-questions.md)) are bypassed wholesale on the headless path, not asked once per phase.
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
8. ! **Select launch path automatically** based on detection results — do NOT present static options:
|
|
34
34
|
- **`start_agent` available** → Orchestrated launch (Step 2a) — preferred path, fully automated, no manual tab management
|
|
35
35
|
- **`start_agent` unavailable, Warp detected** → Interactive Warp tabs (Step 2b) — full MCP, global rules, warm index; requires manual tab management
|
|
36
|
-
- **Cursor
|
|
36
|
+
- **Cursor detected (no `start_agent`, no `WARP_*`)** → Cursor dest-placing launch (Step 2e / `host-cursor.md`) (Tier 1 / Approach 1). Local implement is nursery inherit on a dest-rooted window or dest-rooted `@cursor/sdk` `Agent.create({ local: { cwd } })` with reservation before exec — not Task dest keys. Descriptor is `cursor-composer` (interactive) or `cursor-cloud-agent` (cloud)
|
|
37
37
|
- **Claude Code available (no `start_agent`, no `WARP_*`, no Cursor classification)** → Claude Code launch (Step 2g) via `Agent` with `run_in_background: true` (Tier 1 / Approach 1) — descriptor is `claude-code` (#3134)
|
|
38
38
|
- **OpenClaw `sessions_spawn` available (no `start_agent`, no `WARP_*`, no Cursor, no Claude Code)** → OpenClaw launch (Step 2f) via `sessions_spawn` (Tier 1 / Approach 1) — descriptor is `openclaw`
|
|
39
39
|
- **Grok Bot unique signals available (no earlier Tier-1 primitive)** → Grok Bot launch (Step 2h) via Task/executor/CloudAgent (Tier 1 / Approach 1) — descriptor is `grok-bot` (#4201)
|
|
@@ -2,32 +2,52 @@
|
|
|
2
2
|
|
|
3
3
|
Legend (RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
4
4
|
|
|
5
|
-
Descriptor: `cursor-composer` or `cursor-cloud-agent
|
|
5
|
+
Descriptor: `cursor-composer` or `cursor-cloud-agent`. Detect still probes the Cursor `Task` tool. Local implement launch is dest-placing Cursor, not dest-binding Task (#4295).
|
|
6
6
|
|
|
7
7
|
Load this file only after detect selects Cursor. Do not load other host adapters.
|
|
8
8
|
|
|
9
|
-
! **Windows + Cursor Task-tool console windows (#2563):** Local Cursor
|
|
9
|
+
! **Windows + Cursor Task-tool console windows (#2563):** Local dest-placing Cursor swarms on Windows are first-class. Shipped mitigations (do not regress): `windowsHide: true` (CREATE_NO_WINDOW) on engine/spawn paths, and warm-dist skip via `tasks/ts-build-fresh.cjs` so `engine:_ts-build` does not cold-rebuild when `packages/cli/dist` is current. See `templates/agent-prompt-preamble.md` §3.8. ! Default to **local dest-placing Cursor** on Windows (not cloud-for-Windows; not dest-binding Task). Parallel cohorts are allowed — do not force concurrency=1 for #2563. ⊗ Drop or weaken those mitigations without a replacement that keeps Windows local swarm workable.
|
|
10
10
|
|
|
11
|
-
### Step 2e: Cursor Launch
|
|
11
|
+
### Step 2e: Cursor Launch — dest-placing, not Task dest (#4295 / #1877)
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
0. Create `<worktree>/.deft-scratch/subagent-status/` before spawn if `swarm:launch` / `swarm:pre-dispatch` did not already (#3730). Include preamble § 10.5 (heartbeat + commit early) and poll with `task verify:subagent-alive -- --require-agent <agent-id>`.
|
|
15
|
-
1. The canonical `templates/agent-prompt-preamble.md` content as the preamble (AGENTS.md read mandate, #810 xBRIEF gate, #798 PowerShell UTF-8, pre-PR + review-cycle mandates).
|
|
16
|
-
2. The standard worktree prompt (STEP 1-6 from the Prompt Template below).
|
|
17
|
-
3. The worktree path set to the agent's isolated git worktree.
|
|
18
|
-
4. ! **`run_in_background: true`** for any worker or poller whose loop runs longer than a short task (~3 min) — implementation, fix, and review-cycle workers — so the monitor conversation pane stays interactive (#1880 Gap D). The parent is notified on completion.
|
|
19
|
-
5. ! **Deliberate model routing (#1739):** pass the route's `resolved_model` (when non-null) as the Task tool's `model` argument — stamping the C2 manifest is prep; the recorded model MUST reach the actual spawn call.
|
|
13
|
+
Cursor `Task` has no local dest field. Extra keys (`isolation`, `worktree_path`, `cwd`) are stripped before `preToolUse`. Hook `updated_input` dest fields do not re-root Task. A prompt token may select a trusted reservation record; it does not move the child. Comment 5611146439 stands.
|
|
20
14
|
|
|
21
|
-
|
|
15
|
+
⊗ Dispatch local implement via Cursor `Task` dest keys, a worktree map in the prompt, or inherited primary cwd.
|
|
16
|
+
⊗ Treat a prompt token as moving the child onto a worktree.
|
|
22
17
|
|
|
18
|
+
! **Local implement (required):** dest-placing Cursor. The child process or window folder is an already-created linked worktree *before* it can write.
|
|
19
|
+
|
|
20
|
+
Two local hatches, in this order:
|
|
21
|
+
|
|
22
|
+
1. **Nursery inherit (interactive dest-rooted window).** Open Composer on the reserved linked worktree (not primary). One Task child may inherit that payload root: consult treats the window as dest, mints a unique reservation, and admits the child through `occupancy:grant`. While that grant is live, parent product writes in that tree are denied. A second Task in the same window is reservation-conflict. Nested Task from a dest-rooted session is still dest-missing unless *this* window is the dest. Nursery child `workspace_roots` equal the parent window.
|
|
23
|
+
2. **Headless dest-rooted SDK.** `@cursor/sdk` `Agent.create({ local: { cwd: <reserved-worktree> } })` with `Agent.resume` / `agent.send` as the retain-capable sibling. Reservation before exec. Process-handle liveness (not parent-cwd `verify:subagent-alive`). Doctor check `cursor-sdk-auth` for the separate SDK login (`CURSOR_API_KEY`). The leaf implements in that session and does not nested-Task.
|
|
24
|
+
|
|
25
|
+
! Create `<worktree>/.deft-scratch/subagent-status/` before spawn if `swarm:launch` / `swarm:pre-dispatch` did not already (#3730). Include preamble § 10.5 (heartbeat + commit early). Headless SDK liveness is the process handle; scratch heartbeats remain for dest-rooted Composer sessions.
|
|
26
|
+
! Include the canonical `templates/agent-prompt-preamble.md` content as the preamble.
|
|
27
|
+
! Include the standard worktree prompt (STEP 1-6 from the Prompt Template).
|
|
28
|
+
! **`run_in_background: true`** (or SDK async create) for any worker or poller whose loop runs longer than a short task (~3 min).
|
|
29
|
+
! **Deliberate model routing (#1739):** pass the route `resolved_model` (when non-null) into the actual spawn primitive.
|
|
30
|
+
|
|
31
|
+
~ Cursor stays **Tier 1 → Approach 1**. Do not downgrade to `generic-terminal`. Spawn available means dest-placing dispatch exists, not Task-present (#3032 / #4295).
|
|
32
|
+
? Cloud `Task` (`environment: "cloud"`) is the #4294 dest-consult carve-out. Complementary. Do not treat cloud as local dest-proof. Do not duplicate that hook slice here.
|
|
33
|
+
|
|
34
|
+
### Fence-in-place (parked)
|
|
35
|
+
|
|
36
|
+
Fence-in-place (bind a parent-cwd Task and rewrite writes into `.deft-scratch/worktrees/`) stays parked until measured:
|
|
37
|
+
|
|
38
|
+
- Shell `updated_input.cwd`
|
|
39
|
+
- Write/ApplyPatch path rewrite
|
|
40
|
+
- Composer visibility of gitignored `.deft-scratch/worktrees/`
|
|
41
|
+
|
|
42
|
+
The write gate does not cover Shell or MCP. Relative targets resolve against hook cwd. Bind is specifiable later (`EXACT_LIFECYCLE_VERBS` + identity rewrite; adding `spawn:bind`). ⊗ Sequence `best-of-n-runner` ahead of nursery. ⊗ Primary-window writes through `.deft-scratch/worktrees/`.
|
|
23
43
|
|
|
24
44
|
## Nested Task boundary
|
|
25
45
|
|
|
26
|
-
! Cursor ownership split (#2797 / #2893) lives in `references/core-phase-3.md` Orchestrator dispatch doctrine — a Cursor
|
|
46
|
+
! Cursor ownership split (#2797 / #2893) lives in `references/core-phase-3.md` Orchestrator dispatch doctrine — a Cursor implement leaf MUST NOT nested-spawn a review-monitor Task. Dest-rooted SDK / nursery leaves implement in-session.
|
|
27
47
|
|
|
28
48
|
## Retained / continue-by-id (#3158)
|
|
29
49
|
|
|
30
50
|
! **Default one-shot after Task completion:** Cursor `Task` leaves that exit their tool loop are typically terminal — prefer **split-dispatch** for mid-scope user-approval gates (#954) unless the host surfaces an explicit continue/resume-by-agent-id for that Task.
|
|
31
|
-
?
|
|
32
|
-
! Liveness failures (`task verify:subagent-alive` exit `1` / `REDISPATCH_OK`) still authorize replacement re-dispatch — retain does not override the false-alive contract (#2824).
|
|
51
|
+
? `@cursor/sdk` `Agent.resume` / `agent.send` is retain-capable for the headless dest-rooted path.
|
|
52
|
+
! Liveness failures (`task verify:subagent-alive` exit `1` / `REDISPATCH_OK`) still authorize replacement re-dispatch for Composer heartbeats — retain does not override the false-alive contract (#2824). Headless SDK replacement keys on the process handle.
|
|
33
53
|
~ Stance: orchestration only (#3164).
|
|
@@ -55,6 +55,18 @@ If the leaf needs another agent, it stops and reports `BLOCKED`. The parent owns
|
|
|
55
55
|
! Heartbeat liveness on the Grok Build hybrid path is required — see `references/core-phase-4.md` Heartbeat liveness check (#1365) and `docs/subagent-heartbeat.md`.
|
|
56
56
|
! Poll coordination uses worktree state + `get_command_or_subagent_output` (not OpenClaw parent-announce).
|
|
57
57
|
|
|
58
|
+
## Parent-steer inbox (#4286)
|
|
59
|
+
|
|
60
|
+
! Grok-build leaves still need a parent-writable steer path because this host has no child prompt and no live `resume_from`. Directive owns that path. Do not wait for an xAI input field.
|
|
61
|
+
|
|
62
|
+
! Inbox: `<worktree>/.deft-scratch/subagent-steer/<agent-id>.json` (not heartbeat JSON). Child reads on each pollable slice and acks apply-once via `<agent-id>.ack.json`. `task verify:subagent-steer` is the parent-visible unread flag (`STEER_PENDING`). It is not `REDISPATCH_OK`.
|
|
63
|
+
|
|
64
|
+
! Tool-loop duty: no blocking wait longer than the heartbeat/steer poll interval when the leaf must remain steerable; between slices, read the inbox and rewrite heartbeat. A scratch path does not interrupt a blocked tool.
|
|
65
|
+
|
|
66
|
+
⊗ Replace split-dispatch for mid-scope approval gates with this inbox.
|
|
67
|
+
⊗ Invent OpenClaw `sessions_yield` or live `resume_from` on this host.
|
|
68
|
+
⊗ Drop a second JSON schema into `.deft-scratch/subagent-status/`.
|
|
69
|
+
|
|
58
70
|
## Retained / continue-by-id (#3158)
|
|
59
71
|
|
|
60
72
|
! **Default one-shot:** `spawn_subagent` workers that finish their tool loop are observed terminal (`succeeded` / failed); the `agent_id` is not a general message-later inbox. Mid-scope user-approval gates MUST use **split-dispatch** (#954) unless this host later documents continue-by-agent-id.
|
package/tasks/scm.yml
CHANGED
|
@@ -93,7 +93,7 @@ tasks:
|
|
|
93
93
|
ENGINE_CMD: 'scm issue edit {{.CLI_ARGS}}'
|
|
94
94
|
|
|
95
95
|
issue:design-critique-chip:
|
|
96
|
-
desc: "[#3642] Exclusive design-critique catalog chip -- task scm:issue:design-critique-chip -- --issue N --chip
|
|
96
|
+
desc: "[#3642] Exclusive design-critique catalog chip -- task scm:issue:design-critique-chip -- --issue N --chip mechanism-shaped|in-progress|ingest-ready [--repo OWNER/NAME]"
|
|
97
97
|
dir: '{{.USER_WORKING_DIR}}'
|
|
98
98
|
deps:
|
|
99
99
|
- task: :engine:_ts-build
|
package/tasks/verify.yml
CHANGED
|
@@ -703,3 +703,13 @@ tasks:
|
|
|
703
703
|
- task: :engine:invoke
|
|
704
704
|
vars:
|
|
705
705
|
ENGINE_CMD: 'verify-subagent-alive {{.CLI_ARGS}}'
|
|
706
|
+
|
|
707
|
+
subagent-steer:
|
|
708
|
+
desc: "Parent-visible unread steer flag (#4286): exit 1 is STEER_PENDING, not REDISPATCH_OK. Three-state exit (0 none / 1 unread / 2 config)."
|
|
709
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
710
|
+
deps:
|
|
711
|
+
- task: :engine:_ts-build
|
|
712
|
+
cmds:
|
|
713
|
+
- task: :engine:invoke
|
|
714
|
+
vars:
|
|
715
|
+
ENGINE_CMD: 'verify-subagent-steer {{.CLI_ARGS}}'
|
|
@@ -97,7 +97,7 @@ Populate `selected_backend` OR `routing_policy` (or both when the operator sets
|
|
|
97
97
|
**Role-boundary expectations (all providers):** the same boundaries apply whether the worker runs on Composer, Grok Build, Cursor/cloud, Claude Code, OpenClaw, or a future adapter:
|
|
98
98
|
|
|
99
99
|
- ! `leaf-implementation` workers implement scoped xBRIEF work in their assigned worktree only -- gates (`task check`, file-scope audit, Greptile review cycle) are model-agnostic and MUST still pass.
|
|
100
|
-
- ! **Spawned mutating workers take their own worktree (#4066).** Implement-class spawn must
|
|
100
|
+
- ! **Spawned mutating workers take their own worktree (#4066 / #4295).** Implement-class spawn must dest-place before occupancy claim. Grok `spawn_subagent` dest is `cwd` only (cannot rewrite PreToolUse input). Claude/Codex keep `isolation=worktree` or a linked path. Cursor Task has no local dest field — dest-placing is a dest-rooted window (nursery inherit) or `@cursor/sdk` `Agent.create({ local: { cwd } })`; do not advertise Task dest keys. Sharing the primary checkout with a live occupant is refuse, not `occupancy:grant` across hosts. Master/primary occupancy is the exception (`release-cut`, `policy-restore`, operator-directed default-branch work). `--read-only` never claims. On DONE/terminal the dispatcher compare-and-releases the recorded child tree (incarnation + parent-id); do not steal the parent's lease to recover.
|
|
101
101
|
- ! `orchestrator`, `review-monitor`, and `merge-release` roles MUST run on strong or review-capable agents; dispatchers MUST NOT route these roles to cheap leaf backends.
|
|
102
102
|
- ⊗ Route a cheap leaf backend onto the merge cascade, Phase 5->6 release gate, conflict-resolution rebase, or review-cycle merge-ready decision -- these are irreversible-damage surfaces that stay on the strong tier regardless of provider.
|
|
103
103
|
|
|
@@ -238,7 +238,7 @@ On Windows, Cursor Task-tool local subagents historically opened a visible `cmd.
|
|
|
238
238
|
|
|
239
239
|
**Directive rule for orchestrators on Windows:**
|
|
240
240
|
|
|
241
|
-
- ! Use **local
|
|
241
|
+
- ! Use **local dest-placing Cursor** as the default dispatch path — same as other platforms (nursery inherit or dest-rooted `@cursor/sdk` `Agent.create`; not dest-binding Task). Do not route to cloud solely because the host is Windows.
|
|
242
242
|
- ! Parallel local cohorts are allowed; do not force concurrency=1 because of #2563.
|
|
243
243
|
- ~ Prefer the normal warm `task` / `dist/bin.js` path; avoid unnecessary `DEFT_FORCE_TS_BUILD=1` across a parallel cohort.
|
|
244
244
|
- ⊗ Drop or weaken the #2563 `windowsHide` / warm-dist mitigations without a replacement that keeps Windows local swarm workable.
|
|
@@ -566,6 +566,13 @@ The parent monitor watches the heartbeat file directly (three-state exit 0 ok /
|
|
|
566
566
|
|
|
567
567
|
! **Recovery dispatch vs stale ritual (#3730 / #2992):** Before a replacement spawn, run `task verify:session-ritual -- --tier=gated`. If it fails, run `task session:start --rearm --session-id=<same>` (or the `deft` form) rather than a full cold ceremony, unless re-arm is ineligible. A ritual deny MUST name `session:start --rearm`. Do not treat a bare deny as a dead end, and do not re-arm under a new session id (that reclaims occupancy and blocks the parent's own writes).
|
|
568
568
|
|
|
569
|
+
! **Parent-steer inbox (#4286):** Grok Build `spawn_subagent` has no child prompt and no live `resume_from`. That host gap does not invent retain, OpenClaw `sessions_yield`, or a replacement for split-dispatch mid-scope approval gates. Grok-build implementation leaves whose tool loop exceeds ~3 min MUST still have a parent-writable steer path because the host has no other channel.
|
|
570
|
+
|
|
571
|
+
- Inbox path: `<worktree>/.deft-scratch/subagent-steer/<agent-id>.json` (sibling of heartbeat, not inside `subagent-status/`). Closed schema `deft.subagent.steer.v1`: bound to `agent_id`, `steer_id` apply-once ack, `expires_at`, `writer_kind` `occupancy-owner` | `dispatching-parent`. Ack file: `<agent-id>.ack.json` in the same steer dir. Distinct from the child-owned heartbeat JSON.
|
|
572
|
+
- Tool-loop duty: no blocking wait longer than the heartbeat/steer poll interval (2-3 min) when the leaf must remain steerable. Between slices, read the inbox, apply unread once, rewrite heartbeat. A scratch path does not interrupt a blocked tool. Long `task check` recovery stays REDISPATCH_OK / split-dispatch — not "poll while blocked".
|
|
573
|
+
- Parent-visible unread flag: `task verify:subagent-steer` exit `1` prints `STEER_PENDING`. ⊗ Treat unread steer as missing heartbeat. ⊗ Print `REDISPATCH_OK` from the steer gate. ⊗ Put a second JSON schema in `.deft-scratch/subagent-status/` — `sweepScratchDirs` only reads top-level heartbeat `<agent-id>.json` and skips `deft.subagent.steer*` schema.
|
|
574
|
+
- ⊗ Invent message-later / live `resume_from` on grok-build. ⊗ Treat steer `text` as a new dispatch envelope or constitution edit. Depth: `docs/subagent-heartbeat.md`.
|
|
575
|
+
|
|
569
576
|
## 10.55 Rule Authority and Thin Fail-Closed (#3313)
|
|
570
577
|
|
|
571
578
|
Principle: `main.md` `## Rule Authority [AXIOM]`.
|
|
@@ -31,7 +31,7 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
|
|
|
31
31
|
|
|
32
32
|
! Writes: `./xbrief/` (`PROJECT-DEFINITION.xbrief.json`, `plan.xbrief.json`, `specification.xbrief.json`) as `"xBRIEFInfo"` `"version": "0.8"`. Legacy `vbrief/`; `deft migrate:xbrief`.
|
|
33
33
|
! Completed xBRIEFs are record of *what is*, zero authority over *what to build next* (#3383). Current contract = active xBRIEF + human operator live instruction.
|
|
34
|
-
⊗ Treat a completed xBRIEF as the next-build contract. ⊗ Emit `"version": "0.6"` on new writes.
|
|
34
|
+
⊗ Treat a completed xBRIEF as the next-build contract. ⊗ Emit `"version": "0.6"` on new writes. ⊗ No xBRIEF DeftVersion stamps (#4271).
|
|
35
35
|
|
|
36
36
|
## Unmanaged project header (#2065)
|
|
37
37
|
|
|
@@ -86,7 +86,7 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
|
|
|
86
86
|
|
|
87
87
|
## Through-merge worker dispatch (#3032)
|
|
88
88
|
|
|
89
|
-
! 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).
|
|
89
|
+
! 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). Spawn dest (#4066 / #4295): dest-place implement workers before occupancy. Cursor local is dest-placing (nursery inherit or dest-rooted `@cursor/sdk` `Agent.create`); ⊗ Task dest keys.
|
|
90
90
|
⊗ Parent conversation implements or babysits product fix/CI loops for drive-to:merge-ready work when background subagent/worktree dispatch is available (#3032).
|
|
91
91
|
! After leaf announce: tool-first / yield / one short non-repeated answer; ⊗ N>2 near-identical zero-tool (FC14 / #3131). Machine: `evaluateParentTurnShape` (`parent-turn-shape`). Depth: preamble §11 + `docs/openclaw-agent-host.md`.
|
|
92
92
|
|
|
@@ -109,6 +109,10 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
|
|
|
109
109
|
|
|
110
110
|
! Mid-scope gates: **split-dispatch** when `agent_id` is terminal; retain-capable hosts (continue-by-agent-id / message-later / steer-mid-flight) MAY re-message the live child. Retention = orchestration only — not constitution self-edit (#3164). Depth: preamble §10; `deft-directive-swarm`. Topology: #3155 nuclear-family. ⊗ Invent retain on one-shot hosts.
|
|
111
111
|
|
|
112
|
+
## Parent-steer inbox (#4286)
|
|
113
|
+
|
|
114
|
+
! Grok-build leaves whose tool loop exceeds ~3 min poll `.deft-scratch/subagent-steer/<agent-id>.json` on each pollable slice. `deft verify:subagent-steer` exit 1 is `STEER_PENDING`, not missing-heartbeat takeover. Depth: preamble §10.5; `docs/subagent-heartbeat.md`. ⊗ Replace split-dispatch mid-scope approval gates with this inbox. ⊗ Treat unread steer as REDISPATCH_OK.
|
|
115
|
+
|
|
112
116
|
## Review-surface precedence (#2308)
|
|
113
117
|
|
|
114
118
|
! 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).
|
|
@@ -135,7 +139,7 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
|
|
|
135
139
|
|
|
136
140
|
## Windows PowerShell: multi-line git/gh bodies (#2646 / #2744)
|
|
137
141
|
|
|
138
|
-
! Multi-line git commit / gh issue|pr|comment bodies: write UTF-8 (no BOM) to OS temp, then `git commit -F` / `gh --body-file` / `deft scm:body:* --body-file`. Issue-body RMW on win32: `deft scm:body:issue:fetch --out-file` then edit the file then `deft scm:body:issue:edit --body-file` (#2607 postcondition verify). ⊗ bash heredocs, `<<<`, inline multi-line `--body`, or PS capture-concat of `gh api --jq .body` (string[]/$OFS destroys bodies — #2087, #2741, #1492). Detail: `.deft/core/scm/github.md` § #2646 / #2744. `ghx` is read-only — mutations stay on live `gh`.
|
|
142
|
+
! Multi-line git commit / gh issue|pr|comment bodies: write UTF-8 (no BOM) to OS temp, then `git commit -F` / `gh --body-file` / `deft scm:body:* --body-file`. Issue-body RMW on win32: `deft scm:body:issue:fetch --out-file` then edit the file then `deft scm:body:issue:edit --body-file` (#2607 postcondition verify). ⊗ bash heredocs, `<<<`, inline multi-line `--body`, or PS capture-concat of `gh api --jq .body` (string[]/$OFS destroys bodies — #2087, #2741, #1492). Detail: `.deft/core/scm/github.md` § #2646 / #2744. `ghx` is read-only — mutations stay on live `gh`. Explicit PR `--body-file` / `--body` / `--fill` skip the GitHub template (#4293): compose the template `Documentation impact` block, then `deft verify:docs-impact -- --body-file` on those same bytes (leftover-complete / finalize-cohort).
|
|
139
143
|
|
|
140
144
|
## Contextual guardrails (runtime-detect lazy-load)
|
|
141
145
|
|
|
@@ -12,7 +12,7 @@ Dispatch envelope skeleton for one critic or synthesis pass. Fill the fields. Re
|
|
|
12
12
|
- Critic role (fresh | resume):
|
|
13
13
|
- Id ceiling (GitHub comment id, inclusive):
|
|
14
14
|
- SHA at dispatch:
|
|
15
|
-
- Run posture (`arc-mode:
|
|
15
|
+
- Run posture (`arc-mode: no-ingest` | `arc-mode: checkout`):
|
|
16
16
|
- Target (work issue or umbrella):
|
|
17
17
|
- Audit targets (marker ids, comma-separated, or `none`; ids only, no parent rationale):
|
|
18
18
|
- Seat families (N≥3: three claimed families before spawn):
|
|
@@ -94,6 +94,23 @@ m = re.search(
|
|
|
94
94
|
last_reviewed_sha = m.group("sha") if m else None
|
|
95
95
|
```
|
|
96
96
|
|
|
97
|
+
### Thin HTML named state (#4289)
|
|
98
|
+
|
|
99
|
+
When the body is `<!-- greptile_summary -->` with a parsed Confidence Score and **no** `Last reviewed commit:` line, this is **not** informal-clean and **not** INCOMPLETE_BUT_RATED. Do not scrape the HTML for a SHA.
|
|
100
|
+
|
|
101
|
+
Pin SHA currency to the already-fetched `Greptile Review` check-run on current HEAD (`completed` + `{success, neutral}`), not `pending_required`. Body SHA still wins when present. Findings come from REST `pulls/<N>/comments` and/or check-run `N comments added` text -- vacuous `detect()` zeros are not a findings pin. Missing findings channel fail-closes (`clean_gate_holdout=findings_channel`). Dirty REST P0/P1 is NEW_P0/P1 without a body SHA.
|
|
102
|
+
|
|
103
|
+
If that pin or findings channel is missing, restate the open-PR symptom **per surface** (do not bind every-consumer-until-TIMEOUT): blocking `pr:watch` waits to cap TIMEOUT; `--one-shot` is PENDING; `pr:merge-ready` is a parse fail; this poller STALLs; review-cycle Step 6 stays `unknown`. Keep #4288 as the merged/closed terminal.
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
thin_html = ("<!-- greptile_summary -->" in body and confidence is not None and last_reviewed_sha is None)
|
|
107
|
+
if thin_html and greptile_terminal:
|
|
108
|
+
last_reviewed_sha = head_sha
|
|
109
|
+
# Do NOT set findings_channel_present=True here. Derive it from paginated REST
|
|
110
|
+
# pulls comments and/or check-run comments-added in the CLEAN-gate call site.
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
|
|
97
114
|
A regex that requires the SHA inline after `Last reviewed commit:` will NEVER match Greptile's actual output -- the poller will fall through every iteration and run to its `{poll_cap_minutes}`-minute cap (Agent D, post-#721 swarm; #727 comment 2 Bug 1).
|
|
98
115
|
|
|
99
116
|
### P0/P1 findings detection (TRIPLE-TIER -- #910)
|
|
@@ -378,9 +395,14 @@ def evaluate_clean_gate(
|
|
|
378
395
|
errored,
|
|
379
396
|
terminal_check_run,
|
|
380
397
|
min_confidence=4,
|
|
398
|
+
findings_channel_present=True,
|
|
381
399
|
):
|
|
382
400
|
"""Return (is_clean, clean_gate_holdout) per the (6)-condition AND gate.
|
|
383
401
|
|
|
402
|
+
findings_channel_present defaults True only for markdown Last-reviewed
|
|
403
|
+
bodies. Thin HTML MUST pass a derived value (paginated REST pulls
|
|
404
|
+
comments and/or check-run comments-added). Do not CLEAN on the default.
|
|
405
|
+
|
|
384
406
|
clean_gate_holdout names the FIRST failing condition (in 1/2/3/4/5/6
|
|
385
407
|
order) or None when all six pass. The order is the operative
|
|
386
408
|
contract -- callers MUST NOT reorder the checks or the holdout will
|
|
@@ -416,6 +438,8 @@ def evaluate_clean_gate(
|
|
|
416
438
|
return False, "errored"
|
|
417
439
|
if not terminal_check_run:
|
|
418
440
|
return False, "terminal_check_run"
|
|
441
|
+
if not findings_channel_present:
|
|
442
|
+
return False, "findings_channel"
|
|
419
443
|
return True, None
|
|
420
444
|
```
|
|
421
445
|
|
|
@@ -434,6 +458,57 @@ greptile_terminal = (
|
|
|
434
458
|
```
|
|
435
459
|
|
|
436
460
|
```python
|
|
461
|
+
import json
|
|
462
|
+
import subprocess
|
|
463
|
+
|
|
464
|
+
_COMMENTS_ADDED_RE = re.compile(r"(\d+)\s+comments?\s+added", re.I)
|
|
465
|
+
_summary = None
|
|
466
|
+
if greptile_run is not None:
|
|
467
|
+
_summary = (greptile_run.get("output") or {}).get("summary") or greptile_run.get("summary")
|
|
468
|
+
_m = _COMMENTS_ADDED_RE.search(_summary or "")
|
|
469
|
+
comments_added = int(_m.group(1)) if _m else None
|
|
470
|
+
|
|
471
|
+
findings_channel_present = True
|
|
472
|
+
if thin_html:
|
|
473
|
+
findings_channel_present = False
|
|
474
|
+
rest_fetched = False
|
|
475
|
+
rest_p0 = 0
|
|
476
|
+
rest_p1 = 0
|
|
477
|
+
proc = subprocess.run(
|
|
478
|
+
["gh", "api", "--paginate", f"repos/{repo}/pulls/{pr_number}/comments?per_page=100"],
|
|
479
|
+
capture_output=True,
|
|
480
|
+
text=True,
|
|
481
|
+
)
|
|
482
|
+
items = []
|
|
483
|
+
if proc.returncode == 0:
|
|
484
|
+
raw = proc.stdout or "[]"
|
|
485
|
+
try:
|
|
486
|
+
parsed = json.loads(raw)
|
|
487
|
+
items = parsed if isinstance(parsed, list) else []
|
|
488
|
+
rest_fetched = isinstance(parsed, list)
|
|
489
|
+
except json.JSONDecodeError:
|
|
490
|
+
rest_fetched = False
|
|
491
|
+
for item in items:
|
|
492
|
+
user = (item or {}).get("user") or {}
|
|
493
|
+
if user.get("login") != "greptile-apps[bot]":
|
|
494
|
+
continue
|
|
495
|
+
commit_id = item.get("commit_id") or ""
|
|
496
|
+
if head_sha and commit_id and not (
|
|
497
|
+
str(head_sha).startswith(str(commit_id)) or str(commit_id).startswith(str(head_sha))
|
|
498
|
+
):
|
|
499
|
+
continue
|
|
500
|
+
text = item.get("body") or ""
|
|
501
|
+
if '<img alt="P0"' in text:
|
|
502
|
+
rest_p0 += 1
|
|
503
|
+
if '<img alt="P1"' in text:
|
|
504
|
+
rest_p1 += 1
|
|
505
|
+
findings_channel_present = rest_fetched or comments_added is not None
|
|
506
|
+
if rest_fetched:
|
|
507
|
+
p0_count, p1_count = rest_p0, rest_p1
|
|
508
|
+
has_blocking = rest_p0 + rest_p1 > 0
|
|
509
|
+
elif comments_added is not None:
|
|
510
|
+
has_blocking = has_blocking or comments_added > 0
|
|
511
|
+
|
|
437
512
|
is_clean, clean_gate_holdout = evaluate_clean_gate(
|
|
438
513
|
last_reviewed_sha=last_reviewed_sha,
|
|
439
514
|
head_sha=head_sha,
|
|
@@ -442,6 +517,7 @@ is_clean, clean_gate_holdout = evaluate_clean_gate(
|
|
|
442
517
|
ci_failures=ci_failure_count,
|
|
443
518
|
errored=errored,
|
|
444
519
|
terminal_check_run=greptile_terminal,
|
|
520
|
+
findings_channel_present=findings_channel_present,
|
|
445
521
|
)
|
|
446
522
|
print(
|
|
447
523
|
f"[poll {{i}}/{{cap}}] last_reviewed_sha={{last_reviewed_sha}} "
|
|
@@ -488,7 +564,7 @@ Send to parent:
|
|
|
488
564
|
|
|
489
565
|
### (2) NEW P0/P1 FINDINGS
|
|
490
566
|
|
|
491
|
-
`last_reviewed_sha` matches HEAD AND `has_blocking` is True. Do NOT exit on P2 -- those are non-blocking style suggestions per `skills/deft-directive-review-cycle/SKILL.md`.
|
|
567
|
+
`last_reviewed_sha` matches HEAD AND `has_blocking` is True. Thin HTML (#4289): `has_blocking` from REST pulls comments / comments-added, and NEW_P0/P1 does not require a body SHA when the Greptile Review check-run is terminal on HEAD. Do NOT exit on P2 -- those are non-blocking style suggestions per `skills/deft-directive-review-cycle/SKILL.md`.
|
|
492
568
|
|
|
493
569
|
Address the findings per Phase 2 Step 2-3 of the review-cycle skill: read every finding, plan a single coherent batch, run `task check`, commit with message `fix: address Greptile review findings (batch)`, push. After the push, you MAY reset the **poll-wait timer** for the new HEAD (Greptile needs a fresh review window) — but you MUST NOT reset the dual-stop **fix-batch counter** (#2442).
|
|
494
570
|
|