@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.
Files changed (34) hide show
  1. package/Taskfile.yml +1 -1
  2. package/UPGRADING.md +22 -3
  3. package/commands.md +24 -2
  4. package/contracts/design-critique.md +117 -16
  5. package/docs/delivery-attempt.md +2 -1
  6. package/docs/freshness-contract.md +6 -1
  7. package/docs/getting-started.md +10 -11
  8. package/docs/hook-runtime-unavailable.md +54 -0
  9. package/docs/orphan-active-verdict-basis.md +166 -0
  10. package/package.json +1 -1
  11. package/packs/skills/skills-pack-0.1.json +7 -7
  12. package/scm/github.md +31 -1
  13. package/skills/deft-directive-build/SKILL.md +1 -1
  14. package/skills/deft-directive-cost/SKILL.md +7 -11
  15. package/skills/deft-directive-design-critique/SKILL.md +8 -1
  16. package/skills/deft-directive-design-critique/references/motion-shape.md +19 -0
  17. package/skills/deft-directive-interview/SKILL.md +10 -10
  18. package/skills/deft-directive-release/SKILL.md +10 -6
  19. package/skills/deft-directive-review-cycle/SKILL.md +33 -0
  20. package/skills/deft-directive-setup/SKILL.md +53 -22
  21. package/skills/deft-directive-swarm/references/core-ops.md +4 -0
  22. package/skills/deft-directive-swarm/references/core-phase-1-2.md +1 -1
  23. package/skills/deft-directive-swarm/references/core-phase-3.md +3 -1
  24. package/skills/deft-directive-swarm/references/core-phase-4.md +11 -8
  25. package/skills/deft-directive-swarm/references/host-cursor.md +1 -0
  26. package/skills/deft-directive-swarm/references/host-grok-build.md +1 -0
  27. package/tasks/engine.yml +2 -0
  28. package/tasks/occupancy.yml +24 -2
  29. package/tasks/prd.yml +4 -5
  30. package/tasks/session.yml +3 -3
  31. package/tasks/toolchain.yml +2 -2
  32. package/tasks/verify.yml +11 -1
  33. package/templates/agent-prompt-preamble.md +9 -2
  34. package/templates/agents-entry.md +6 -1
package/tasks/engine.yml CHANGED
@@ -103,6 +103,8 @@ tasks:
103
103
  " session:ready "|" session-ready "|\
104
104
  " occupancy:steal "|" occupancy-steal "|\
105
105
  " occupancy:release "|" occupancy-release "|\
106
+ " occupancy:heartbeat "|" occupancy-heartbeat "|\
107
+ " occupancy:grant "|" occupancy-grant "|\
106
108
  " session:end "|" session-end "|\
107
109
  " lifecycle:event "|" lifecycle-event "|\
108
110
  " verify:session-ritual "|" verify-session-ritual "|\
@@ -7,7 +7,7 @@ vars:
7
7
 
8
8
  tasks:
9
9
  steal:
10
- desc: "Supersede a live worktree occupancy lease (#3433). Flags: --confirm --occupant <id>"
10
+ desc: "Lease-only confirmed steal (#3433/#3611). Flags: --confirm --occupant <reported-session-id>; manual/Grok owner: --session-id <your-session-id> or DEFT_SESSION_ID. If ritual differs, align that ID with eligible re-arm or cold session:start. Prefer session:start --steal."
11
11
  dir: '{{.USER_WORKING_DIR}}'
12
12
  env:
13
13
  PYTHONUTF8: "1"
@@ -17,7 +17,7 @@ tasks:
17
17
  ENGINE_CMD: 'occupancy:steal --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
18
18
 
19
19
  release:
20
- desc: "Release this worktree occupancy lease (#3604). Owner live or expired residue. Non-owner live denied."
20
+ desc: "Release this worktree occupancy lease (#3604/#3611). Manual/Grok owner: --session-id <id> or DEFT_SESSION_ID. Owner live or expired residue; non-owner live denied."
21
21
  dir: '{{.USER_WORKING_DIR}}'
22
22
  # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
23
23
  env:
@@ -26,3 +26,25 @@ tasks:
26
26
  - task: :engine:invoke
27
27
  vars:
28
28
  ENGINE_CMD: 'occupancy:release --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
29
+
30
+ heartbeat:
31
+ desc: "Refresh your own live lease during long quiet stretches (#3599). Manual/Grok owner: --session-id <id> or DEFT_SESSION_ID. Gated writes refresh automatically; this never claims."
32
+ dir: '{{.USER_WORKING_DIR}}'
33
+ # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
34
+ env:
35
+ PYTHONUTF8: "1"
36
+ cmds:
37
+ - task: :engine:invoke
38
+ vars:
39
+ ENGINE_CMD: 'occupancy:heartbeat --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
40
+
41
+ grant:
42
+ desc: "Admit a dispatched child to your lease for writes (#3755). Owner-only: --session-id <id> or DEFT_SESSION_ID, plus --child-session-id <id> --role <worker-role> [--ttl-minutes N] [--revoke]. Grants admit writes, never administration."
43
+ dir: '{{.USER_WORKING_DIR}}'
44
+ # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
45
+ env:
46
+ PYTHONUTF8: "1"
47
+ cmds:
48
+ - task: :engine:invoke
49
+ vars:
50
+ ENGINE_CMD: 'occupancy:grant --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
package/tasks/prd.yml CHANGED
@@ -21,12 +21,11 @@ tasks:
21
21
  # would cause go-task to short-circuit before `cmds:` runs, dropping
22
22
  # CLI_ARGS and silently breaking the #539 recovery path (#573, #574).
23
23
  # See deft/conventions/task-caching.md for the full rule.
24
- desc: Export plan.narratives from the specification artifact to a read-only PRD.md
24
+ desc: Export resolved project narratives to a read-only PRD.md
25
25
  summary: |
26
- Reads the specification artifact (xbrief/specification.xbrief.json on migrated
27
- trees, vbrief/specification.vbrief.json on legacy trees) and extracts
28
- plan.narratives into a human-readable PRD.md for stakeholder export. PRD.md is
29
- never authoritative -- the xBRIEF is the source of truth.
26
+ Resolves full-spec or greenfield authority from the project root and extracts
27
+ stakeholder-safe narratives into a human-readable PRD.md. Explicit --spec remains
28
+ supported. PRD.md is never authoritative -- the resolved xBRIEF is the source of truth.
30
29
  dir: '{{.USER_WORKING_DIR}}'
31
30
  deps:
32
31
  - task: :engine:_ts-build
package/tasks/session.yml CHANGED
@@ -10,7 +10,7 @@ vars:
10
10
 
11
11
  tasks:
12
12
  start:
13
- desc: "Run quick-tier session-start ritual and write .deft/ritual-state.json (#1348). Flags: --defer step=reason / --json"
13
+ desc: "Claim occupancy and run the quick-tier ritual for one owner (#1348/#3611). Flags: --session-id <id> / --steal --confirm --occupant <current-id> / --defer step=reason / --json"
14
14
  dir: '{{.USER_WORKING_DIR}}'
15
15
  # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
16
16
  env:
@@ -21,7 +21,7 @@ tasks:
21
21
  ENGINE_CMD: 'session:start --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
22
22
 
23
23
  ready:
24
- desc: "One-shot mutation recovery to gated write-ready (#2993). Composes session:start + verify:session-ritual --tier=gated + cache fetch-all when needed. Flags: --json / --repo OWNER/NAME / --with-network"
24
+ desc: "One-shot mutation recovery to gated write-ready (#2993/#3611). Composes session:start + verify:session-ritual --tier=gated + cache fetch-all when needed. Flags: --session-id <id> / --json / --repo OWNER/NAME / --with-network"
25
25
  dir: '{{.USER_WORKING_DIR}}'
26
26
  # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
27
27
  env:
@@ -32,7 +32,7 @@ tasks:
32
32
  ENGINE_CMD: 'session:ready --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
33
33
 
34
34
  end:
35
- desc: "End this mutation session by releasing occupancy (#3604). Same as occupancy:release."
35
+ desc: "End this mutation session by releasing occupancy (#3604/#3611). Manual/Grok owner: --session-id <id> or DEFT_SESSION_ID. Same as occupancy:release."
36
36
  dir: '{{.USER_WORKING_DIR}}'
37
37
  # Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
38
38
  env:
@@ -14,10 +14,10 @@ tasks:
14
14
  ENGINE_CMD: 'toolchain-check'
15
15
 
16
16
  check-consumer:
17
- desc: Verify required consumer toolchain is installed (git, gh, node, pnpm, task) without Python/go/uv (#2022 Phase 3).
17
+ desc: Verify git, gh, node, and the consumer's selected npm or pnpm; this gate does not probe go-task/Python/go/uv (#3610/#3335).
18
18
  deps:
19
19
  - task: :engine:_ts-build
20
20
  cmds:
21
21
  - task: :engine:invoke
22
22
  vars:
23
- ENGINE_CMD: 'toolchain-check --consumer'
23
+ ENGINE_CMD: 'toolchain-check --consumer --project-root "{{.USER_WORKING_DIR}}"'
package/tasks/verify.yml CHANGED
@@ -503,7 +503,7 @@ tasks:
503
503
  ENGINE_CMD: 'verify:lifecycle-visible --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
504
504
 
505
505
  orphan-active:
506
- desc: "Fail-closed orphan-active guard (#2321 / #3429). Detects xbrief/active/ briefs with plan.status==running whose referenced GitHub issues are all closed and/or whose linked PR is merged — the stop-at:pr-open lifecycle leak. Confirmed shipped remediates with task scope:complete / scope:cancel or swarm finalize. Unresolved GitHub lookup still exits 1 but prints a retry, not scope:complete. Three-state exit (0 clean / 1 orphan / 2 config). Pass --issue N to scan one origin after merge; --skip-gh to rely on triage cache only."
506
+ desc: "Fail-closed orphan-active guard (#2321 / #3429). Detects xbrief/active/ briefs with plan.status==running whose referenced GitHub issues are all closed and/or whose linked PR is merged — the stop-at:pr-open lifecycle leak. Confirmed shipped remediates with task scope:complete / scope:cancel or swarm finalize. Unresolved GitHub lookup still exits 1 but prints a retry, not scope:complete. Three-state exit (0 clean / 1 orphan / 2 config). Pass --issue N to scan one origin after merge; --skip-gh to rely on triage cache only. Issue state resolves by query shape (#3767): scoped --issue N takes an authoritative read and stays fail-closed on unknown; the unscoped sweep uses one complete open-issue inventory and stays fail-open on unknown. A cache hit counts only within 15 minutes, and every run prints the basis of its verdict — see content/docs/orphan-active-verdict-basis.md."
507
507
  dir: '{{.USER_WORKING_DIR}}'
508
508
  deps:
509
509
  - task: :engine:_ts-build
@@ -512,6 +512,16 @@ tasks:
512
512
  vars:
513
513
  ENGINE_CMD: 'verify:orphan-active --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
514
514
 
515
+ pr-closeout-attestable:
516
+ desc: "Fail-closed merge-time closeout gate (#3781). Refuses a merge when the PR's structured closing references name an issue whose brief is still running in xbrief/active/ with acceptance criteria carrying neither x-directive/evidence nor x-directive/disposition. The trigger is the closing reference, not the branch diff — CI runs before the merge and the issue closes on it, so a diff-keyed gate can never fail the PR that creates the orphan. Reuses evaluateAcceptanceEvidenceGate, the same rule scope:complete enforces. A PR that leaves an unattested brief WITHOUT closing its issue is unaffected. Three-state exit (0 attestable or closes nothing / 1 unattested closeout / 2 config or closing-reference lookup error). -- task verify:pr-closeout-attestable -- --pr N [--repo OWNER/REPO]"
517
+ dir: '{{.USER_WORKING_DIR}}'
518
+ deps:
519
+ - task: :engine:_ts-build
520
+ cmds:
521
+ - task: :engine:invoke
522
+ vars:
523
+ ENGINE_CMD: 'verify:pr-closeout-attestable --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
524
+
515
525
  completed-write-guard:
516
526
  desc: "Fail-closed completed/ write guard (#3679). Newly added xbrief/completed/ (or vbrief/completed/) artifacts must have been written by scope:complete / scope:fail. Historical corpus is advisory via doctor. Remediation names the leftover land PR (#3476). Three-state exit (0 clean / 1 unguarded add / 2 config). Does not change verify:completed-tracked."
517
527
  dir: '{{.USER_WORKING_DIR}}'
@@ -551,10 +551,17 @@ The parent monitor watches the heartbeat file directly (three-state exit 0 ok /
551
551
 
552
552
  ! **OpenClaw `sessions_spawn` / heartbeat mapping (#2879):** Same file-heartbeat contract applies to OpenClaw review-monitors and long-running leaves. OpenClaw host session liveness, Control UI presence, or gateway channel reachability does NOT replace periodic heartbeats — those signals only prove the session exists, not that the tool loop is progressing. OpenClaw pollers write `.deft-scratch/subagent-status/<agent-id>.json` so `task agent:monitor` / `task verify:subagent-alive` can detect stalled monitors; OpenClaw-native session status MAY be a *supplementary* signal only. Host "still running" + missing/STALE heartbeat authorizes the same `REDISPATCH_OK` posture as Cursor #2824.
553
553
 
554
- ! **Parent ensures scratch dir + startup grace before REDISPATCH_OK (#2879):** `task verify:subagent-alive` exits `2` (config error, no `REDISPATCH_OK`) when the scratch directory is **missing** and has no records. Parents MUST `mkdir` the worker worktree's `.deft-scratch/subagent-status/` at dispatch time so a later missing record is exit `1` + `REDISPATCH_OK`. Parents MUST ALSO wait a **startup grace** (default 3 minutes from dispatch, or until the first `phase: "starting"` heartbeat is observed) before treating a missing required-agent as takeover-eligible — probing an empty parent-created dir immediately races a healthy worker still writing its first heartbeat and can spawn a duplicate. Exit `2` remains reserved for true config errors (bad args / wrong path).
554
+ ! **Parent ensures scratch dir + startup grace before REDISPATCH_OK (#2879 / #3730):** `task verify:subagent-alive` exits `2` (config error, no `REDISPATCH_OK`) when the scratch directory is **missing** and has no records. Parents MUST `mkdir` the worker worktree's `.deft-scratch/subagent-status/` at dispatch time so a later missing record is exit `1` + `REDISPATCH_OK`. `task swarm:launch` (worktree map) and `task swarm:pre-dispatch --action begin` on a filesystem target mkdir this directory mechanically. Interactive Cursor/OpenClaw/Grok spawn without those verbs still MUST mkdir before the spawn primitive. Parents MUST ALSO wait a **startup grace** (default 3 minutes from dispatch, or until the first `phase: "starting"` heartbeat is observed) before treating a missing required-agent as takeover-eligible — probing an empty parent-created dir immediately races a healthy worker still writing its first heartbeat and can spawn a duplicate. Exit `2` remains reserved for true config errors (bad args / wrong path). ⊗ Put runtime liveness on the C2 launch manifest (written `mode: "replace"`) or in `occupancy.json`.
555
555
 
556
556
  - Monitors run `task verify:subagent-alive -- --require-agent <agent-id> [--scratch-dir <worktree>/.deft-scratch/subagent-status]` each poll iteration.
557
557
  - Workers run `task agent:monitor` (raw sweep) or the gate verb above; both wrap `subagent-monitor` (#1365).
558
+ - Workers MUST write the first heartbeat immediately (`phase: "starting"`) and keep the cadence in this section. A dispatch that never instructs the worker to heartbeat leaves the armed directory empty and a host-kill indistinguishable from "never started" until grace elapses.
559
+
560
+ ! **Commit early (#3730):** Long-running implementation workers MUST commit as soon as a coherent unit exists (source + tests that compile), then commit again at natural checkpoints. A host-kill leaves uncommitted work invisible to every gate. ⊗ Hold a complete correct diff uncommitted until PR time.
561
+
562
+ ! **Killed-worker takeover (#3730 / #3228):** `REDISPATCH_OK` does not lift `DENY_DUPLICATE_ACTIVE`. A killed worker's delivery attempt stays `running` until cancelled. Takeover is `task swarm:pre-dispatch -- --scope-id <id> --target-id <worktree> --action cancel` then the same command without `--action` (begin). Do not add a third liveness classifier.
563
+
564
+ ! **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).
558
565
 
559
566
  ## 10.55 Rule Authority and Thin Fail-Closed (#3313)
560
567
 
@@ -577,7 +584,7 @@ Multi-iteration implement, pre-PR, repair, and monitor loops require **two** sto
577
584
 
578
585
  ! On failure stop: halt; emit an operator-visible report (what was tried, what is missing, what human decision is needed). Prefer `BLOCKED:` over silent retry. ⊗ Thrash past the envelope. Durable delivery/acceptance mechanical enforcement is **#3143** (`packages/core/src/delivery-attempt/`; not prompt-only).
579
586
 
580
- ! **Implement-leaf pre-dispatch (#3228):** Before spawning a peer implement leaf on a unit (story/worktree), monitors/orchestrators MUST run `task swarm:pre-dispatch -- --scope-id <id> --target-id <worktree-or-branch>` (exit **0** allow / **1** active deny / **2** config). Non-zero → do not spawn. Gate is #3143 `DENY_DUPLICATE_ACTIVE`. Takeover = `--action cancel` then pre-dispatch begin again. Pointer only — skill depth: swarm `core-phase-4.md`.
587
+ ! **Implement-leaf pre-dispatch (#3228 / #3730):** Before spawning a peer implement leaf on a unit (story/worktree), monitors/orchestrators MUST run `task swarm:pre-dispatch -- --scope-id <id> --target-id <worktree-or-branch>` (exit **0** allow / **1** active deny / **2** config). Non-zero → do not spawn. Gate is #3143 `DENY_DUPLICATE_ACTIVE`. Takeover after `REDISPATCH_OK` = `--action cancel` then pre-dispatch begin again. A killed worker stays `running` until that cancel. Pointer only — skill depth: swarm `core-phase-4.md`.
581
588
 
582
589
  ## 11. Mandatory DONE message even on early exit
583
590
 
@@ -10,9 +10,14 @@ Deft is installed in .deft/core/. Full guidelines: .deft/core/main.md
10
10
  ! Before further Directive process load, check root `.deft-directive-disable` (presence = flag). If present → stop DD load; recovery = delete file + NEW agent session. Deposit OK; not `.no-deft-directive` (#2926). Docs: `.deft/core/docs/deft-directive-disable.md`.
11
11
  ⊗ Claim full operation while the flag exists or after delete without a NEW agent session.
12
12
 
13
+ ## Hook runtime unavailable (#3785)
14
+
15
+ ! Opaque non-zero exit (usually 127) on every mutation = `deft-hook` is not executable on this host, not a Directive deny — no Directive code ran, and no in-session flag reaches it. Out of band: `deft policy:disable-host-hooks --host cursor --confirm`, or install the runtime (`npm i -g @deftai/directive`). Depth: `.deft/core/docs/hook-runtime-unavailable.md`.
16
+ ⊗ Hand-edit `failClosed` in `.cursor/hooks.json` — the next `deft update` rewrites it and silently re-arms the lockout.
17
+
13
18
  ## Session routing (#2176)
14
19
 
15
- ! **Read-only default** until mutation intent: load AGENTS.md / main.md / USER.md / `xbrief/PROJECT-DEFINITION.xbrief.json`; resolve USER.md via `deft session:start` (`USER.md resolved …`; win32 `%APPDATA%\deft\USER.md`; unix `~/.config/deft/USER.md`; ⊗ invent `~/.config/deft` on Windows #2544); confirm Deft alignment + addressing-name; ⊗ no mutable `deft session:start` / triage welcome / sync / branch-policy unless asked or implementation-ready (#2176) — `.deft/core/commands.md` § Session routing. Bootstrap: cold-start → README § Cold-start (#2273) ⊗ never `.deft/core/`; pre-cutover → setup Pre-Cutover (#2068); missing USER.md / PROJECT-DEFINITION → setup Phase 1/2 (#1813) ⊗ before answering; else main → USER → PROJECT-DEFINITION; ~ sync. Mutation → `deft session:start` then `deft verify:session-ritual -- --tier=gated` (#1149). Mutation occupancy lease (#3433/#3604): occupant `occupancy:release`/`session:end` (`commands.md`). ? `deft session:start -- --read-only` (#2176).
20
+ ! **Read-only default** until mutation intent: load AGENTS.md / main.md / USER.md / `xbrief/PROJECT-DEFINITION.xbrief.json`; resolve USER.md via `deft session:start` (`USER.md resolved …`; win32 `%APPDATA%\deft\USER.md`; unix `~/.config/deft/USER.md`; ⊗ invent `~/.config/deft` on Windows #2544); confirm Deft alignment + addressing-name; ⊗ no mutable `deft session:start` / triage welcome / sync / branch-policy unless asked or implementation-ready (#2176) — `.deft/core/commands.md` § Session routing. Bootstrap: cold-start → README § Cold-start (#2273) ⊗ never `.deft/core/`; pre-cutover → setup Pre-Cutover (#2068); missing USER.md / PROJECT-DEFINITION → setup Phase 1/2 (#1813) ⊗ before answering; else main → USER → PROJECT-DEFINITION; ~ sync. Mutation → `deft session:start` then `deft verify:session-ritual -- --tier=gated` (#1149). Occupancy (#3433/#3611/#3755): bearer-id, not auth/lineage; `occupancy:grant` `commands.md`. ? `deft session:start -- --read-only` (#2176).
16
21
 
17
22
  ## Session-start ritual (#1149)
18
23