@deftai/directive-content 0.87.0 → 0.89.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 (58) hide show
  1. package/.agents/skills/deft-directive-swarm/SKILL.md +1 -996
  2. package/QUICK-START.md +4 -0
  3. package/Taskfile.yml +16 -0
  4. package/UPGRADING.md +34 -2
  5. package/coding/coding.md +5 -1
  6. package/coding/security.md +13 -1
  7. package/commands.md +27 -1
  8. package/contracts/closed-verb-authz.md +117 -0
  9. package/contracts/escalation.md +114 -0
  10. package/contracts/finish-loop.md +121 -0
  11. package/contracts/host-lifecycle-duties.md +86 -0
  12. package/contracts/human-origin-authz.md +109 -0
  13. package/contracts/intent-ceiling.md +44 -0
  14. package/contracts/path-write-fence.md +128 -0
  15. package/contracts/runtime-authority.md +44 -8
  16. package/docs/getting-started.md +4 -0
  17. package/docs/no-deft-directive.md +87 -0
  18. package/docs/openclaw-agent-host.md +34 -1
  19. package/docs/product-signal.md +2 -0
  20. package/docs/writing-ste100.md +53 -0
  21. package/glossary.md +37 -39
  22. package/package.json +2 -1
  23. package/packs/rules/rules-pack-0.1.json +66 -2
  24. package/packs/skills/skills-pack-0.1.json +24 -24
  25. package/packs/strategies/strategies-pack-0.1.json +4 -4
  26. package/patterns/install-trust.md +117 -0
  27. package/scm/github.md +14 -2
  28. package/skills/deft-directive-article-review/SKILL.md +4 -1
  29. package/skills/deft-directive-release/SKILL.md +15 -0
  30. package/skills/deft-directive-setup/SKILL.md +43 -15
  31. package/skills/deft-directive-swarm/SKILL.md +81 -978
  32. package/skills/deft-directive-swarm/references/core-ops.md +144 -0
  33. package/skills/deft-directive-swarm/references/core-phase-0.md +200 -0
  34. package/skills/deft-directive-swarm/references/core-phase-1-2.md +73 -0
  35. package/skills/deft-directive-swarm/references/core-phase-3.md +145 -0
  36. package/skills/deft-directive-swarm/references/core-phase-4.md +71 -0
  37. package/skills/deft-directive-swarm/references/core-phase-5-6.md +317 -0
  38. package/skills/deft-directive-swarm/references/host-cursor.md +25 -0
  39. package/skills/deft-directive-swarm/references/host-generic.md +27 -0
  40. package/skills/deft-directive-swarm/references/host-grok-build.md +37 -0
  41. package/skills/deft-directive-swarm/references/host-openclaw.md +93 -0
  42. package/skills/deft-directive-swarm/references/host-warp.md +37 -0
  43. package/skills/deft-directive-write-skill/SKILL.md +17 -0
  44. package/strategies/artifact-guards.md +24 -14
  45. package/strategies/discuss.md +40 -1
  46. package/strategies/interview.md +103 -30
  47. package/strategies/probe.md +27 -1
  48. package/tasks/directive.yml +22 -0
  49. package/tasks/engine-invoke.cjs +69 -13
  50. package/tasks/engine-invoke.test.cjs +188 -0
  51. package/tasks/pr.yml +16 -0
  52. package/tasks/scm.yml +20 -0
  53. package/tasks/verify.yml +17 -0
  54. package/templates/agent-prompt-preamble.md +18 -0
  55. package/templates/agents-entry.md +6 -2
  56. package/templates/project.md.template +6 -0
  57. package/vbrief/schemas/vbrief-core.schema.json +33 -0
  58. package/vbrief/vbrief.md +4 -2
@@ -0,0 +1,86 @@
1
+ # Host lifecycle duty list (#2968 / A3)
2
+
3
+ Stable moments where a **host** (IDE deposit or session-first workspace) must load
4
+ Directive’s portable brain (Skills Index, pins, main.md / AGENTS.md) before freestyle
5
+ tools. Short duty list — not a multi-host platform RFC.
6
+
7
+ Legend (RFC2119): `!`=MUST, `~`=SHOULD, `≉`=SHOULD NOT, `⊗`=MUST NOT, `?`=MAY.
8
+
9
+ Related: OpenClaw cold-start adapter
10
+ [`../skills/deft-directive-swarm/references/host-openclaw.md`](../skills/deft-directive-swarm/references/host-openclaw.md) (A7),
11
+ skill pins [`../docs/skill-pin-policy.md`](../docs/skill-pin-policy.md) (#2508),
12
+ session routing in AGENTS.md (#2176), cold-start algorithm orientation (#609).
13
+
14
+ ## Two host families
15
+
16
+ | Family | Typical hosts | How Directive loads |
17
+ |--------|---------------|---------------------|
18
+ | **1 — IDE / repo deposit** | Cursor, VS Code-class | Open folder → installer rails / deposit → agent already on project root |
19
+ | **2 — Session / workspace / companion** | OpenClaw, Buzz-class | Agent awake in workspace home; host skill list ≠ Directive Skills Index until bridged |
20
+
21
+ ! Directive **writes** host adapters. Host vendors expose extension points; they are not required to ship Directive adapters.
22
+
23
+ ⊗ Wait on Cursor / OpenClaw / Buzz vendors to implement our adapter for cold-start correctness.
24
+
25
+ ## Duty table (stable moments)
26
+
27
+ | Moment | Duty |
28
+ |--------|------|
29
+ | **Session start** | Resolve **project root** (WSL / dual-path SoT when applicable). Know how to reach the **Skills Index** (consumer: `.deft/core/REFERENCES.md`; framework: `content/REFERENCES.md` or root `REFERENCES.md`). Optional session ritual when mutation intent applies (`session:start` / `#1149`). Confirm Deft alignment when USER.md is present (#2176). |
30
+ | **Deft-shaped user intent** | Route via **Skills Index / skill trigger path before freestyle host tools**. Prefer **pinned Directive skills** over same-named host skills (e.g. Cursor `/review` or host “review” ≠ `deft-directive-article-review` / `deft-directive-review-cycle`). |
31
+ | **Tool boundary** (optional) | Classifier hook / write-intent path when installed (#2967 A2 class). Graph append when installed (#2966 A1 class). Not required for this first cut. |
32
+ | **Turn / session end** (optional) | Evidence flush / MEMORY note of which skill path ran, for APE continuity. |
33
+
34
+ ### Deft-shaped intent (examples)
35
+
36
+ Treat as Deft-shaped when the user asks for skills, review, triage, swarm, build, pre-PR, article review, consumer-repo Directive work, xBRIEF lifecycle, or equivalent process verbs.
37
+
38
+ ! On Deft-shaped intent: scan Skills Index (Level-0) → open matching `SKILL.md` (Level-1) **before** freestyle `gh` / shell / host-global skill improvisation.
39
+
40
+ ! Prefer always-pin Directive skills (`deft-directive-build`, `deft-directive-pre-pr`, `deft-directive-review-cycle`, `deft-directive-swarm`) when the work type matches (#2508).
41
+
42
+ ⊗ Answer a Deft-shaped request with only host-global tools or same-named host skills when a Directive skill is in the Skills Index for that intent (2026-07-30 miss class: “use review skill” + URL never entered `deft-directive-article-review`).
43
+
44
+ ## Family-1 reference: Cursor deposit
45
+
46
+ Cursor / project-deposit remains the **family-1 reference adapter**:
47
+
48
+ 1. Open repo at project root.
49
+ 2. Deposit / AGENTS managed section points at Skills Index and pins.
50
+ 3. Session routing loads main → USER → PROJECT-DEFINITION before mutation.
51
+
52
+ ### Cursor parity checklist
53
+
54
+ | Check | Status |
55
+ |-------|--------|
56
+ | Project root = opened workspace folder | **Pass** (host default) |
57
+ | Skills Index reachable from AGENTS managed section | **Pass** when deposit current |
58
+ | Always-pin names for process skills | **Pass** when AGENTS pin section present (#2508) |
59
+ | Plan-mode / product action bypass of skill path | **Known gap** — plan-mode and host product actions can skip skill load (#1708 class); fix on Cursor adapter only when cold-start or skill route still fails |
60
+ | Same-named host skill vs Directive skill | **Known gap** — prefer Directive pin / Skills Index match over host `/review`-class labels |
61
+
62
+ ## Family-2 first ship: OpenClaw (A7)
63
+
64
+ OpenClaw cold-start steps live in the swarm host adapter (source of truth for spawn + cold-start on that host):
65
+
66
+ [`../skills/deft-directive-swarm/references/host-openclaw.md`](../skills/deft-directive-swarm/references/host-openclaw.md) § Cold-start.
67
+
68
+ Operator map (non-authoritative discovery): [`../docs/openclaw-agent-host.md`](../docs/openclaw-agent-host.md).
69
+
70
+ ## Extension notes (out of first ship)
71
+
72
+ | Host / class | Note |
73
+ |--------------|------|
74
+ | **Buzz / Pi** | Session-first family-2 peers. Implement a dedicated `host-*.md` adapter when scheduled; reuse this duty table. Do not invent full platform abstraction in this cut. |
75
+ | **Warp / Grok Build** | Family-1-adjacent spawn hosts; deposit + AGENTS still own session orientation. Swarm launch adapters are separate from cold-start Skills Index load. |
76
+
77
+ ## Anti-patterns
78
+
79
+ - ⊗ Freestyle host tools first on Deft-shaped intent, then maybe open a skill.
80
+ - ⊗ Treat host skill inventory (`available_skills`, workspace skill folders) as the Directive Skills Index without a bridge.
81
+ - ⊗ Assume IDE deposit behavior on a session-first host that started outside the project root.
82
+ - ⊗ Abstract multi-host portability RFC with zero OpenClaw (or second-family) behavior change.
83
+
84
+ ## Acceptance pointer
85
+
86
+ Issue [#2968](https://github.com/deftai/directive/issues/2968): A3 = this contract; A7 = OpenClaw cold-start in `host-openclaw.md`. First cut closes when both surfaces land and `task verify:openclaw-tier1` stays green.
@@ -0,0 +1,109 @@
1
+ # Human-origin approval + UAT mutation lease (#2944 / #2948 Wave 1)
2
+
3
+ Layer **L1–L2** of the layered authorization stack (epic #2948). Composes with
4
+ `runtimeAuthority` (L3, #1394 / #2711) and does **not** re-implement Shell push/merge
5
+ matchers.
6
+
7
+ Threat model: **aligned agent** confusion — the agent believes self-authored
8
+ xBRIEF/lifecycle/dispatch state is permission. Credential-compromised local-file
9
+ forgery remains #983-class out of scope.
10
+
11
+ ## Defaults
12
+
13
+ | Surface | Default | Notes |
14
+ | --- | --- | --- |
15
+ | UAT lease | inactive | No Wave 1 denials until operator starts UAT |
16
+ | Human-origin grants | none | Minted only via `deft authz:grant` |
17
+
18
+ ## Human-origin grant
19
+
20
+ Stored under `.deft/authz/grants/<id>.json`.
21
+
22
+ Accepted `origin.kind` values:
23
+
24
+ - `operator-cli` (mint path: `deft authz:grant`)
25
+ - `operator-session` (future interactive approval)
26
+ - `human-event` (external human event ref)
27
+
28
+ **Rejected** (never satisfy an implementation-approval gate):
29
+
30
+ - `agent-lifecycle`, `xbrief-status`, `dispatch-envelope`, `allocation-context`,
31
+ `self-asserted`, `agent-authored`
32
+ - any grant with actor `agent` / `agent:*` / `self`
33
+
34
+ Structural binding (not crypto/HMAC):
35
+
36
+ - `scope.planRef`, `repo`, `branch`, `worktree`
37
+ - `scope.surfaces` — path globs (including user-visible UI)
38
+ - `scope.operations` — `edit` \| `push` \| `pr` \| `merge` \| `settings` \| `deployment` \| `issue_mutation`
39
+ - `scope.storyIds` / `issueIds`
40
+ - `scope.cohortId` — **required** for product mutations while UAT is active
41
+ - `semantics.expiresAt` / `singleUse`
42
+
43
+ ## Fail-closed UAT mutation lease
44
+
45
+ Start: `deft authz:uat-start -- --campaign <id>`
46
+ Suspend: `deft authz:uat-suspend`
47
+ Inspect: `deft authz:show`
48
+
49
+ While UAT is **active** (and was started with human-origin provenance):
50
+
51
+ | Attempt | Result without matching fix-cohort grant |
52
+ | --- | --- |
53
+ | Product / UI direct write | **deny** |
54
+ | `git push` / classifiable push MCP | **deny** |
55
+ | `gh pr create` / ready / edit | **deny** |
56
+ | `gh pr merge` / classifiable merge MCP | **deny** |
57
+ | settings / deploy heuristics | **deny** |
58
+ | Test execution (`vitest`, `pnpm test`, …) | **allow** |
59
+ | Issue filing (`gh issue create`) | **allow** |
60
+ | Evidence / defect capture writes (`xbrief/proposed/**`, `**/evidence/**`, `incidents/**`) | **allow** |
61
+
62
+ Approving one named fix cohort **does not** clear the UAT lock or authorize adjacent
63
+ failures or other operations (e.g. edit grant ≠ push).
64
+
65
+ ## Enforcement order (PreToolUse)
66
+
67
+ 1. Ritual / scope / read-only / spawn gates
68
+ 2. **Authz Wave 1** — UAT lease + human-origin grant (`#2944`)
69
+ 3. Runtime authority path + `scopes.edits` / `scopes.push` / `scopes.merge` (#1394 / #2711)
70
+
71
+ Denials name the missing permission and the human action required (typically
72
+ `deft authz:grant -- --cohort <id> --operations … --surfaces …`).
73
+
74
+ Audit appends to `.deft/authz/audit.jsonl` with:
75
+
76
+ `humanApprovalRef`, `approvedScope`, `attemptedOp`, `path`, `result`, `code`, `campaignId`.
77
+
78
+ ## CLI
79
+
80
+ ```bash
81
+ deft authz:show
82
+ deft authz:uat-start -- --campaign uat-2026-07-30
83
+ deft authz:grant -- --operations edit --surfaces 'apps/web/src/**' --cohort fix-defect-12 --stories 2944
84
+ deft authz:uat-suspend
85
+ deft authz:revoke -- grant-…
86
+ ```
87
+
88
+ ## Explicit non-goals (siblings)
89
+
90
+ | Concern | Owner |
91
+ | --- | --- |
92
+ | Shell/MCP push/merge matchers alone | #2711 |
93
+ | Slash-command intent ceiling / human merge | #1193 |
94
+ | Path write fence schema | #516 / #2443 |
95
+ | AFK session-auth / release verbs | #1095 — see `content/contracts/closed-verb-authz.md` (Wave 4; consumes these grants) |
96
+ | HMAC / hardware-keyed grants | non-goal for MVP |
97
+
98
+ ## Wave 4 consumers
99
+
100
+ Release-class closed verbs (`release-cut`, `release-publish`, `release-rollback`)
101
+ evaluate via `evaluateClosedVerb` and accept only:
102
+
103
+ - `DEFT_ALLOW_<VERB>=1` ephemeral bypass, or
104
+ - a **human-origin** grant from this store (templates: `deft authz:grant -- --template release-publish --target <ver>`)
105
+
106
+ They do not mint grants of their own. Walk-away finish-loop product: #871 (Wave 5) —
107
+ `authz:grant --template finish-loop` and `content/contracts/finish-loop.md`.
108
+
109
+ Refs #2948 #2711 #1394 #1378 #2176 #2402 #1095.
@@ -0,0 +1,44 @@
1
+ # Intent ceiling — slash-command containment, hotfix classifier, human merge (#1193)
2
+
3
+ Wave 2 of the layered authorization stack (#2948). Complements human-origin grants (#2944) and runtimeAuthority (#2711 / #1394).
4
+
5
+ ## R1 — Slash-command intent containment
6
+
7
+ When a session is originated by a slash command, that command is the **only** authorized verb for the session.
8
+
9
+ | Surface | Behavior |
10
+ |---------|----------|
11
+ | Env | `DEFT_SESSION_SLASH_VERB` (e.g. `/github-issue`, `/build`) |
12
+ | Preflight | `task xbrief:preflight` fails when the verb is non-implement |
13
+ | Hooks | PreToolUse denies implement/push/merge for non-implement verbs |
14
+ | Pure API | `evaluateIntentCeiling({ sessionVerb, requestedOp })` in `@deftai/directive-core/policy` |
15
+
16
+ **Implement verbs:** `/build`, `/ship`, `/ship-hotfix`, `/swarm`, `/implement` (plus free-text #810 action verbs when no slash provenance).
17
+
18
+ **Non-implement (contained):** `/github-issue`, `/triage`, `/refine`, `/discuss`, `/research`, and unknown stems (fail closed for lifecycle escalation).
19
+
20
+ ## R2 — Hotfix classifier
21
+
22
+ Typed `plan.policy.hotfixCriteria` (`maxLines` default 10, `maxFiles` default 2, `forbiddenPathGlobs`).
23
+
24
+ Pure `evaluateHotfixEligibility(input)`:
25
+
26
+ - **Eligible → propose `hotfix-candidate` only** (agent never promotes to `hotfix`)
27
+ - Pure revert always qualifies
28
+ - Small fix within limits, restores green, no new deps/exports/schema
29
+ - **Never:** refactor, new handler/route, export surface change, forbidden paths (Dockerfile, fly.toml, `.github/workflows/**`, migrations, auth/secrets)
30
+
31
+ ## R3 — Human merge gate
32
+
33
+ Typed `plan.policy.requireHumanMerge` (default **true** when `autoDeployOnMerge` is true).
34
+
35
+ | Surface | Behavior |
36
+ |---------|----------|
37
+ | Merge preflight | `task pr:wait-mergeable-and-merge` refuses agent merge when ON |
38
+ | `verify:branch` | Advisory note when ON |
39
+ | Branch protection | Setup docs: ≥1 human reviewer when ON |
40
+ | Session-start | Disclosure: `[deft policy] Human merge gate is ON …` |
41
+
42
+ **Override:** `task policy:allow-bot-merge -- --confirm` (capability-cost disclosure + audit log) or `DEFT_ALLOW_BOT_MERGE=1`.
43
+
44
+ Inspect: `task policy:show --field=requireHumanMerge` / `--field=hotfixCriteria`.
@@ -0,0 +1,128 @@
1
+ # Path write fence (#516 / #2443 / #2948 Wave 3)
2
+
3
+ Unified **write-scope** enforcement for agents: project path policy and per-story
4
+ `file_scope` share one evaluation model. There is no third parallel `writeScope`
5
+ schema with its own matcher.
6
+
7
+ ## Source of truth
8
+
9
+ | Layer | Where declared | Role |
10
+ | --- | --- | --- |
11
+ | **Project** | `plan.policy.runtimeAuthority` in `xbrief/PROJECT-DEFINITION.xbrief.json` | Session-level `allowPaths` / `denyPaths` + scopes (`edits` / `push` / `merge`) |
12
+ | **Story** | `plan.metadata.swarm.file_scope` on the active running xBRIEF | Per-story allow globs (swarm readiness already uses this list) |
13
+ | **Legacy alias** | `writeScope` on `plan.metadata` or `plan.metadata.swarm` | Read-time normalize to `file_scope` + deny globs only — **not** a second engine |
14
+
15
+ **Evaluation SoT (code):**
16
+
17
+ 1. `resolveWriteFence(projectPolicy, storyFileScope?)` builds one `RuntimeAuthorityPolicy`
18
+ 2. `evaluateRuntimeAuthorityPath` / `evaluateRuntimeAuthorityDirectWrite` decide allow/deny
19
+
20
+ ## Intersection rules
21
+
22
+ - **Empty project `allowPaths` when enabled** → all paths allowed until a story narrows them
23
+ - **Empty story `file_scope`** → project policy only
24
+ - **Story alone** (project `runtimeAuthority.enabled: false`) → story fence still enables path checks for direct writes
25
+ - **Both non-empty** → path must match **project allow** *and* **story file_scope** (AND)
26
+ - **`denyPaths` always win** (project denys + any denys from normalized `writeScope.deny`)
27
+
28
+ ## Runtime enforcement
29
+
30
+ When a fence is active, PreToolUse direct writes (Write / Edit / StrReplace / …) **fail closed**
31
+ for out-of-fence paths after ritual / scope / read-only / human-origin authz gates.
32
+
33
+ Deny reasons are stable and name the fence source:
34
+
35
+ - `write fence project allowPaths (source: project)` or `project+story`
36
+ - `write fence story file_scope (source: story)` or `project+story`
37
+ - `write-fence denyPaths (source: …)`
38
+
39
+ Inspect project policy:
40
+
41
+ ```bash
42
+ deft policy:show --field=runtimeAuthority
43
+ ```
44
+
45
+ ### Active-story seam
46
+
47
+ The hook dispatcher loads `file_scope` from the implementation-eligible active xBRIEF
48
+ path when `inspectActiveScope` reports one. Residual gaps (document, not silent):
49
+
50
+ - Host / worktree cannot identify the active story → story layer omitted; project fence still applies
51
+ - Multiple active artifacts → first preflight-eligible path wins (same as scope gate)
52
+ - Story JSON unreadable → story layer fail-open; project fence still applies
53
+
54
+ Shell/MCP push/merge scopes remain project-only (`runtimeAuthority.scopes`); they are not
55
+ re-scoped by `file_scope`.
56
+
57
+ ## Skill behavior (build / swarm)
58
+
59
+ When a project or active-story fence is set:
60
+
61
+ - **build** and **swarm** workers MUST treat out-of-fence Write/Edit as refused (PreToolUse deny
62
+ or equivalent product check)
63
+ - Prefer declaring intended paths in `plan.metadata.swarm.file_scope` before autonomous loops
64
+ - ⊗ Do not invent a second write-scope schema or dual matcher beside `resolveWriteFence` +
65
+ `evaluateRuntimeAuthority*`
66
+
67
+ ## writeScope alias (compatibility)
68
+
69
+ ```json
70
+ {
71
+ "plan": {
72
+ "metadata": {
73
+ "writeScope": {
74
+ "allow": ["src/**", "tests/**"],
75
+ "deny": [".env", "secrets/**"]
76
+ }
77
+ }
78
+ }
79
+ }
80
+ ```
81
+
82
+ Loaders map this to `file_scope` + deny globs at read time. If both `file_scope` and
83
+ `writeScope.allow` are present, **`file_scope` wins** for the allow list; `writeScope.deny`
84
+ still merges into denyPaths.
85
+
86
+ ## Example
87
+
88
+ ```json
89
+ // PROJECT-DEFINITION
90
+ {
91
+ "plan": {
92
+ "policy": {
93
+ "runtimeAuthority": {
94
+ "enabled": true,
95
+ "allowPaths": ["packages/**", "src/**", "xbrief/**"],
96
+ "denyPaths": [".env", "secrets/**"],
97
+ "scopes": { "edits": true, "push": false, "merge": false }
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ // Active story swarm block
104
+ {
105
+ "plan": {
106
+ "metadata": {
107
+ "swarm": {
108
+ "file_scope": [
109
+ "packages/core/src/policy/**",
110
+ "content/contracts/path-write-fence.md"
111
+ ]
112
+ }
113
+ }
114
+ }
115
+ }
116
+ ```
117
+
118
+ With both set, a write to `packages/core/src/policy/write-fence.ts` is allowed;
119
+ `src/index.ts` is denied (outside story); `secrets/x` is denied (deny wins).
120
+
121
+ ## Related
122
+
123
+ - Contract: `content/contracts/runtime-authority.md` (#1394 / #2711)
124
+ - Human-origin / UAT: `content/contracts/human-origin-authz.md` (#2944)
125
+ - Intent ceiling: `content/contracts/intent-ceiling.md` (#1193)
126
+ - Program: #2948 Wave 3
127
+
128
+ Refs #516, #2443, #2948, #1394.
@@ -1,4 +1,4 @@
1
- # Runtime authority policy (#1394)
1
+ # Runtime authority policy (#1394 / #2711)
2
2
 
3
3
  Typed session-level enforcement under `plan.policy.runtimeAuthority` in `xbrief/PROJECT-DEFINITION.xbrief.json`.
4
4
 
@@ -10,20 +10,58 @@ Typed session-level enforcement under `plan.policy.runtimeAuthority` in `xbrief/
10
10
  | `allowPaths` | `[]` | Empty = allow all paths (when enabled) |
11
11
  | `denyPaths` | `[]` | Deny wins over allow |
12
12
  | `scopes.edits` | `true` | Direct Write/Edit/StrReplace tools |
13
- | `scopes.push` | `false` | Schema only Shell matcher TODO |
14
- | `scopes.merge` | `false` | Schema only Shell matcher TODO |
13
+ | `scopes.push` | `false` | Shell/Bash `git push` and classifiable MCP push tools (#2711) |
14
+ | `scopes.merge` | `false` | Shell/Bash `gh pr merge` and classifiable MCP merge tools (#2711) |
15
15
 
16
16
  ## Path globs
17
17
 
18
18
  Gitignore-style globs via the shared `matchPath` helper (`src/**`, `**/AGENTS.md`, etc.). Paths are normalized to project-relative POSIX before matching.
19
19
 
20
+ ## Unified write fence (#516 / #2443 / #2948 Wave 3)
21
+
22
+ Path checks for direct writes go through **one** evaluation SoT:
23
+
24
+ 1. `resolveWriteFence(projectPolicy, storyFileScope?)` intersects this project policy with the active story’s `plan.metadata.swarm.file_scope` (optional `writeScope` alias normalizes at read-time — not a second engine)
25
+ 2. `evaluateRuntimeAuthorityPath` / `evaluateRuntimeAuthorityDirectWrite` decide allow/deny
26
+
27
+ Rules: empty project `allowPaths` when enabled = all paths until story narrows; empty story scope = project only; **denyPaths always win**; when both allow layers are non-empty, a path must match **both**. Full contract: `content/contracts/path-write-fence.md`.
28
+
20
29
  ## Evaluation order (PreToolUse)
21
30
 
22
31
  1. Ritual / scope / read-only / spawn gates (existing #2438 / #1185 stack)
23
- 2. Runtime authority path + `scopes.edits` (this policy)
32
+ 2. **Human-origin authz / UAT lease** (#2944 Wave 1) — when UAT is active, product mutations require a named fix-cohort human-origin grant (see `content/contracts/human-origin-authz.md`). Composes with this policy; does not re-own Shell matchers.
33
+ 3. Runtime authority path + story write fence + `scopes.edits` for direct-write tools (`resolveWriteFence` → `evaluateRuntimeAuthorityDirectWrite`)
34
+ 4. Runtime authority `scopes.push` / `scopes.merge` for Shell/Bash and classifiable MCP tools (#2711)
24
35
 
25
36
  Policy load failures fail open (host crash behavior unchanged).
26
37
 
38
+ ## Shell / MCP classification (#2711)
39
+
40
+ When `enabled: true`:
41
+
42
+ | Classified as | Examples | Scope |
43
+ | --- | --- | --- |
44
+ | **push** | `git push …`, `git -C <path> push`, env-prefixed `FOO=1 git push`, after `&&` / `;` / `\|` | `scopes.push` |
45
+ | **merge** | `gh pr merge …`, `gh.exe pr merge …` | `scopes.merge` |
46
+ | **MCP merge** | tool names matching `merge_pull_request`, `pr_merge`, … | `scopes.merge` |
47
+ | **MCP push** | tool names matching `git_push`, `push_branch`, … | `scopes.push` |
48
+
49
+ **Fail open (allow)** when:
50
+
51
+ - the tool is Shell/MCP but the command/tool name is **not** classifiable as push or merge (e.g. `git status`, unrelated MCP tools)
52
+ - the host payload omits a command string
53
+ - policy load throws
54
+
55
+ **Install note:** agent-host PreToolUse deposits include a Shell/Bash matcher (`SHELL_HOOK_MATCHER`) so classifiable shell ops reach `hook:dispatch` (#2711). MCP tools are classified when the host invokes the hook for that tool name; hosts that never fire PreToolUse for MCP remain a residual gap.
56
+
57
+ **Not enforced** (document as residual host gap):
58
+
59
+ - WebSearch / non-shell non-MCP tools
60
+ - Obfuscated shell (`bash -c "$(echo Z2l0IHB1c2g=|base64 -d)"`) — not a complete substitute for Tier-2 git hooks
61
+ - Every MCP host spelling — only patterns above; unknown MCP tools fail open
62
+ - MCP tools on hosts that do not install/subscribe a PreToolUse matcher for those tool names
63
+ Tier-2 git hooks remain authoritative for commit/push on the working tree. This layer is session-time PreToolUse only.
64
+
27
65
  ## Inspection
28
66
 
29
67
  ```bash
@@ -47,8 +85,6 @@ deft policy:show --field=runtimeAuthority
47
85
  }
48
86
  ```
49
87
 
50
- ## Deferred (host gap)
51
-
52
- - Shell/Bash `git push`, `gh pr merge`, MCP mutations — not on the direct-write PreToolUse matcher today. `scopes.push` / `scopes.merge` are reserved for a follow-on Shell matcher (#1394 phase 2).
88
+ With that shape, a PreToolUse `Bash` / `Shell` invocation of `git push` or `gh pr merge` is denied when the matching scope is `false`.
53
89
 
54
- Refs #2437 Core T1 Wave C.
90
+ Refs #2437 Core T1 Wave C residual, #2711, #2948 Wave 0; Wave 3 path fence #516 / #2443 — `content/contracts/path-write-fence.md`.
@@ -141,3 +141,7 @@ Full command reference for every triage and cache verb lives in [`commands.md`
141
141
  <!-- TODO: Cover AGENTS.md, skill routing, Warp Drive integration, and cloud agent dispatch -->
142
142
 
143
143
  **OpenClaw:** If your agent host is OpenClaw (persistent-memory agents, Control UI, `sessions_spawn`), read [openclaw-agent-host.md](./openclaw-agent-host.md) for the host mental model, executable babysit path (installed skills), and the epic babysit → `sessions_spawn` Approach 1 expectation. Skill gate text remains in `deft-directive-review-cycle` / `deft-directive-swarm` — the host doc only points.
144
+
145
+ **Writing:** For docs, issues, and PR prose, follow [writing-ste100.md](./writing-ste100.md) (short controlled English; #2927).
146
+
147
+ **Opt out:** To mark a repo as not using Directive, add root [`.no-deft-directive`](./no-deft-directive.md) (#2926). Tools skip install and session ritual when that file is present.
@@ -0,0 +1,87 @@
1
+ # Opt out with `.no-deft-directive`
2
+
3
+ Some projects should not use Deft Directive. Use a **root file flag** so tools and agents stop offering install, session ritual, and setup.
4
+
5
+ Tracker: [#2926](https://github.com/deftai/directive/issues/2926).
6
+
7
+ ## Filename and location
8
+
9
+ ```text
10
+ .no-deft-directive
11
+ ```
12
+
13
+ - **Exact name:** lowercase `.no-deft-directive`
14
+ - **Location:** project / workspace **root only** (the root the agent or CLI opened)
15
+ - **Content:** empty file or a short `#` comment. Presence is the flag. No schema.
16
+
17
+ ~ Commit the flag. Opt-out is a project decision other clones should see.
18
+
19
+ ## Behavior
20
+
21
+ | Condition | Behavior |
22
+ |-----------|----------|
23
+ | Flag **present** | Directive **off** for this project. Do not install. Do not run session ritual (CLI `session:start` **and** installed host SessionStart hooks). Do not offer setup. |
24
+ | Flag **absent**, no deposit | Tools **may** ask whether to install. On decline, create the flag. On enable, install and do **not** create the flag. |
25
+ | Operator stops using DD | Create `.no-deft-directive`. Do **not** auto-delete an existing deposit. |
26
+ | Operator starts using DD | Remove the flag, then run `directive init` or `directive update` so install is present. |
27
+
28
+ One-line message when tools honor the flag:
29
+
30
+ ```text
31
+ Directive disabled via `.no-deft-directive`
32
+ ```
33
+
34
+ ## Inconsistent state (flag + deposit)
35
+
36
+ If **both** `.no-deft-directive` and a deposit (`.deft/core`) exist:
37
+
38
+ - **Doctor:** **warns** and exits dirty (exit 1)
39
+ - **`session:start`:** short-circuits with the disabled message plus the inconsistency warning (exit 1)
40
+ - **Host SessionStart hooks:** skip ritual bookkeeping (allow with `session-start-disabled`); never write `.deft/last-session.json` under opt-out
41
+ - **`init` / `update`:** **fail closed** (no scaffold/refresh)
42
+
43
+ **Product choice (v1):** warn in doctor; fail closed on mutating install paths (`warn-and-fail-closed`).
44
+
45
+ Fix by either:
46
+
47
+ 1. Removing the flag if the project should use Directive, or
48
+ 2. Removing the deposit if opt-out is intentional (explicit cleanup only — tools do not delete `.deft/` when creating the flag)
49
+
50
+ ## Local flag wins (v1)
51
+
52
+ The root flag **wins locally** over ambient trusted-org / product-signal force-on. Org defaults must not override a committed opt-out without an explicit product decision beyond v1.
53
+
54
+ ## CLI helpers (optional)
55
+
56
+ ```bash
57
+ directive policy:disable-directive [--project-root .] [--note "reason"]
58
+ directive policy:enable-directive [--project-root .]
59
+ ```
60
+
61
+ - `disable-directive` creates the flag (optional `--note` becomes a `#` comment)
62
+ - `enable-directive` removes the flag and tells you to ensure install
63
+
64
+ Presence detection is the core contract. CLI helpers are convenience only.
65
+
66
+ ## Setup skill contract
67
+
68
+ When `deft-directive-setup` runs:
69
+
70
+ 1. ! Check for root `.no-deft-directive` **before** any install or interview phase
71
+ 2. ! If present → stop with `Directive disabled via \`.no-deft-directive\``
72
+ 3. ? If absent and no deposit → ask the human whether to use Directive
73
+ 4. ! On decline → create `.no-deft-directive` and stop
74
+ 5. ! On enable / “start using DD” → remove the flag and ensure install
75
+
76
+ ## Non-goals / follow-ups
77
+
78
+ - ⊗ Auto-delete `.deft/` when creating the flag
79
+ - ⊗ Org-wide ban (this is per-project filesystem only)
80
+ - ⊗ Nested monorepo package roots (v1 is workspace root only; multi-package monorepo rules are a follow-up)
81
+ - ⊗ Host personality / who may approve gates
82
+
83
+ ## Related
84
+
85
+ - [getting-started.md](./getting-started.md) — install and first project
86
+ - [product-signal.md](./product-signal.md) — optional partner signal (defaults off; flag still wins locally)
87
+ - `session:start`, `doctor`, `directive init`, `directive update`
@@ -33,7 +33,7 @@ OpenClaw’s native background-spawn tool is **`sessions_spawn`**. Operator inte
33
33
 
34
34
  ! Gate tiers, allowed register primitives, dispatch detection, and review Approaches are defined **only** in shipped skill + engine text:
35
35
 
36
- - Swarm capability matrix + launch path: [`skills/deft-directive-swarm/SKILL.md`](../skills/deft-directive-swarm/SKILL.md) (Phase 3 runtime detection / launch adapter).
36
+ - Swarm capability matrix + launch path: [`skills/deft-directive-swarm/SKILL.md`](../skills/deft-directive-swarm/SKILL.md) (thin skill: detect + route table) and OpenClaw adapter [`skills/deft-directive-swarm/references/host-openclaw.md`](../skills/deft-directive-swarm/references/host-openclaw.md) (Step 2f launch, worktree-before-spawn #2929, phase handoff #2934, parent-monitor tool-first after announce #2943). Skill text remains source of truth.
37
37
  - PR babysit / shepherd / watch: [`skills/deft-directive-review-cycle/SKILL.md`](../skills/deft-directive-review-cycle/SKILL.md) → **Review Monitoring**.
38
38
  - Provider-neutral dispatch envelope: [`templates/agent-prompt-preamble.md`](../templates/agent-prompt-preamble.md).
39
39
  - Review-owner lease: `task review-monitor:register` / `task verify:review-monitor` (only `--platform-primitive` values those commands accept in your install).
@@ -117,6 +117,36 @@ OpenClaw agents often act under a **bot / service identity** (e.g. `ape-deft`-cl
117
117
 
118
118
  ---
119
119
 
120
+
121
+ ---
122
+
123
+ ## Swarm on OpenClaw (#2929 / #2934 / #2943)
124
+
125
+ ! For **parallel** swarm leaves on OpenClaw:
126
+
127
+ 1. Create worktrees (or consume a worktree-map) **before** any `sessions_spawn`.
128
+ 2. Set each worker cwd to that worktree — not the shared repo root.
129
+ 3. Prefer `task swarm:launch` + manifest; DIY multi-leaf `sessions_spawn` without worktree prep is forbidden.
130
+
131
+ ! After a coding cohort completes, dispatch the next phase with a **real tool call in the same turn**, or write explicit terminal status (`blocked` / `awaiting-human` / `done`). Do not end on narrative-only “I will spawn…”.
132
+
133
+ ### Parent-monitor after `subagent_announce` (#2943)
134
+
135
+ OpenClaw parents can lock into a **text-only repetition hang** after thin leaf completions: the model regenerates the same “checking worktrees / open PRs next” sentence with **zero tool calls** until length cap or abort. Subagents may still be healthy; only the parent appears hung.
136
+
137
+ ! After any leaf completion event (`subagent_announce` / parent-push completion), the parent’s **first response** MUST be **tool-first** or **yield**:
138
+
139
+ 1. **Tool-first ground-truth batch** — one same-turn tool batch that inspects reality (`gh` PR/issue status, `git` / worktree status, or file/xBRIEF state), **or**
140
+ 2. **`sessions_yield`** (or host equivalent yield) — leave the turn steerable without narrating unfinished work.
141
+
142
+ ⊗ Open the first response after announce with multi-sentence progress-only prose (“Two leaves look unfinished…”, “Checking worktrees next…”, “Implementing both myself…”) and **zero** tool calls / yield.
143
+
144
+ ! **Thin DONE = failed leaf:** a completion without PR URL / merge evidence (and without a structured `BLOCKED` / `FAILED` terminal) is **not** success. Treat as failed: re-dispatch or take over after the ground-truth batch. Do not celebrate thin DONE as shipped.
145
+
146
+ ~ Prefer structured completion fields when present (`prUrl`, `mergeStatus`, `emptyDiff`); never model free-text thin DONE as success.
147
+
148
+ Full rules: [`skills/deft-directive-swarm/references/host-openclaw.md`](../skills/deft-directive-swarm/references/host-openclaw.md), thin swarm SKILL hard-gates, and [`templates/agent-prompt-preamble.md`](../templates/agent-prompt-preamble.md) §11. This page does not fork a second source of truth.
149
+
120
150
  ## Anti-patterns
121
151
 
122
152
  - ⊗ Main-session `gh` poll + **cron** as the default babysit path when the installed skill offers a Tier 1 / background monitor.
@@ -124,6 +154,8 @@ OpenClaw agents often act under a **bot / service identity** (e.g. `ape-deft`-cl
124
154
  - ⊗ Treating `content/platforms/` hardware packs as the home for agent-host OpenClaw guidance.
125
155
  - ⊗ Substituting host-native review theater for `deft-directive-review-cycle` on Deft-managed repos.
126
156
  - ⊗ Claiming this doc alone makes `sessions_spawn` a shipped register/matrix primitive — that is epic skill/engine work (#2875 / #2876).
157
+ - ⊗ Multi-sentence progress-only first response after `subagent_announce` with zero tools / yield (#2943 text-repetition hang).
158
+ - ⊗ Treating thin DONE (no PR URL / merge evidence) as success (#2943).
127
159
 
128
160
  ---
129
161
 
@@ -134,4 +166,5 @@ OpenClaw agents often act under a **bot / service identity** (e.g. `ape-deft`-cl
134
166
  - [skill-pin-policy.md](./skill-pin-policy.md) — always-pin process skills (includes review-cycle)
135
167
  - [`skills/deft-directive-review-cycle/SKILL.md`](../skills/deft-directive-review-cycle/SKILL.md)
136
168
  - [`skills/deft-directive-swarm/SKILL.md`](../skills/deft-directive-swarm/SKILL.md)
169
+ - [`skills/deft-directive-swarm/references/host-openclaw.md`](../skills/deft-directive-swarm/references/host-openclaw.md) — OpenClaw swarm adapter
137
170
  - [`templates/agent-prompt-preamble.md`](../templates/agent-prompt-preamble.md)
@@ -6,6 +6,8 @@ Phase 1 consented product-improvement signal under epic #2603 (#2693). Defaults
6
6
 
7
7
  Trusted-org repos (`deftai/*`, plus `DEFT_VALUE_AUTOENABLE_ORGS`) receive a **one-time** install/upgrade force-on (#2822): local value feedback and product-signal enable flip ON on the next `directive update`, with a durable `.deft-cache/org-force-on-v2822.json` marker so later intentional opt-out is not fought forever. Outbound product signal still requires personal consent (D17).
8
8
 
9
+ **Verify-on-skip (#2903):** the marker stores the pre-migration policy snapshots (key-order independent). If `PROJECT-DEFINITION` force-on is discarded (working-tree-only write lost beside a deposit PR, `git restore`, branch without PD) while the marker remains, the next `directive update` sees current typed blocks still equal those snapshots and **re-applies** force-on. Snapshot equality is company policy: restoring the exact pre-migration disabled shape is treated as incomplete migration (not a durable opt-out). An intentional post-migration disable must **differ** from the previous snapshot (and from the force-on shape), or use `task policy:clear-value-feedback`, or root `.no-deft-directive`. Outbound product signal still requires personal consent (D17) even when local enable is forced on. Manual recovery remains `rm -f .deft-cache/org-force-on-v2822.json && deft update`, then commit `xbrief/PROJECT-DEFINITION.xbrief.json`.
10
+
9
11
  ```bash
10
12
  task product-signal:enable -- --confirm
11
13
  task policy:show -- --field=productSignal