@deftai/directive-content 0.107.0 → 0.108.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/Taskfile.yml +1 -1
- package/UPGRADING.md +22 -3
- package/commands.md +24 -2
- package/contracts/design-critique.md +117 -16
- package/docs/delivery-attempt.md +2 -1
- package/docs/freshness-contract.md +6 -1
- package/docs/getting-started.md +10 -11
- package/docs/hook-runtime-unavailable.md +54 -0
- package/docs/orphan-active-verdict-basis.md +166 -0
- package/package.json +1 -1
- package/packs/skills/skills-pack-0.1.json +7 -7
- package/scm/github.md +31 -1
- package/skills/deft-directive-build/SKILL.md +1 -1
- package/skills/deft-directive-cost/SKILL.md +7 -11
- package/skills/deft-directive-design-critique/SKILL.md +8 -1
- package/skills/deft-directive-design-critique/references/motion-shape.md +19 -0
- package/skills/deft-directive-interview/SKILL.md +10 -10
- package/skills/deft-directive-release/SKILL.md +10 -6
- package/skills/deft-directive-review-cycle/SKILL.md +33 -0
- package/skills/deft-directive-setup/SKILL.md +53 -22
- package/skills/deft-directive-swarm/references/core-ops.md +4 -0
- package/skills/deft-directive-swarm/references/core-phase-1-2.md +1 -1
- package/skills/deft-directive-swarm/references/core-phase-3.md +3 -1
- package/skills/deft-directive-swarm/references/core-phase-4.md +11 -8
- package/skills/deft-directive-swarm/references/host-cursor.md +1 -0
- package/skills/deft-directive-swarm/references/host-grok-build.md +1 -0
- package/tasks/engine.yml +2 -0
- package/tasks/occupancy.yml +24 -2
- package/tasks/prd.yml +4 -5
- package/tasks/session.yml +3 -3
- package/tasks/toolchain.yml +2 -2
- package/tasks/verify.yml +11 -1
- package/templates/agent-prompt-preamble.md +9 -2
- package/templates/agents-entry.md +6 -1
package/scm/github.md
CHANGED
|
@@ -338,8 +338,38 @@ auth.
|
|
|
338
338
|
`deft github-auth-modes --json` validates API reachability and optional
|
|
339
339
|
repo access.
|
|
340
340
|
|
|
341
|
+
### Ambiguous Cursor runtime and the host-gh opt-in (#3859)
|
|
342
|
+
|
|
343
|
+
`CURSOR_AGENT` is set by local desktop Cursor, by Cursor-managed cloud VMs, and
|
|
344
|
+
by Windows "My Machines" workers, so it cannot decide the runtime by itself.
|
|
345
|
+
|
|
346
|
+
- ! Cursor-managed VMs serve a metadata API on `CURSOR_AGENT_SOCKET` whose
|
|
347
|
+
`agent/runtime` is `managed`. A positive read classifies `cloud-headless` at
|
|
348
|
+
higher precedence than any other Cursor signal **and** than the opt-in below.
|
|
349
|
+
- ⊗ Treat absence of that socket as proof of local desktop. Absence means "not
|
|
350
|
+
managed, or unreachable" and MUST NOT select host credentials -- that is the
|
|
351
|
+
marker-absence grant this rule exists to prevent.
|
|
352
|
+
- ! When `CURSOR_AGENT` is set and the probe does not report `managed`, the
|
|
353
|
+
runtime is **ambiguous**. Deft does not guess from `process.platform`. Host
|
|
354
|
+
credentials then require an explicit selection:
|
|
355
|
+
`DEFT_GITHUB_AUTH_MODE=host-gh`, set in the execution environment on a
|
|
356
|
+
machine you control. Dispatchers should export the same `github_auth_mode`
|
|
357
|
+
label they already record in the dispatch envelope.
|
|
358
|
+
- ! Absent that selection, behaviour is unchanged: the runtime stays
|
|
359
|
+
`cloud-headless` and SCM-dependent gates are skipped. The skip names its
|
|
360
|
+
reason (`runtime_mode_reason` in `scm:status --json`, and in the `[deft scm]`
|
|
361
|
+
session-start lines) and points at this opt-in.
|
|
362
|
+
- ⊗ Use an OS predicate (`process.platform === "win32"`) as a cloud
|
|
363
|
+
discriminator. Cursor's managed fleet being Ubuntu is a versioned fact about
|
|
364
|
+
a third party's infrastructure, not a runtime invariant.
|
|
365
|
+
|
|
366
|
+
Reason ids: `cursor-managed-runtime-probe`, `cursor-marker-runtime-ambiguous`,
|
|
367
|
+
`explicit-host-gh-selection`, `ci-marker`, `cursor-sandbox-marker`,
|
|
368
|
+
`no-runtime-marker`.
|
|
369
|
+
|
|
341
370
|
Contract file: `content/contracts/scm-readiness.md`. Implementation:
|
|
342
|
-
`packages/core/src/scm/readiness.ts
|
|
371
|
+
`packages/core/src/scm/readiness.ts`,
|
|
372
|
+
`packages/core/src/platform/cursor-managed-runtime.ts`.
|
|
343
373
|
|
|
344
374
|
## Windows / ASCII Conventions for Machine-Editable Sections
|
|
345
375
|
|
|
@@ -107,7 +107,7 @@ The gate exits 0 only when the candidate xBRIEF lives in `xbrief/active/` AND `p
|
|
|
107
107
|
|
|
108
108
|
A project is **pre-cutover** if ANY of the following are true. This prose mirrors the executable helper in `scripts/_precutover.py`; when in doubt, the helper is canonical.
|
|
109
109
|
|
|
110
|
-
1. `SPECIFICATION.md` exists and is neither a deprecation redirect nor a current generated spec export. A current generated spec export contains `<!-- Purpose: rendered specification
|
|
110
|
+
1. `SPECIFICATION.md` exists and is neither a deprecation redirect nor a current generated spec export. A current generated spec export contains `<!-- Purpose: rendered specification -->`, all five lifecycle folders exist, and its `<!-- Source of truth: ... -->` marker names an authority artifact that exists: either `xbrief/specification.xbrief.json` for full-spec compatibility or `xbrief/PROJECT-DEFINITION.xbrief.json` for greenfield authority (legacy `vbrief/...` aliases remain read-compatible).
|
|
111
111
|
2. `PROJECT.md` exists and contains neither the legacy `<!-- deft:deprecated-redirect -->` sentinel NOR the current `Purpose: deprecation redirect` canonical-banner marker (real content, not a deprecation redirect)
|
|
112
112
|
3. `xbrief/specification.xbrief.json` exists but the lifecycle folders (`xbrief/proposed/`, `xbrief/pending/`, `xbrief/active/`, `xbrief/completed/`, `xbrief/cancelled/`) do NOT exist
|
|
113
113
|
4. Strategy output shape violations (run `task verify-strategy-output` -- the canonical gate -- or the direct form `python .deft/core/scripts/validate_strategy_output.py --project-root <path>` after `deft` install):
|
|
@@ -24,8 +24,7 @@ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
|
24
24
|
|
|
25
25
|
## When to Use
|
|
26
26
|
|
|
27
|
-
- After `skills/deft-directive-setup/SKILL.md` Phase 3 has produced an
|
|
28
|
-
approved `xbrief/specification.xbrief.json` (status `approved`)
|
|
27
|
+
- After `skills/deft-directive-setup/SKILL.md` Phase 3 has produced either greenfield authority (`xbrief/PROJECT-DEFINITION.xbrief.json` plus lifecycle scopes) or an approved full-spec compatibility artifact
|
|
29
28
|
- Before `skills/deft-directive-build/SKILL.md` kicks off
|
|
30
29
|
- When the user says "cost", "budget", "pre-build cost", "how much will
|
|
31
30
|
this cost", or asks to estimate cost before building
|
|
@@ -60,12 +59,9 @@ two skills agree on the user's preferences file.
|
|
|
60
59
|
|
|
61
60
|
## Inputs
|
|
62
61
|
|
|
63
|
-
- ! `xbrief/
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
gate.
|
|
67
|
-
- ~ `xbrief/PROJECT-DEFINITION.xbrief.json` (for tech-stack and
|
|
68
|
-
architecture narratives). Optional but improves the estimate.
|
|
62
|
+
- ! Resolve the same two-path authority used by `task project:export-spec`: prefer an existing full-spec artifact, otherwise use `xbrief/PROJECT-DEFINITION.xbrief.json` plus lifecycle scopes.
|
|
63
|
+
- ! For full-spec authority, require its existing approval contract. For greenfield authority, require the setup approval decision and at least one lifecycle scope; do not require `plan.status = "approved"` on PROJECT-DEFINITION.
|
|
64
|
+
- ⊗ Require or create `xbrief/specification.xbrief.json` solely to estimate a greenfield project.
|
|
69
65
|
- ~ `templates/COST-ESTIMATE.md` (canonical artifact body).
|
|
70
66
|
- ~ `references/cost-models.md` (methodology).
|
|
71
67
|
|
|
@@ -73,8 +69,8 @@ two skills agree on the user's preferences file.
|
|
|
73
69
|
|
|
74
70
|
### Phase 1 -- Read the spec & detect categories
|
|
75
71
|
|
|
76
|
-
- ! Read the
|
|
77
|
-
- ! Walk the
|
|
72
|
+
- ! Read the resolved authority: the full-spec artifact when present, otherwise PROJECT-DEFINITION plus relevant lifecycle scopes.
|
|
73
|
+
- ! Walk the resolved narratives and scope requirements to identify which cost categories apply for this
|
|
78
74
|
project: hosting / infrastructure, API / third-party fees, pre-flight
|
|
79
75
|
account sign-ups, build & maintenance time. Drop categories that do
|
|
80
76
|
not apply.
|
|
@@ -139,7 +135,7 @@ This is your project's cost estimate. Pick one.
|
|
|
139
135
|
`skills/deft-directive-refinement/SKILL.md` to pull spec scope back,
|
|
140
136
|
or the interview), then re-run this skill from Phase 1.
|
|
141
137
|
- ! On `No-build`, write the decision to `COST-ESTIMATE.md`, mark the
|
|
142
|
-
|
|
138
|
+
applicable lifecycle scope xBRIEFs accordingly, exit, and do NOT chain into the build
|
|
143
139
|
skill.
|
|
144
140
|
- ! On `Skip`, write the decision and skip reason to `COST-ESTIMATE.md`
|
|
145
141
|
and proceed to the build kickoff.
|
|
@@ -44,12 +44,19 @@ After critic post: posted successor lean, then verbs.
|
|
|
44
44
|
Auto-stamp after operator confirm; not while same-round siblings outstanding.
|
|
45
45
|
Walk / walk all. Auto-stamp when agents agree: Operator verbs.
|
|
46
46
|
Parent chip write: scm:issue:design-critique-chip.
|
|
47
|
+
Chip apply miss is non-blocking convenience; do not halt. Ingest waits on the completed-arc record, not a catalog chip.
|
|
47
48
|
|
|
48
49
|
Each critic dispatch EXITs after posting.
|
|
49
50
|
|
|
51
|
+
## Motion shape
|
|
52
|
+
|
|
53
|
+
Not sequential review. Same-round critics are isolated: each reads one fixed input ceiling and cannot read other siblings' posts through the thread. More: [`references/motion-shape.md`](references/motion-shape.md).
|
|
54
|
+
|
|
55
|
+
After each critic EXIT, the parent posts the successor lean; the operator confirms or amends before bind or stamp.
|
|
56
|
+
|
|
50
57
|
⊗ Auto-dispatch critics from this skill.
|
|
51
58
|
⊗ Copy the variant table, synthesis rules, or other contract bodies into this skill.
|
|
52
59
|
|
|
53
60
|
## EXIT
|
|
54
61
|
|
|
55
|
-
deft-directive-design-critique complete -- exiting skill. Next:
|
|
62
|
+
deft-directive-design-critique complete -- exiting skill. Next: operator fills the brief template and dispatches the next envelope.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Design critique — motion shape
|
|
2
|
+
|
|
3
|
+
Orientation only. Normative rules: [`contracts/design-critique.md`](../../../contracts/design-critique.md).
|
|
4
|
+
|
|
5
|
+
## Same-round critics
|
|
6
|
+
|
|
7
|
+
- Parallel, not sequential. Each critic in a round reads one fixed input ceiling set before any sibling dispatch.
|
|
8
|
+
- A sibling's post is out of envelope for every other sibling in that round — they cannot read each other through the issue thread.
|
|
9
|
+
- Serial dispatch (critic B after critic A posts) destroys isolation even when bind guards still pass.
|
|
10
|
+
|
|
11
|
+
## Who adjudicates
|
|
12
|
+
|
|
13
|
+
| Step | Actor | Action |
|
|
14
|
+
|------|-------|--------|
|
|
15
|
+
| After critic EXIT | Parent | Post successor lean with proposed per-heading takes |
|
|
16
|
+
| Before bind/stamp | Operator | Confirm or amend that lean |
|
|
17
|
+
| Next envelope | Operator (or parent after operator verb) | Fill brief template and dispatch |
|
|
18
|
+
|
|
19
|
+
Comment-lead chips (model then role) govern comment signing — see brief template and Stop 3.
|
|
@@ -196,7 +196,7 @@ The answers map format:
|
|
|
196
196
|
|
|
197
197
|
## Output Targets
|
|
198
198
|
|
|
199
|
-
Interview output writes to `
|
|
199
|
+
Interview output writes to the authority selected by the calling skill. Greenfield setup writes project-level narratives to `xbrief/PROJECT-DEFINITION.xbrief.json` and implementation requirements to lifecycle scope xBRIEFs in `xbrief/proposed/`; it does not create `xbrief/specification.xbrief.json`. A caller that explicitly owns a full-spec workflow may target the compatibility specification artifact. PRD.md is never authoritative. New xBRIEFs target the current v0.8 schema; see [`../../conventions/references.md`](../../conventions/references.md).
|
|
200
200
|
|
|
201
201
|
When the interview captures origin provenance (e.g. the user links to a GitHub issue or Jira ticket), include a `references` entry in the canonical form documented in [`../../conventions/references.md`](../../conventions/references.md):
|
|
202
202
|
|
|
@@ -212,7 +212,7 @@ When the interview captures origin provenance (e.g. the user links to a GitHub i
|
|
|
212
212
|
|
|
213
213
|
### Full Path Output
|
|
214
214
|
|
|
215
|
-
! On the Full path, the
|
|
215
|
+
! On the greenfield Full path, the calling setup skill merges these rich keys into `PROJECT-DEFINITION.xbrief.json` and creates traceable proposed scope xBRIEFs:
|
|
216
216
|
|
|
217
217
|
- `ProblemStatement`: What problem this project solves
|
|
218
218
|
- `Goals`: High-level project goals
|
|
@@ -224,23 +224,23 @@ When the interview captures origin provenance (e.g. the user links to a GitHub i
|
|
|
224
224
|
|
|
225
225
|
! All narrative values MUST be plain strings — never objects or arrays.
|
|
226
226
|
|
|
227
|
-
! The human approval gate reviews the
|
|
227
|
+
! The human approval gate reviews the PROJECT-DEFINITION narratives and proposed scope plan directly. On approval, the calling setup skill records the decision and generates downstream scope xBRIEFs without manufacturing a specification artifact.
|
|
228
228
|
|
|
229
229
|
### Light Path Output
|
|
230
230
|
|
|
231
|
-
! On the Light path, the
|
|
231
|
+
! On the greenfield Light path, the calling setup skill merges these slim narratives into `PROJECT-DEFINITION.xbrief.json`:
|
|
232
232
|
|
|
233
233
|
- `Overview`: Brief project summary
|
|
234
234
|
- `Architecture`: System design description
|
|
235
235
|
|
|
236
|
-
! On approval,
|
|
236
|
+
! On approval, the calling setup skill creates scope xBRIEFs in `xbrief/proposed/` for each identified work item; it does not create `specification.xbrief.json`.
|
|
237
237
|
|
|
238
238
|
### PRD.md (deprecated — never authoritative)
|
|
239
239
|
|
|
240
|
-
PRD.md is not generated as part of the interview workflow on either path.
|
|
240
|
+
PRD.md is not generated as part of the interview workflow on either path. It is a read-only export from the resolved authority.
|
|
241
241
|
|
|
242
|
-
- ? If stakeholders require a traditional PRD document, run `task prd:render` to export a read-only `PRD.md` from
|
|
243
|
-
- ! PRD.md is never authoritative —
|
|
242
|
+
- ? If stakeholders require a traditional PRD document, run `task prd:render` to export a read-only `PRD.md` from the resolved project narratives
|
|
243
|
+
- ! PRD.md is never authoritative — greenfield authority is PROJECT-DEFINITION plus lifecycle scopes; full-spec compatibility authority remains supported when present
|
|
244
244
|
- ⊗ Generate an authoritative PRD.md during the interview process
|
|
245
245
|
- ⊗ Treat PRD.md as a source of truth — it is a generated export artifact
|
|
246
246
|
|
|
@@ -375,7 +375,7 @@ Tatooine), branded characters (Mickey Mouse, Spider-Man), sports leagues
|
|
|
375
375
|
2. ! Emit the plain-English risk summary from
|
|
376
376
|
`scripts/ip_risk.py:plain_risk_summary(hits, intent)` into the
|
|
377
377
|
interview output AND into an `IPRisk` narrative on the
|
|
378
|
-
|
|
378
|
+
authoritative interview output selected by the calling skill. The summary opens with `not legal
|
|
379
379
|
advice`, names the detected categories, and (for commercial intent)
|
|
380
380
|
states explicitly that lawyer consultation is **not optional output**
|
|
381
381
|
from this interview.
|
|
@@ -513,7 +513,7 @@ for it.
|
|
|
513
513
|
- ⊗ Skip the depth gate and generate artifacts with known ambiguity remaining
|
|
514
514
|
- ⊗ Exit the interview without producing a structured answers map for the calling skill
|
|
515
515
|
- ⊗ Combine interview questions with artifact generation in the same message
|
|
516
|
-
- ⊗ Generate an authoritative PRD.md — interview output targets
|
|
516
|
+
- ⊗ Generate an authoritative PRD.md — interview output targets the calling skill's resolved xBRIEF authority
|
|
517
517
|
- ⊗ Treat PRD.md as a source of truth — it is a read-only export via `task prd:render`
|
|
518
518
|
- ⊗ Auto-advance to the next question on number press without echoing the selection and waiting for confirmation
|
|
519
519
|
- ⊗ Refuse backward navigation during the interview -- the user must be able to revisit previous answers
|
|
@@ -321,12 +321,13 @@ Race-condition mitigation: `download_count` is double-read with a 5s sleep betwe
|
|
|
321
321
|
|
|
322
322
|
! Only enter Phase 7 if Phase 6 took the Publish branch (rollback branch ends here with the unwind log).
|
|
323
323
|
|
|
324
|
-
1. ! **Re-verify npm publish landed (#1910, #1909, #2002).** Phase 5 checked workflow status before the GitHub publish flip; Phase 7 confirms registry truth AFTER `task release:publish`. For each of `@deftai/directive-types`, `@deftai/directive-core`, `@deftai/directive-content`, and `@deftai/directive`, run `npm view <pkg>@<version> version` (expect `<version>`) and confirm provenance on the npm page. A green GitHub release with missing npm packages means consumers cannot `npm i -g @deftai/directive@<version>` -- escalate immediately. (Real-registry verification depends on #1909's credential; until then verify workflow-run status and flag credential gaps.)
|
|
325
|
-
2. !
|
|
326
|
-
3. !
|
|
327
|
-
4. !
|
|
328
|
-
5. ! Verify
|
|
329
|
-
6. !
|
|
324
|
+
1. ! **Re-verify npm publish landed (#1910, #1909, #2002).** Phase 5 checked workflow status before the GitHub publish flip; Phase 7 confirms registry truth AFTER `task release:publish`. For each of `@deftai/directive-types`, `@deftai/directive-core`, `@deftai/directive-content`, and `@deftai/directive`, run `npm view <pkg>@<version> version --prefer-online` (expect `<version>`) and confirm provenance on the npm page. A green GitHub release with missing npm packages means consumers cannot `npm i -g @deftai/directive@<version>` -- escalate immediately. (Real-registry verification depends on #1909's credential; until then verify workflow-run status and flag credential gaps.) Reading one package is not sufficient — sibling publish is not atomic.
|
|
325
|
+
2. ! **Report local-vs-released CLI drift (#3753).** After the all-four registry check, print the local global CLI version, the released version, whether they match, and the exact remediation `npm i -g @deftai/directive@<version> --prefer-online`. Compare versions with `checkActiveCliAgainstTarget` (not bare `deft --version`) so a PATH-shadowed install cannot report success (#3233). If some siblings are visible and others are not, report **still propagating**. If none are visible after this wait, report **publish incomplete**. `task release` already emitted a non-blocking snapshot of the same report at pipeline completion (single probe, no wait — Step 13 returns before `npm-publish.yml` is green). Phase 7 is the bounded wait. ⊗ Run `npm i -g`. The report must not fail the release.
|
|
326
|
+
3. ! Verify GitHub auto-closed the discrete-task issue(s) referenced via `Closes #N` in the release notes (mirrors `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 2)
|
|
327
|
+
4. ! Run `gh issue view <N> --json state --jq .state` for each closed issue. If any didn't auto-close, manually close with `gh issue close <N> --comment "Closed by release v<version> (squash auto-close did not trigger)"` (Layer 1, #167)
|
|
328
|
+
5. ! Verify ROADMAP.md correctness via `task roadmap:render` (the release pipeline already invoked this; Phase 7 is the second-pass sanity check)
|
|
329
|
+
6. ! Verify binaries are downloadable from the public release URL: `gh release view v<version> --json assets --jq '.assets[].url'` and curl one to confirm 200 OK
|
|
330
|
+
7. ! For any umbrella / staying-OPEN issue (`Refs #N`) referenced in the release notes, run the Layer 3 reopen sweep from `skills/deft-directive-swarm/SKILL.md` Phase 6 Step 1: any protected issue that auto-closed MUST be reopened with a comment citing #701
|
|
330
331
|
|
|
331
332
|
⊗ Skip the post-publish verification. The closing-keyword false-positive (Layer 1 / Layer 2 / Layer 3) and the incremental-renderer-drift (#641, #614) are exactly the kind of issues that surface only AFTER a release is public.
|
|
332
333
|
|
|
@@ -384,6 +385,9 @@ Where `<one-line guidance>` is one of:
|
|
|
384
385
|
- ⊗ Run `task release:rollback` against a release that has > 30 minutes of consumer-driven downloads without first weighing the hot-fix path -- a withdrawal note in the next patch is almost always less disruptive than deleting a public artifact
|
|
385
386
|
- ⊗ Use `--allow-data-loss` without first reading the script docstring's hot-fix-path recommendation -- the flag is an explicit acknowledgment of consumer impact, not a default
|
|
386
387
|
- ⊗ Skip the Phase 7 Layer 3 reopen sweep -- protected umbrellas can auto-close on a release-merge squash even when the release notes use `Refs #N` only
|
|
388
|
+
- ⊗ Run `npm i -g` from the release pipeline or Phase 7 (#3753) -- report local-vs-released drift only; no global mutation
|
|
389
|
+
- ⊗ Trust bare `deft --version` after a cut -- use `checkActiveCliAgainstTarget` so a PATH-shadowed install cannot report success (#3233 / #3753)
|
|
390
|
+
- ⊗ Treat a missing sibling package as a failed publish without distinguishing still-propagating from publish-incomplete (#3753)
|
|
387
391
|
- ⊗ Post the Phase 8 Slack announcement directly from this skill -- the user owns the broadcast; the skill only generates the template
|
|
388
392
|
- ⊗ Hardcode `master` as the base branch -- delegate to the configured base branch from `task release --base-branch <branch>`
|
|
389
393
|
- ⊗ Skip the post-create verify-isDraft gate (#724) -- a successful `gh release create` exit code does NOT prove the release actually landed in draft state; the 5-second poll-and-flip gate in `scripts/release.py` Step 11 is the only safety net against operator-error variants and partial-success races, and any manual recovery path that bypasses `scripts/release.py` MUST run `gh release view --json isDraft` followed by `gh release edit --draft=true` on `isDraft=false` before handing off to Phase 5
|
|
@@ -624,6 +624,39 @@ Cross-links: swarm decision tree `skills/deft-directive-swarm/references/core-ph
|
|
|
624
624
|
6. ! On register conflict when the prior owner is **still alive**: attach to the existing owner or stop — do not parallel-fix.
|
|
625
625
|
7. ⊗ Refuse replacement of a dead owner solely because the 30-minute lease has not expired without attempting force takeover (#3044).
|
|
626
626
|
|
|
627
|
+
### Advisory pass-open mark on issue threads (#3607)
|
|
628
|
+
|
|
629
|
+
! **Advisory, not a lock.** On an **issue** thread the same `<!-- deft:review-owner -->` marker carries `kind: pass` to say a structured pass (triage, design-critique, review-response) is open: pass kind, owner, declared ceiling, and `expires_at`. An arriving agent **reads and is informed**; nothing is held and no write is blocked. A pass has N+1 writers by construction (parent plus panel), so an exclusive hold names no actual actor — blocking was refuted 3/3 by the #3607 panel.
|
|
630
|
+
|
|
631
|
+
! **Read before writing into an open pass.** Fetch the mark (`fetchActivePassMarker`, or `gh api repos/<owner>/<repo>/issues/<N>/comments` filtered on the marker). When a mark is open, prefer flagging your comment as post-ceiling, or hold voluntarily — your call, not a gate.
|
|
632
|
+
|
|
633
|
+
! **The lifecycle runs on the issue thread itself — there is no separate verb.** Open the mark by posting a comment whose body is the marker block; clear it at synthesis by editing that same comment to carry `ended_at`. Engine callers use `openPassMarker` / `closePassMarker` / `fetchActivePassMarker` (`packages/core/src/review-monitor/github-lease.ts`); an agent without those bindings posts the identical block through the safe-body verbs, exactly as the #2878 gh-only lease fallback does.
|
|
634
|
+
|
|
635
|
+
```text
|
|
636
|
+
<!-- deft:review-owner -->
|
|
637
|
+
kind: pass
|
|
638
|
+
pass_kind: design-critique
|
|
639
|
+
owner: <github-login>
|
|
640
|
+
agent_id: <pass owner agent id>
|
|
641
|
+
ceiling: <declared ceiling comment id>
|
|
642
|
+
started_at: 2026-08-28T19:48:24Z
|
|
643
|
+
expires_at: 2026-08-28T20:48:24Z
|
|
644
|
+
<!-- /deft:review-owner -->
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
1. ! **Open** at pass start with a **new** comment, and keep the comment id it returns: `task scm:body:comment:create -- --repo <owner>/<repo> --issue <N> --body-file <file>`.
|
|
648
|
+
2. ! **Read** on arrival: `gh api repos/<owner>/<repo>/issues/<N>/comments`, then take the **oldest unexpired** `kind: pass` block. A mark already open means you were informed, not stopped.
|
|
649
|
+
3. ! **Refresh or clear** only the comment id your own open returned: `task scm:body:comment:edit -- --repo <owner>/<repo> --comment <id> --body-file <file>`, adding `ended_at: <now>` at synthesis.
|
|
650
|
+
|
|
651
|
+
⊗ Edit a marker comment you did not open, including one carrying your own login from another pass — a comment belongs to the pass that created it. Editing another author's comment is also a 403 for a non-maintainer. Open your own and let oldest-comment-id-wins settle which mark arrivals honour.
|
|
652
|
+
|
|
653
|
+
! **Expiry is the release.** A mark self-clears on read once `expires_at` passes, and the owner clears it at synthesis (`ended_at`), so an abandoned pass never marks a thread forever and no heartbeat is needed. Concurrent marks resolve **oldest comment id wins**, matching the lease; the later mark is removed and its author is told which mark stands.
|
|
654
|
+
|
|
655
|
+
! **Trust boundary.** Pass marks are read from **any** author association, including `CONTRIBUTOR`, because they inform rather than gate. Ownership leases stay maintainer-authored (`OWNER` / `MEMBER` / `COLLABORATOR`, #2307) because `verify:review-monitor` / `verify:l4-owner` exit 0 on a live lease.
|
|
656
|
+
|
|
657
|
+
⊗ Treat a pass mark as permission to hold, block, or gate another actor's write.
|
|
658
|
+
⊗ Read a `kind: pass` mark as a review-owner lease — a pass mark never satisfies `verify:review-monitor` / `verify:l4-owner`.
|
|
659
|
+
|
|
627
660
|
### Required non-empty monitor handback (#3044)
|
|
628
661
|
|
|
629
662
|
! Approach 1 review-monitor prompts (including `templates/swarm-greptile-poller-prompt.md` and any host-filled spawn prompt) MUST require a **non-empty** final handback with these fields:
|
|
@@ -127,6 +127,8 @@ When guiding an operator through migration on the pinned release, mention the mi
|
|
|
127
127
|
- ! If `$DEFT_USER_PATH` is set, it takes precedence on any platform
|
|
128
128
|
- ! Create parent directories as needed when writing USER.md
|
|
129
129
|
- ~ `$DEFT_PROJECT_PATH` overrides the default project config path (`./xbrief/PROJECT-DEFINITION.xbrief.json`) if set
|
|
130
|
+
- ! Resolve `<policy-project-root>` to the user's working directory at skill entry. When `$DEFT_PROJECT_PATH` is set, resolve it relative to that root and preserve the environment variable for every Phase 2 command; the public policy writer, inspector, lock, and conformance gate honor the configured file even when it is outside the canonical `xbrief/` path.
|
|
131
|
+
- ! Pass `--project-root <policy-project-root>` to every Phase 2 policy inspector, writer, and conformance command. Do not unset or rewrite `$DEFT_PROJECT_PATH`, and do not let those commands fall back to a different working directory.
|
|
130
132
|
|
|
131
133
|
## Agent Behavior
|
|
132
134
|
|
|
@@ -418,6 +420,15 @@ for project-scoped settings (strategy, coverage).
|
|
|
418
420
|
- ~ Skip if `./xbrief/PROJECT-DEFINITION.xbrief.json` exists (or `$DEFT_PROJECT_PATH` if set) and user doesn't want to replace
|
|
419
421
|
- ⊗ Count `./deft/PROJECT-DEFINITION.xbrief.json` or `./deft/core/project.md` as the user's project config — those are framework-internal
|
|
420
422
|
|
|
423
|
+
### Re-entry shadow guard (#3609)
|
|
424
|
+
|
|
425
|
+
! Before any Phase 2 confirmation or file mutation when PROJECT-DEFINITION already exists, run `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` and inspect **stderr as well as the exit code**. The inspector intentionally exits 0 when it can still read the namespaced value, so a warning that bare `plan.policy` coexists with `plan["x-directive/policy"]` is a hard stop even when the command succeeds.
|
|
426
|
+
|
|
427
|
+
! On that warning, do not regenerate, overwrite, or run a policy writer. Inventory the keys in both blocks; fold every bare-only key into `plan["x-directive/policy"]`; resolve every collision explicitly; delete bare `plan.policy`; then rerun the inspector. Preserve all unrelated PROJECT-DEFINITION content. Resume only when exactly one policy block remains.
|
|
428
|
+
|
|
429
|
+
⊗ Treat matching `allowDirectCommitsToMaster` values as safe while other keys may still be stranded in the shadowed block
|
|
430
|
+
⊗ Copy arbitrary policy values into a diagnostic or silently choose one side of a collision
|
|
431
|
+
|
|
421
432
|
### Inference
|
|
422
433
|
|
|
423
434
|
- ! Before asking, infer from codebase — look for `package.json`, `go.mod`, `requirements.txt`, `Cargo.toml`, `pyproject.toml`, `*.csproj`
|
|
@@ -491,21 +502,21 @@ apply here too. Do not combine questions. See `skills/deft-directive-interview/S
|
|
|
491
502
|
! **Capability-cost disclosure (#746):** When the user picks option 2 (trunk-based), the agent MUST present the capability-cost disclosure verbatim BEFORE writing the typed flag, then re-prompt for explicit confirmation:
|
|
492
503
|
|
|
493
504
|
> "Capability-cost disclosure -- enabling direct commits to the default branch turns OFF the deft branch-protection policy. The pre-commit + pre-push hooks will no longer block default-branch commits, `task verify:branch` will pass on the default branch, and the skill-level guards in deft-directive-{swarm,review-cycle,pre-pr,release} will not halt for default-branch work. The change is reversible (`task policy:enforce-branches`) and is recorded to meta/policy-changes.log for auditability. The CI sanity check (head_ref != base_ref) remains independent and will continue to flag master->master PRs. Are you sure?"
|
|
494
|
-
> 1. Yes, opt out --
|
|
495
|
-
> 2. No, keep branch-protection enforced --
|
|
505
|
+
> 1. Yes, opt out -- persist `allowDirectCommitsToMaster=true` through the policy writer
|
|
506
|
+
> 2. No, keep branch-protection enforced -- persist `allowDirectCommitsToMaster=false` through the policy writer
|
|
496
507
|
> 3. Discuss
|
|
497
508
|
> 4. Back
|
|
498
509
|
|
|
499
510
|
! Default to option 2 (enforce). Explicit affirmative on option 1 is required to opt out -- a broad `proceed` does NOT satisfy this gate. The same affirmative-only rule applies as in `/deft:change` (`yes`, `confirmed`, `approve`).
|
|
500
511
|
|
|
501
|
-
!
|
|
512
|
+
! Record the answer as the logical field `plan.policy.allowDirectCommitsToMaster`, but do not hand-write either policy block. The common Output Path gate below invokes the only writer and stores the boolean under `plan["x-directive/policy"].allowDirectCommitsToMaster`. Default `false` (enforce branches) when the user picks option 2 OR omits the question entirely. Agents MUST NOT write bare `plan.policy` or the legacy free-form `Allow direct commits to master:` narrative key.
|
|
502
513
|
|
|
503
|
-
! **Re-running the interview detects the existing flag (#746 part G2):**
|
|
514
|
+
! **Re-running the interview detects the existing flag (#746 part G2):** After the Re-entry shadow guard passes, surface the resolved current value (e.g. "Current setting: `allowDirectCommitsToMaster=false` (branch-protection ON)") and ask whether to keep it or change it before re-prompting. A keep choice still runs the selected writer so legacy-only storage is migrated; an already-namespaced match is a no-op with no audit append. On Track 2 or 3, preserve an existing resolved boolean by default without asking a new branching question. Never replace an existing `true` with the greenfield `false` default unless the operator explicitly chooses the Track 1 change flow.
|
|
504
515
|
|
|
505
|
-
! **
|
|
506
|
-
-
|
|
507
|
-
-
|
|
508
|
-
-
|
|
516
|
+
! **Consumer command alternatives (#746 part G2):** Once the project is set up, use the public CLI directly:
|
|
517
|
+
- `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` -- display the current resolved policy and source
|
|
518
|
+
- `deft policy:enforce-branches --actor agent:deft-directive-setup --project-root <policy-project-root>` -- set `allowDirectCommitsToMaster=false`
|
|
519
|
+
- `deft policy:allow-direct-commits --confirm --actor agent:deft-directive-setup --project-root <policy-project-root>` -- set `allowDirectCommitsToMaster=true`
|
|
509
520
|
|
|
510
521
|
Each transition is recorded to `meta/policy-changes.log` for auditability.
|
|
511
522
|
|
|
@@ -515,14 +526,30 @@ apply here too. Do not combine questions. See `skills/deft-directive-interview/S
|
|
|
515
526
|
- Step 3: Ask languages (show detected, confirm or adjust; if none detected, infer from type and ask)
|
|
516
527
|
- Step 4: Ask strategy (default to USER.md Defaults; ask if this project needs different — show Available Strategies numbered list with descriptions and recommended marker)
|
|
517
528
|
- Default coverage to USER.md Defaults without asking
|
|
529
|
+
- ! Do not ask a branching question. For greenfield or absent policy, the common Output Path gate persists `allowDirectCommitsToMaster=false`. On re-entry it preserves the resolved existing boolean, including `true`; change it only through the Track 1 disclosure gate.
|
|
518
530
|
|
|
519
531
|
**Track 3 (non-technical) — 1 step:**
|
|
520
532
|
- Step 1: Present summary of inferences: "Based on your project: {name} ({type}), built with {stack}. Look right?"
|
|
521
533
|
- ⊗ Ask about strategy or coverage — use Phase 1 defaults
|
|
534
|
+
- ! Do not ask a branching question. For greenfield or absent policy, the common Output Path gate persists `allowDirectCommitsToMaster=false`. On re-entry it preserves the resolved existing boolean, including `true`; change it only through the Track 1 disclosure gate.
|
|
522
535
|
|
|
523
536
|
### Output Path
|
|
524
537
|
|
|
525
|
-
`./xbrief/PROJECT-DEFINITION.xbrief.json` (or `$DEFT_PROJECT_PATH` if set). Create
|
|
538
|
+
`./xbrief/PROJECT-DEFINITION.xbrief.json` (or the resolved `$DEFT_PROJECT_PATH` if set). Create `<policy-project-root>/xbrief/` and its lifecycle subfolders (`proposed/`, `pending/`, `active/`, `completed/`, `cancelled/`) if they don't exist. A configured PROJECT-DEFINITION may live elsewhere; the lifecycle root remains under `<policy-project-root>`.
|
|
539
|
+
|
|
540
|
+
### Branch-policy persistence gate (#3609)
|
|
541
|
+
|
|
542
|
+
! This gate applies to **every track**, including default/greenfield and keep/re-entry paths. For greenfield setup, first write the confirmed PROJECT-DEFINITION base without any hand-authored policy block. On re-entry, merge base changes while preserving the existing policy block byte-for-byte: keep a legacy-only bare `plan.policy` intact until the shared writer migrates the whole block, and keep a namespaced block intact until that writer updates it. Never delete or reconstruct a legacy-only block before the writer because it may contain unrelated keys such as `wipCap`. Then invoke exactly one public writer:
|
|
543
|
+
|
|
544
|
+
- Branch-based/greenfield-default/keep-false: `deft policy:enforce-branches --actor agent:deft-directive-setup --project-root <policy-project-root>`
|
|
545
|
+
- Explicitly confirmed trunk-based/keep-true/Track 2 or 3 existing-true: `deft policy:allow-direct-commits --confirm --actor agent:deft-directive-setup --project-root <policy-project-root>`
|
|
546
|
+
|
|
547
|
+
! A nonzero writer exit halts Phase 2 immediately. Do not print a completion claim and do not retry by hand-editing JSON. Resolve the reported configuration problem, rerun the Re-entry shadow guard, and invoke the writer again.
|
|
548
|
+
|
|
549
|
+
! Before Phase 2 can complete, re-read PROJECT-DEFINITION and verify all three postconditions: `plan["x-directive/policy"].allowDirectCommitsToMaster` is the selected boolean; bare `plan.policy` is absent; and `deft verify:vbrief-conformance --project-root <policy-project-root>` exits 0. Also run `deft policy:show --field=plan.policy.allowDirectCommitsToMaster --project-root <policy-project-root>` and confirm its resolved value matches the selection. Any mismatch is a hard stop.
|
|
550
|
+
|
|
551
|
+
⊗ Finish Phase 2 after writing only the narrative template
|
|
552
|
+
⊗ Add a setup-specific policy writer or weaken conformance to permit bare `plan.policy`
|
|
526
553
|
|
|
527
554
|
### GitHub PR Template Scaffolding (#531)
|
|
528
555
|
|
|
@@ -579,7 +606,7 @@ omit = [
|
|
|
579
606
|
"Strategy": "Use {strategy name} for this project",
|
|
580
607
|
"Quality": "Run task check before every commit. Achieve >= {coverage}% coverage overall + per-module. Store secrets in secrets/ dir.",
|
|
581
608
|
"ProjectRules": "{Any rules the user specified, or 'No project-specific rules defined.'}",
|
|
582
|
-
"Branching": "{If trunk-based: '
|
|
609
|
+
"Branching": "{If confirmed trunk-based: 'Trunk-based workflow', otherwise 'Branch-based workflow (default)'}",
|
|
583
610
|
"DeftVersion": "0.20.0"
|
|
584
611
|
},
|
|
585
612
|
"items": []
|
|
@@ -614,7 +641,7 @@ omit = [
|
|
|
614
641
|
! **Path Resolution Anchor**: Same rule as Phase 2 -- resolve ALL paths relative to the user's pwd at skill entry, never relative to the skill file, AGENTS.md, or any framework directory.
|
|
615
642
|
|
|
616
643
|
- ~ Skip if user already has scope xBRIEFs in `./xbrief/` they're happy with
|
|
617
|
-
- ! Check `./xbrief/
|
|
644
|
+
- ! Check `./xbrief/PROJECT-DEFINITION.xbrief.json` and `./xbrief/proposed/` for existing greenfield authority; treat `./xbrief/specification.xbrief.json` as a full-spec compatibility artifact only
|
|
618
645
|
- ⊗ Count ANY file inside `./deft/` as the project's spec — those are framework-internal
|
|
619
646
|
(e.g. `deft/PROJECT.md`, `deft/specs/`, `deft/templates/`, `deft/core/project.md`
|
|
620
647
|
are all part of the framework, NOT the user's project)
|
|
@@ -682,8 +709,10 @@ project complexity per [strategies/interview.md](../../strategies/interview.md#s
|
|
|
682
709
|
- ⊗ Combine the sizing proposal with the first interview question
|
|
683
710
|
- ⊗ Proceed to interview questions before the user has confirmed the path
|
|
684
711
|
|
|
685
|
-
**Light** (small/medium): Interview →
|
|
686
|
-
**Full** (large/complex): Interview → rich narratives
|
|
712
|
+
**Light** (small/medium): Interview → slim narratives (Overview + Architecture) in `PROJECT-DEFINITION.xbrief.json` → scope xBRIEFs in `xbrief/proposed/`.
|
|
713
|
+
**Full** (large/complex): Interview → rich PROJECT-DEFINITION narratives for user approval → scope xBRIEFs with traceability.
|
|
714
|
+
|
|
715
|
+
! Neither greenfield path creates `xbrief/specification.xbrief.json`; that file remains a full-spec compatibility artifact.
|
|
687
716
|
|
|
688
717
|
### Interview Process (interview strategy)
|
|
689
718
|
|
|
@@ -715,7 +744,7 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
715
744
|
|
|
716
745
|
### Output — Light Path
|
|
717
746
|
|
|
718
|
-
1. !
|
|
747
|
+
1. ! Merge the confirmed slim narratives into `./xbrief/PROJECT-DEFINITION.xbrief.json`:
|
|
719
748
|
- `Overview`: Brief project summary
|
|
720
749
|
- `Architecture`: System design description
|
|
721
750
|
2. ! Create scope xBRIEFs in `./xbrief/proposed/` for each identified work item
|
|
@@ -733,8 +762,8 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
733
762
|
}
|
|
734
763
|
]
|
|
735
764
|
```
|
|
736
|
-
3. ! Summarize decisions
|
|
737
|
-
4. !
|
|
765
|
+
3. ! Summarize decisions and ask the user to approve the PROJECT-DEFINITION narratives and proposed scope set
|
|
766
|
+
4. ! Record approval in the setup session; do not manufacture or require `specification.xbrief.json`
|
|
738
767
|
- ⊗ Create a separate PRD.md on the Light path
|
|
739
768
|
- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`
|
|
740
769
|
|
|
@@ -747,7 +776,7 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
747
776
|
|
|
748
777
|
### Output — Full Path
|
|
749
778
|
|
|
750
|
-
1. !
|
|
779
|
+
1. ! Merge these rich narratives into `./xbrief/PROJECT-DEFINITION.xbrief.json` for review:
|
|
751
780
|
- `ProblemStatement`: What problem this project solves
|
|
752
781
|
- `Goals`: High-level project goals
|
|
753
782
|
- `UserStories`: User stories in standard format
|
|
@@ -755,8 +784,8 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
755
784
|
- `SuccessMetrics`: Measurable success criteria
|
|
756
785
|
- `Architecture`: System design and technical architecture
|
|
757
786
|
- `Overview`: Brief project summary
|
|
758
|
-
2. ! **Human approval gate**: Present the
|
|
759
|
-
3. !
|
|
787
|
+
2. ! **Human approval gate**: Present the PROJECT-DEFINITION narratives and proposed scope plan to the user for review. The user may request changes before approving.
|
|
788
|
+
3. ! Record approval in the setup session and proceed to downstream generation; do not manufacture or require `specification.xbrief.json`
|
|
760
789
|
4. ! Create scope xBRIEFs in `./xbrief/proposed/` with traceability to requirement IDs from the narratives
|
|
761
790
|
- ! Scope xBRIEFs MUST trace tasks back to requirement IDs (FR-1, NFR-1) from the `Requirements` narrative
|
|
762
791
|
- ⊗ Generate an authoritative PRD.md — if needed, users run `task prd:render`
|
|
@@ -813,8 +842,9 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
813
842
|
|
|
814
843
|
### Handoff to deft-directive-build
|
|
815
844
|
|
|
816
|
-
- ! Emit a structured-tool question asking whether to continue
|
|
817
|
-
-
|
|
845
|
+
- ! Emit a structured-tool question asking whether to continue toward the build phase only when the host preserves numeric labels; otherwise emit the deterministic numbered menu in chat. Options: `1. Yes (run cost phase)`, `2. Not now (exit setup)`, `3. Discuss`, `4. Back (revisit previous phase)`. The numeric labels MUST remain visible and be returned as numeric selections or exact displayed option text.
|
|
846
|
+
- ! If the user picks Yes, invoke `skills/deft-directive-cost/SKILL.md`; only a recorded Build or Skip decision from that skill may hand off to `skills/deft-directive-build/SKILL.md`
|
|
847
|
+
- ⊗ Invoke the build skill directly from setup and bypass the required cost decision
|
|
818
848
|
- ⊗ Leave user with a dead end -- always offer the next step via the structured-tool phase-transition question
|
|
819
849
|
- ⊗ Ask the handoff-to-build question as unnumbered conversational prose or through a structured UI that hides the canonical numeric labels -- it is a deterministic menu and MUST preserve visible numbers (#478, #1563).
|
|
820
850
|
|
|
@@ -832,7 +862,8 @@ Per [strategies/interview.md](../../strategies/interview.md#interview-rules-shar
|
|
|
832
862
|
4. ! If the user says `no`: re-display the values and ask which ones to correct, then re-confirm before writing
|
|
833
863
|
5. ! If any value appears to be auto-generated filler (e.g. repeated default text, placeholder strings, or values that echo the question prompt), warn the user explicitly: "Some values look like they may have been auto-filled rather than provided by you. Please review carefully."
|
|
834
864
|
|
|
835
|
-
⊗ Write USER.md, PROJECT-DEFINITION.xbrief.json,
|
|
865
|
+
⊗ Write USER.md, PROJECT-DEFINITION.xbrief.json, lifecycle scope xBRIEFs, or any other deft-directive-setup artifact without first displaying captured values and receiving explicit user confirmation.
|
|
866
|
+
⊗ Create `specification.xbrief.json` on a greenfield Light or Full path solely to satisfy export, cost, or build handoff.
|
|
836
867
|
⊗ Treat a broad "proceed" or "continue" as confirmation to write files -- the user must explicitly confirm the displayed values.
|
|
837
868
|
|
|
838
869
|
? **Yolo strategy carve-out**: When the user's chosen strategy is `yolo` (auto-pilot), the confirmation gate still applies but the agent (Johnbot) may self-confirm on the user's behalf by displaying the summary and immediately proceeding -- the user has already opted into auto-pilot by selecting yolo. The summary must still be displayed so the user can interrupt if values look wrong.
|
|
@@ -61,6 +61,8 @@ Task B (xBRIEF: [filename], issue #[N]): [one-paragraph description with specifi
|
|
|
61
61
|
STEP 3 — Validate: Use iteration fast lane during commits (affected/static gates). Run full task check once before push/PR (#1704). Fix any failures.
|
|
62
62
|
|
|
63
63
|
STEP 4 — Commit: Add CHANGELOG.md entries under [Unreleased].
|
|
64
|
+
Commit early: as soon as a coherent unit exists (source + tests that compile), then at checkpoints.
|
|
65
|
+
A host-kill must not leave the only copy unversioned (#3730).
|
|
64
66
|
Commit with message: [type]([scope]): [description] — with bullet-point body.
|
|
65
67
|
|
|
66
68
|
STEP 5 — Push and PR: Push branch to origin. Create PR targeting <configured-base-branch> using gh CLI.
|
|
@@ -77,6 +79,8 @@ CONSTRAINTS:
|
|
|
77
79
|
- Iteration commits: affected/static fast lane only; full task check required before push (#1704)
|
|
78
80
|
- Never force-push
|
|
79
81
|
- Dual stop (#2442): multi-iteration fix/repair loops need success + failure/budget stop (build defaults: max 5 quality-fix iters or 3 identical no-progress; pre-PR: max 3 polish passes). On halt: operator-visible report (tried / missing / human decision). Single-turn work is exempt. Delivery/acceptance mechanical ledger is #3143 (`packages/core/src/delivery-attempt/` / `docs/delivery-attempt.md`).
|
|
82
|
+
- Heartbeat (#1365 / #3730): write `.deft-scratch/subagent-status/<agent-id>.json` immediately on start (`phase: starting`) and every 2-3 minutes. See `docs/subagent-heartbeat.md`.
|
|
83
|
+
- Commit early (#3730): first coherent unit, then checkpoints. Do not hold a complete correct diff uncommitted until PR time.
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
### Template Rules
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
#### Mode A -- Pre-created worktree map (C3, headless via `--worktree-map`)
|
|
38
38
|
|
|
39
39
|
- ! When `task swarm:launch -- ... --worktree-map <path>` supplied a **pre-created worktree map** (**C3**), Phase 2 CONSUMES it instead of running `git worktree add` per agent. The C3 map is a JSON array of `{ "story_id": str, "worktree_path": str, "base_branch": str }`.
|
|
40
|
-
- ! The launch engine resolves the worktree map via `resolveWorktreeMap` (`packages/core/src/swarm/worktrees.ts`), which validates normalized C3 records and RAISES on same-path collisions
|
|
40
|
+
- ! The launch engine resolves the worktree map via `resolveWorktreeMap` (`packages/core/src/swarm/worktrees.ts`), which validates normalized C3 records and RAISES on same-path collisions, base-branch mismatches, or a registered path whose HEAD OID differs from the requested base OID. The HEAD check is a snapshot at resolution time -- `swarm:launch` emits a manifest and stops, so HEAD can still move before spawn. The monitor MUST surface any such raise verbatim and HALT setup -- a same-path collision means two agents would share one worktree (the Duplicate-Agent Failure Mode in Phase 4).
|
|
41
41
|
- ! Each resolved record's `worktree_path` and `base_branch` feed straight into Phase 3 dispatch and MUST match the **C2** launch-manifest's `worktree_path` / `branch` fields for the same `story_id`.
|
|
42
42
|
|
|
43
43
|
#### Mode B -- Monitor-created worktrees (interactive path)
|
|
@@ -100,7 +100,9 @@ Cross-references: `packages/core/src/platform/platform-capabilities.ts` (#1557a)
|
|
|
100
100
|
|
|
101
101
|
! **Supported backend examples (none mandatory):** Composer-class coding agents, Grok Build `spawn_subagent` workers, Cursor/cloud agents, and future adapters are all first-class examples. No single backend is required — Grok Build is one implementation of provider-neutral routing, not the only target.
|
|
102
102
|
|
|
103
|
-
! **Implement-leaf pre-dispatch (#3228):** Before the actual spawn primitive for an implement leaf (and before any re-dispatch), run `task swarm:pre-dispatch -- --scope-id <id> --target-id <worktree-or-branch>` — exit **0** only means spawn is allowed; exit **1** is `DENY_DUPLICATE_ACTIVE` (do not spawn). Depth + takeover: [`core-phase-4.md`](core-phase-4.md) Pre-dispatch deny gate; library #3143.
|
|
103
|
+
! **Implement-leaf pre-dispatch (#3228 / #3730):** Before the actual spawn primitive for an implement leaf (and before any re-dispatch), run `task swarm:pre-dispatch -- --scope-id <id> --target-id <worktree-or-branch>` — exit **0** only means spawn is allowed; exit **1** is `DENY_DUPLICATE_ACTIVE` (do not spawn). Begin on a filesystem worktree target also mkdirs `.deft-scratch/subagent-status/` so `verify:subagent-alive --require-agent` can return REDISPATCH_OK instead of exit 2. Depth + takeover: [`core-phase-4.md`](core-phase-4.md) Pre-dispatch deny gate; library #3143.
|
|
104
|
+
|
|
105
|
+
! **Arm the heartbeat path at dispatch (#3730):** Create the worker worktree's `.deft-scratch/subagent-status/` before spawn (mechanical on `swarm:launch` worktree-map and `swarm:pre-dispatch` begin). Instruct the worker to heartbeat per `templates/agent-prompt-preamble.md` § 10.5 and to commit early. Monitors MUST pass `--require-agent <agent-id>` on `task verify:subagent-alive`. ⊗ Put liveness on the C2 launch manifest or in `occupancy.json`.
|
|
104
106
|
|
|
105
107
|
! **Operator model routing (#1739):** the concrete per-role model lives in the gitignored, per-machine `.deft/routing.local.json`, keyed by `(dispatch_provider, worker_role)`. Record a decision with `task swarm:routing-set -- --role <role> (--model <slug> | --harness-default)`. `task swarm:launch` resolves the active provider's route and stamps `resolved_model` + `model_source` into each C2 manifest record. When `resolved_model` is non-null, the monitor MUST pass it as the **model argument of the actual dispatch primitive** (e.g. the Task tool's `model` field for a Cursor sub-agent) — stamping the manifest is prep; a recorded model that never reaches the spawn call is the bug #1739 closes. Run `task verify:routing` before dispatching a cohort (pre-dispatch hard gate; fails when a dispatched role is undecided) and `task verify:routing -- --advise` at session start (non-blocking disclosure). For harness-bound providers (e.g. `grok`) only `--harness-default` is recordable and `resolved_model` stays null.
|
|
106
108
|
|
|
@@ -11,16 +11,17 @@
|
|
|
11
11
|
|
|
12
12
|
! On the Grok Build hybrid path (`spawn_subagent` dispatch, no native lifecycle channel back to the monitor), worktree git state alone is INSUFFICIENT to distinguish a healthy mid-poll sub-agent from a stalled one. Long-running review-cycle pollers spend most of their wall-clock waiting on Greptile and emit no commits during that wait -- the #1166 swarm session is the recurrence record (two of three dispatched pollers went silent with zero observable signals; the monitor could not tell).
|
|
13
13
|
|
|
14
|
-
! The canonical alive-check on the Grok Build hybrid path is the heartbeat contract documented in `docs/subagent-heartbeat.md`. Every long-running sub-agent (pollers, watchdogs, implementation agents whose tool loop exceeds ~3 min) writes a JSON heartbeat to `.deft-scratch/subagent-status/<agent-id>.json` per the canonical poller template + agent preamble
|
|
14
|
+
! The canonical alive-check on the Grok Build hybrid path is the heartbeat contract documented in `docs/subagent-heartbeat.md`. Every long-running sub-agent (pollers, watchdogs, implementation agents whose tool loop exceeds ~3 min) writes a JSON heartbeat to `.deft-scratch/subagent-status/<agent-id>.json` per the canonical poller template + agent preamble. Default threshold is 30 minutes; `--threshold-minutes` overrides.
|
|
15
|
+
|
|
16
|
+
! Monitors MUST poll with `task verify:subagent-alive -- --require-agent <agent-id> [--scratch-dir <worktree>/.deft-scratch/subagent-status]` so a missing required record is exit `1` + `REDISPATCH_OK`, not a raw sweep that treats an empty dir as OK. `task agent:monitor` remains the raw sweep.
|
|
15
17
|
|
|
16
18
|
```
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
--scratch-dir <worktree
|
|
20
|
-
--scratch-dir <worktree-2>/.deft-scratch/subagent-status
|
|
19
|
+
task verify:subagent-alive -- \
|
|
20
|
+
--require-agent <agent-id> \
|
|
21
|
+
--scratch-dir <worktree>/.deft-scratch/subagent-status
|
|
21
22
|
```
|
|
22
23
|
|
|
23
|
-
! Run the
|
|
24
|
+
! Run the liveness gate alongside the worktree git checks at every monitor polling iteration (~2-3 min). When a record is reported STALE (mid-flight, terminal_state unpopulated, age > threshold), treat it as a candidate for the Takeover Triggers below; when it is reported MALFORMED, surface the diagnostics to the user and re-dispatch the agent with a fresh prompt that re-establishes the heartbeat contract. A TERMINAL record (terminal_state set) is NEVER stale -- the agent reached its exit on its own terms.
|
|
24
25
|
|
|
25
26
|
~ The heartbeat is filesystem-only by design; a network partition or rate-limit ceiling cannot mask agent liveness. Pair the on-disk sweep with the worktree git checks (`git status --short`, `git log --oneline -3`) and the per-PR readiness gate (`task pr:merge-ready`) for the full alive + progressing + clean picture.
|
|
26
27
|
|
|
@@ -144,12 +145,14 @@ task swarm:pre-dispatch -- \
|
|
|
144
145
|
--scope-id <id> --target-id <target> \
|
|
145
146
|
--action complete --status succeeded|failed|cancelled|blocked
|
|
146
147
|
|
|
147
|
-
# Takeover: cancel prior attempt, THEN pre-dispatch begin again (never dual active)
|
|
148
|
+
# Takeover after REDISPATCH_OK: cancel prior attempt, THEN pre-dispatch begin again (never dual active)
|
|
148
149
|
task swarm:pre-dispatch -- --scope-id <id> --target-id <target> --action cancel
|
|
149
150
|
task swarm:pre-dispatch -- --scope-id <id> --target-id <target> # begin
|
|
151
|
+
# If verify:session-ritual --tier=gated fails first:
|
|
152
|
+
task session:start --rearm --session-id=<same>
|
|
150
153
|
```
|
|
151
154
|
|
|
152
|
-
! Gate authority is **#3143** `DENY_DUPLICATE_ACTIVE` (`maxActiveAttempts: 1`) on the delivery-attempt unit ledger (`scopeId` + `targetId` + `workflowId`, default workflow `drive-to:merge-ready`). CLI is authoritative; this section is a pointer only.
|
|
155
|
+
! Gate authority is **#3143** `DENY_DUPLICATE_ACTIVE` (`maxActiveAttempts: 1`) on the delivery-attempt unit ledger (`scopeId` + `targetId` + `workflowId`, default workflow `drive-to:merge-ready`). A killed worker stays `queued`/`running` until cancel; `REDISPATCH_OK` does not lift the deny (#3730). CLI is authoritative; this section is a pointer only.
|
|
153
156
|
⊗ Spawn a second implement leaf while pre-dispatch exits 1 (active attempt exists).
|
|
154
157
|
⊗ Treat "resume failed" / host false-alive as license to skip the gate.
|
|
155
158
|
⊗ Lift DENY by concurrent dual active — escape hatch is cancel-then-begin, not override-while-both-run.
|
|
@@ -11,6 +11,7 @@ Load this file only after detect selects Cursor. Do not load other host adapters
|
|
|
11
11
|
### Step 2e: Cursor Launch (Task tool available) — #1877
|
|
12
12
|
|
|
13
13
|
! When the platform descriptor is `cursor-composer` or `cursor-cloud-agent` (Cursor `Task` tool detected with Cursor signals, no `start_agent`, no `WARP_*`, no Claude Code classification, no OpenClaw `sessions_spawn`, no `spawn_subagent`), dispatch each worker via the Cursor `Task` tool with:
|
|
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>`.
|
|
14
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).
|
|
15
16
|
2. The standard worktree prompt (STEP 1-6 from the Prompt Template below).
|
|
16
17
|
3. The worktree path set to the agent's isolated git worktree.
|
|
@@ -24,6 +24,7 @@ This path became first-class in #1342 (platform adapter slices 1-3) and is fully
|
|
|
24
24
|
### Step 2d: Grok Build Launch (spawn_subagent available)
|
|
25
25
|
|
|
26
26
|
! When the platform descriptor is `grok-build` (spawn_subagent detected, no start_agent, no WARP_*, no Cursor `Task`, no OpenClaw `sessions_spawn`), dispatch each worker via `spawn_subagent` with:
|
|
27
|
+
0. Create `<worktree>/.deft-scratch/subagent-status/` before spawn if launch/pre-dispatch did not already, and instruct the worker to heartbeat + commit early (#3730).
|
|
27
28
|
1. The canonical `templates/agent-prompt-preamble.md` content as the preamble
|
|
28
29
|
2. The standard worktree prompt (STEP 1-6 from the Prompt Template below), adapted to use `get_command_or_subagent_output` for polling rather than `start_agent` lifecycle events
|
|
29
30
|
3. The worktree path set to the agent's isolated git worktree
|