@deftai/directive-content 0.89.0 → 0.90.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/commands.md +50 -2
- package/contracts/host-lifecycle-duties.md +10 -0
- package/docs/inter-run-learning.md +27 -0
- package/docs/openclaw-agent-host.md +43 -3
- package/events/README.md +1 -1
- package/events/registry.json +36 -0
- package/package.json +1 -1
- package/patterns/tool-call-taxonomy.md +73 -0
- package/skills/deft-directive-swarm/references/core-phase-4.md +20 -0
- package/skills/deft-directive-swarm/references/host-openclaw.md +4 -0
- package/tasks/engine.yml +1 -0
- package/tasks/lifecycle.yml +14 -1
- package/tasks/session.yml +11 -0
package/commands.md
CHANGED
|
@@ -237,7 +237,7 @@ When the workflow needs an Approach 1 monitor, scope the Cursor leaf `stop-at: p
|
|
|
237
237
|
- Repair missing/drifted entries: `deft update`.
|
|
238
238
|
- **Refresh and opt-out (#2790, #2752):** Upgrade `@deftai/directive`, then run `deft update` to refresh all four deposits to the fast path; do not hand-edit host hook files. Set `plan.policy.hostHooks.<host>` to `false` only when you deliberately need to disable a host's Tier-1 enforcement — it is not the performance fix. When a host is opted out, `deft update` / `directive init` skip creating or re-merging Directive-managed hook entries for that host; if a prior deposit left managed entries in the file, the next update strips only those entries and preserves unrelated settings. Inspect with `deft policy:show --field=hostHooks`. Doctor and `verify:hooks-installed --scope=agent` treat opted-out hosts as healthy — they do not recommend `deft update` to repair them.
|
|
239
239
|
- **Claude matcher scope:** Once `.claude/settings.json` hooks are loaded, Claude's `PreToolUse` matcher keys on tool names (`Edit`, `Write`, …), not target paths — matched tools can be gated for the whole session, including writes outside the project tree. Opt out of Claude hook deposit when that posture is unwanted.
|
|
240
|
-
- **Compact re-arm (#2113):** Cursor `preCompact` and Claude/Grok `PreCompact`/`PostCompact` call `deft-hook --event session.compact` to mark the gated session ritual stale after context compaction/resume
|
|
240
|
+
- **Compact re-arm (#2113 / #2992 / #2993):** Cursor `preCompact` and Claude/Grok `PreCompact`/`PostCompact` call `deft-hook --event session.compact` to mark the gated session ritual stale after context compaction/resume (`rearm_needed`). Prefer `deft session:ready` (#2993) as the one-shot recovery path. Multi-step remains valid: `deft session:start --rearm` (preferred when worktree/HEAD allow) or full `deft session:start`, then `deft verify:session-ritual -- --tier=gated`. Codex has no native compact hook — operators must re-run the mutation ritual manually after compaction.
|
|
241
241
|
- Codex project hooks are trust-gated by Codex. Directive verifies only that the registrations are structurally current; after an install or changed hook hash, open `/hooks` in Codex and review/approve the project hook commands. Runtime trust cannot be inferred from the file alone.
|
|
242
242
|
- Directive writes only `.codex/hooks.json`; it does not parse or modify `.codex/config.toml`. Codex can also load inline hooks from `config.toml`, so avoid defining duplicate Directive commands there or they may run more than once. See the [Codex hooks documentation](https://learn.chatgpt.com/docs/hooks).
|
|
243
243
|
- The P0 hook slice does not classify shell-mediated *file* writes, richer unified-exec calls, or WebSearch by default. **Runtime authority (#1394 / #2711)** adds opt-in path allow/deny lists and graduated `scopes` (`edits`, `push`, `merge`) under `plan.policy.runtimeAuthority` — inspect with `deft policy:show --field=runtimeAuthority`. When `enabled: true`, PreToolUse denies classifiable direct-write targets outside `allowPaths` or matching `denyPaths` after ritual/scope/read-only gates; `scopes.edits` gates all direct writes. `scopes.push` / `scopes.merge` deny classifiable Shell/Bash (`git push`, `gh pr merge`) and classifiable MCP push/merge tool names; unclassifiable shell/MCP calls fail open (see `content/contracts/runtime-authority.md`). **Unified path write fence (#516 / #2443 / #2948 Wave 3):** PreToolUse also intersects project allow/deny with the active story’s `plan.metadata.swarm.file_scope` via `resolveWriteFence` (single evaluation SoT; optional `writeScope` alias normalizes at read-time only). Full contract: `content/contracts/path-write-fence.md`.
|
|
@@ -261,9 +261,14 @@ Full always-on contract for the interactive session-start ritual and its gated v
|
|
|
261
261
|
### Mutable ritual (mutation posture)
|
|
262
262
|
|
|
263
263
|
- ! On **mutation** session start, run `deft session:start` (or `task session:start` in framework source) after loading AGENTS.md. Records quick-tier ritual in `.deft/ritual-state.json`: alignment confirmation, branch-policy disclosure, `deft verify:tools` guidance, default-branch sync warnings, and `deft triage:welcome` one-liner. State is worktree- and HEAD-bound; stale after `plan.policy.sessionRitualStalenessHours` hours (default 4).
|
|
264
|
-
-
|
|
264
|
+
- ! **Hot path latency (#2991):** by default, mutation `session:start` does **not** block ritual-state write on optional network. It skips the npm release-availability probe and triage cache empty-hydrate / self-heal (`ensureTriageCacheHydrated` / `maybeSelfHealCache`). Targets (operator-facing, not CI-hard): warm hot path typically under a few seconds once tools are on PATH; cold path dominated by local `verify:tools` and git, usually well under ~30s when optional network is off. Empty-cache GitHub fetch-all and npm `view` previously accounted for multi-minute hangs in the WWYSYDH pilot — those stay off the critical path unless opted in.
|
|
265
|
+
- ! **Cold vs re-arm ceremony tiers (#2992):** default `session:start` is the **cold** (full) path. After age staleness or compact re-arm (#2113) on the **same worktree** with continuous HEAD and previously-passing quick steps, prefer `deft session:start --rearm` (alias `--tier=rearm`) to refresh the ritual clock + HEAD/worktree bind without `verify:tools`, triage welcome, release probe, or staleness tickler. Full cold remains required for missing/invalid state, worktree change, discontinuous HEAD, first install, or failed/missing quick steps. Compact marks `rearm_needed`; PreToolUse denial and inspect/verify messages prefer re-arm recovery when cold is unnecessary.
|
|
266
|
+
- ? Opt into optional network: `deft session:start -- --with-network` or `DEFT_SESSION_START_NETWORK=1`. When enabled, the bounded release-availability probe runs against the public npm registry (skips framework source checkouts, non-release pins, and `DEFT_NO_NETWORK=1`; identical latest-version notices throttle for 24 hours in `xbrief/.triage-cache/release-availability-state.json`). Default-mode triage welcome then also hydrates/self-heals the triage cache. This is separate from `deft doctor`, whose bare and gated invocations remain offline by default (#2182). Refs #1692 / #2991. Re-arm never runs optional network.
|
|
267
|
+
- ~ `session:start --json` includes `steps[]` with `name` + `duration_ms` for major phases (`alignment`, `branch_policy`, `verify_tools`, `triage_welcome`, `release_probe`, `ritual_write`), plus total `duration_ms`, `optional_network`, and `ceremony_tier` (`cold` | `rearm`). Skipped optional steps report `skipped: true` and `duration_ms: 0`. Use this for attribution when investigating ceremony wall-clock.
|
|
268
|
+
- ~ **Process-cost events (#2994):** on mutation `session:start` completion (cold or re-arm), Directive appends a local `session:start` behavioral event to `.deft-cache/events.jsonl` with `ceremony_tier`, `duration_ms`, `exit_code`, and optional `steps[]` (same labels as `--json`). When PreToolUse denies for `ritual-not-ready`, a local `session:ritual-blocked` event records `tool_name`, `code`, and optional `recovery_tier` / `detail`. Always-on best-effort (never blocks ceremony or deny path); not gated on `valueFeedback`; **no remote upload** (Product Insights #2603 is a separate opt-in). See § Process-cost events below.
|
|
265
269
|
- ~ At safe idle points (clean tree, no in-flight story), mutation session start and `deft scope:complete` may also run the staleness tickler: an interactive, consent-based offer to upgrade Directive (`npm i -g @deftai/directive@latest`) and/or migrate xBRIEF (`deft migrate:xbrief`). Escalation tiers, snooze windows, and opt-out live under `plan.policy.stalenessTickler` — inspect with `deft policy:show --field=stalenessTickler`. State persists in `xbrief/.triage-cache/staleness-tickler-state.json`. Skips framework source checkouts, dirty trees, CI/headless (`DEFT_SESSION_RITUAL_SKIP=1`), and typed opt-out. Refs #2488 / #2489.
|
|
266
270
|
- ! Before any code-writing tool call or `start_agent` implementation dispatch, run `deft verify:session-ritual -- --tier=gated`. Gated tier fails closed unless quick-tier state is fresh; lazily records `deft doctor` and `deft verify:cache-fresh` entrypoints. Step 0 of the pre-`start_agent` gate stack.
|
|
271
|
+
- ! **One-shot recovery (#2993):** when PreToolUse denies writes for a stale/missing gated ritual, run `deft session:ready` (or `task session:ready`). It composes `session:start` (only when quick-tier is not green) + `verify:session-ritual -- --tier=gated` + `cache fetch-all --force` when `cache_fresh` is the remaining blocker, then re-verifies. Idempotent fast path when gated inspect is already fresh (no unnecessary fetch-all). Flags: `--json`, `--repo OWNER/NAME`, `--with-network` (forwarded to session:start). Prefer this over juggling the multi-step recovery sequence under hook pressure.
|
|
267
272
|
- ? Postpone with `deft session:start -- --defer step=reason` (`alignment`, `branch_policy`, `triage_welcome`, `doctor`, `cache_fresh`).
|
|
268
273
|
- Headless workers / CI MAY set `DEFT_SESSION_RITUAL_SKIP=1`; verifier exits 0 but warns when bypass hides failure.
|
|
269
274
|
- ⊗ Self-report ritual complete without fresh `deft session:start` state; ⊗ bypass `deft verify:session-ritual` before implementation dispatch; ⊗ reorder/skip/merge ritual tiers without operator override.
|
|
@@ -288,6 +293,23 @@ flowchart TD
|
|
|
288
293
|
|
|
289
294
|
---
|
|
290
295
|
|
|
296
|
+
## Process-cost events (#2994)
|
|
297
|
+
|
|
298
|
+
Local ceremony cost signal for WWYSYDH / weekly process rollups. Emits to `.deft-cache/events.jsonl` only (same ledger as other behavioral events). Does **not** require Product Insights (#2603).
|
|
299
|
+
|
|
300
|
+
| WWYSYDH / ceremony label | Event name | When | Key payload fields |
|
|
301
|
+
|---|---|---|---|
|
|
302
|
+
| Session start (cold) | `session:start` | Mutation `session:start` cold path finishes | `ceremony_tier=cold`, `duration_ms`, `exit_code`, `steps[]` |
|
|
303
|
+
| Session re-arm | `session:start` | `session:start --rearm` finishes | `ceremony_tier=rearm`, `duration_ms`, `exit_code`, `steps[]` |
|
|
304
|
+
| PreToolUse ritual deny | `session:ritual-blocked` | Hook blocks write/spawn because gated ritual is not ready | `tool_name`, `code=ritual-not-ready`, `recovery_tier` (`cold`\|`rearm`) |
|
|
305
|
+
| Per-step wall-clock | (field on `session:start`) | Same emit as session start | `steps[].name` + `steps[].duration_ms` (`alignment`, `branch_policy`, `verify_tools`, `triage_welcome`, `release_probe`, `ritual_write`) |
|
|
306
|
+
|
|
307
|
+
CLI mirror (no JSONL required): `deft session:start --json` already exposes the same `steps` / `duration_ms` / `ceremony_tier` fields for one-shot inspection.
|
|
308
|
+
|
|
309
|
+
Registry: `content/events/registry.json`. Helper: `packages/core/src/session/process-cost.ts`.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
291
313
|
## Framework behavioral events (#635 / #2631)
|
|
292
314
|
|
|
293
315
|
Review-cycle merge-gate approval is recorded as a structural artifact, not prose-only.
|
|
@@ -299,6 +321,32 @@ Writes a `plan:approved` record to `.deft-cache/events.jsonl` with repository (d
|
|
|
299
321
|
|
|
300
322
|
---
|
|
301
323
|
|
|
324
|
+
## Lifecycle folder stats (#2995)
|
|
325
|
+
|
|
326
|
+
Local, offline inventory of existing `xbrief/` (or legacy `vbrief/`) lifecycle folders `{proposed,pending,active,completed,cancelled}/` for weekly process rollups (WWYSYDH Section C). No network.
|
|
327
|
+
|
|
328
|
+
```bash
|
|
329
|
+
deft lifecycle:stats --since=7d
|
|
330
|
+
deft lifecycle:stats --since=7d --json
|
|
331
|
+
task lifecycle:stats -- --since=7d --json
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
| Field | Folder semantics |
|
|
335
|
+
|---|---|
|
|
336
|
+
| `promoted` | Currently in `pending/`, event time inside `--since` window |
|
|
337
|
+
| `activated` | Currently in `active/`, event time inside window |
|
|
338
|
+
| `completed` | Currently in `completed/` with status completed (or unset), event time inside window |
|
|
339
|
+
| `cancelled_or_failed` | Currently in `cancelled/`, or `completed/` with status `failed`, event time inside window |
|
|
340
|
+
| `still_active` | Snapshot of all briefs in `active/` (not filtered by `--since`) |
|
|
341
|
+
|
|
342
|
+
**Event time:** most recent of `plan.metadata.completedAt`, `plan.updated`, and `xBRIEFInfo`/`vBRIEFInfo`.`updated`; else file mtime. Window is `[as_of - since, as_of]`.
|
|
343
|
+
|
|
344
|
+
**Limitation:** counts are **current-folder membership**, not full transition history. A brief promoted then activated in the same week appears under `activated` / `still_active`, not `promoted`. Default `--since` is `7d` (`24h`, `1w`, ISO-8601 durations accepted).
|
|
345
|
+
|
|
346
|
+
`--json` includes the same counts plus `folder_totals`, `window_start` / `as_of`, and a `semantics` object documenting the definitions above.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
302
350
|
## Backlog Triage And Cache Tasks
|
|
303
351
|
|
|
304
352
|
User-facing surface for the Phase 0 triage workflow and the unified content cache. These commands let agents work an existing backlog locally without repeatedly draining shared GitHub rate limits.
|
|
@@ -67,6 +67,16 @@ OpenClaw cold-start steps live in the swarm host adapter (source of truth for sp
|
|
|
67
67
|
|
|
68
68
|
Operator map (non-authoritative discovery): [`../docs/openclaw-agent-host.md`](../docs/openclaw-agent-host.md).
|
|
69
69
|
|
|
70
|
+
### OpenClaw pin wire (doctor) (#3001)
|
|
71
|
+
|
|
72
|
+
Session-first hosts still need a **bridge** from the installed content package into the host workspace skills root. On OpenClaw:
|
|
73
|
+
|
|
74
|
+
- ! `deft doctor` detects missing always-pins under `$OPENCLAW_STATE_DIR/workspace/skills` or `~/.openclaw/workspace/skills` when OpenClaw signals are present.
|
|
75
|
+
- ! `deft doctor --fix` deposits/links the four always-pins (build, pre-pr, review-cycle, swarm) into that main skills root (symlink preferred; copy fallback). Non-destructive of other user skills.
|
|
76
|
+
- ⊗ Rewrite every `workspace-*` crew seat by default — multi-seat only with `deft doctor --fix --openclaw-all-agents`.
|
|
77
|
+
|
|
78
|
+
Full operator steps: [`../docs/openclaw-agent-host.md`](../docs/openclaw-agent-host.md) § Wire skills into OpenClaw workspace.
|
|
79
|
+
|
|
70
80
|
## Extension notes (out of first ship)
|
|
71
81
|
|
|
72
82
|
| Host / class | Note |
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Inter-run learning surface
|
|
2
|
+
|
|
3
|
+
**Load when:** designing or implementing cross-session agent memory, hot/cold budgets, frozen snapshots, or retargeting memory pattern issues under epic #2741.
|
|
4
|
+
|
|
5
|
+
Legend (RFC2119): `!`=MUST, `~`=SHOULD, `⊗`=MUST NOT.
|
|
6
|
+
|
|
7
|
+
## Pointer
|
|
8
|
+
|
|
9
|
+
Canonical contract (Wave 0 design for [#2742](https://github.com/deftai/directive/issues/2742), epic [#2741](https://github.com/deftai/directive/issues/2741)):
|
|
10
|
+
|
|
11
|
+
**[docs/analysis/2026-07-31-inter-run-learning-surface.md](../../docs/analysis/2026-07-31-inter-run-learning-surface.md)**
|
|
12
|
+
|
|
13
|
+
That note inventories Directive memory SoTs (`USER.md` Personal, lessons/packs, triage cache, session ritual, decision/continue), defines **hot / cold / operator-gated** tiers with freeze and budget rules, lists non-goals, and retargets #688, #978, #832–#835, and #479.
|
|
14
|
+
|
|
15
|
+
## Rules (discovery only)
|
|
16
|
+
|
|
17
|
+
- ! Prefer the design note vocabulary over free-floating “agent-memory contracts” or Mem0-default RAG for Directive core.
|
|
18
|
+
- ! Attach Wave 1+ pattern work (#832–#834, #835, #479) to the tiers and SoTs in the design note.
|
|
19
|
+
- ⊗ Revive `x-vbrief/agent-memory` / `swarm/agent-memory.md` (#2700 solution shape abandoned).
|
|
20
|
+
- ⊗ Implement mid-session mutable always-in hot memory without freeze-at-session-start.
|
|
21
|
+
|
|
22
|
+
## Related
|
|
23
|
+
|
|
24
|
+
- Session ritual: `content/commands.md` § Session-start ritual
|
|
25
|
+
- Continue checkpoints: `content/resilience/continue-here.md`
|
|
26
|
+
- Prompt assembly (freeze mechanism): `content/patterns/prompt-assembly-layer-ordering.md`
|
|
27
|
+
- Skills Index: `REFERENCES.md` → When Managing Context or Long Tasks
|
|
@@ -111,12 +111,50 @@ OpenClaw agents often act under a **bot / service identity** (e.g. `ape-deft`-cl
|
|
|
111
111
|
|
|
112
112
|
1. Install / refresh Directive like any other host ([QUICK-START.md](../QUICK-START.md), `directive init` / `directive update`).
|
|
113
113
|
2. Confirm skills resolve under the deposit (consumer: `.deft/core/.agents/skills/…`; framework checkout: `content/skills/…`).
|
|
114
|
-
3.
|
|
115
|
-
4.
|
|
116
|
-
5.
|
|
114
|
+
3. **Wire always-pin skills into the OpenClaw workspace** (see next section) so session `available_skills` can load cold-start paths.
|
|
115
|
+
4. On first PR shepherding request, open **`deft-directive-review-cycle`** and follow its Review Monitoring section for **your** install. Remember the epic expectation: OpenClaw → Approach 1 via `sessions_spawn` once skill wiring ships (#2875 / #2876).
|
|
116
|
+
5. For multi-story parallel work, follow **`deft-directive-swarm`** — do not hand-roll worktree orchestration outside the skill.
|
|
117
|
+
6. Keep CHANGELOG / xBRIEF / branch gates the same as on Cursor or Warp; the host changes the **spawn surface**, not the Directive lifecycle.
|
|
117
118
|
|
|
118
119
|
---
|
|
119
120
|
|
|
121
|
+
## Wire skills into OpenClaw workspace (#3001)
|
|
122
|
+
|
|
123
|
+
OpenClaw is a **session-first** host: installing `@deftai/directive` puts pin skills in the content package / deposit, but the **main** OpenClaw workspace may still only list host-global skills until something bridges them into `~/.openclaw/workspace/skills` (or `$OPENCLAW_STATE_DIR/workspace/skills`).
|
|
124
|
+
|
|
125
|
+
Always-pins required for cold-start / process gates ([skill-pin-policy.md](./skill-pin-policy.md) #2508):
|
|
126
|
+
|
|
127
|
+
- `deft-directive-build`
|
|
128
|
+
- `deft-directive-pre-pr`
|
|
129
|
+
- `deft-directive-review-cycle`
|
|
130
|
+
- `deft-directive-swarm`
|
|
131
|
+
|
|
132
|
+
### Detect
|
|
133
|
+
|
|
134
|
+
When OpenClaw signals are present (`OPENCLAW` / `DEFT_PROBE_OPENCLAW` / `DEFT_AGENT_RUNTIME=openclaw`, or `~/.openclaw` / `OPENCLAW_STATE_DIR`), `deft doctor` checks the **main** workspace skills root for those four pins.
|
|
135
|
+
|
|
136
|
+
- **Miss:** warning + remediation `deft doctor --fix` (plus pointers to this page and [host-lifecycle-duties.md](../contracts/host-lifecycle-duties.md)).
|
|
137
|
+
- **Hit:** success line — OpenClaw host pins present.
|
|
138
|
+
|
|
139
|
+
### Fix
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
deft doctor --fix
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Doctor links (preferred) or copies the four pin directories from the installed content package (`@deftai/directive-content` / `content/skills/…`) into the main OpenClaw skills root. It does **not** delete other user skills (e.g. a local `vbrief` skill stays). Divergent same-named directories are left alone unless you pass `--force` or confirm on a TTY.
|
|
146
|
+
|
|
147
|
+
After a successful wire: **restart the OpenClaw gateway or start a new session** so host `available_skills` refreshes.
|
|
148
|
+
|
|
149
|
+
### Multi-seat / crew workspaces
|
|
150
|
+
|
|
151
|
+
Default scope is **main only** (`workspace/skills`). Crew seats (`workspace-scotty`, `workspace-pike`, …) are **not** rewritten unless you opt in:
|
|
152
|
+
|
|
153
|
+
```text
|
|
154
|
+
deft doctor --fix --openclaw-all-agents
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
⊗ Silent rewrite of every `workspace-*` seat without that flag.
|
|
120
158
|
|
|
121
159
|
---
|
|
122
160
|
|
|
@@ -156,6 +194,8 @@ Full rules: [`skills/deft-directive-swarm/references/host-openclaw.md`](../skill
|
|
|
156
194
|
- ⊗ Claiming this doc alone makes `sessions_spawn` a shipped register/matrix primitive — that is epic skill/engine work (#2875 / #2876).
|
|
157
195
|
- ⊗ Multi-sentence progress-only first response after `subagent_announce` with zero tools / yield (#2943 text-repetition hang).
|
|
158
196
|
- ⊗ Treating thin DONE (no PR URL / merge evidence) as success (#2943).
|
|
197
|
+
- ⊗ Assuming package install alone populates OpenClaw `available_skills` — wire main workspace pins via `deft doctor --fix` (#3001).
|
|
198
|
+
- ⊗ Auto-enumerating every `workspace-*` seat without `--openclaw-all-agents` (#3001).
|
|
159
199
|
|
|
160
200
|
---
|
|
161
201
|
|
package/events/README.md
CHANGED
|
@@ -14,7 +14,7 @@ data-file-convention check follow-up
|
|
|
14
14
|
|
|
15
15
|
- `registry.json` — single source of truth for every event name, category,
|
|
16
16
|
payload contract, detector / emission pointer, and consumer pointers.
|
|
17
|
-
Lists 5 `detection-bound` events and
|
|
17
|
+
Lists 5 `detection-bound` events and 11 `behavioral` events (16 total).
|
|
18
18
|
- `registry.schema.json` — schema validating the registry's shape, including
|
|
19
19
|
the required `category` enum (`detection-bound` | `behavioral`).
|
|
20
20
|
- `event-record.schema.json` — schema for individual emitted event records.
|
package/events/registry.json
CHANGED
|
@@ -238,6 +238,42 @@
|
|
|
238
238
|
"packages/core/src/events/attribution-ledger.ts",
|
|
239
239
|
"(deferred) task deft:feedback:file / deft-directive-feedback skill (#1709 child 5)"
|
|
240
240
|
]
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"name": "session:start",
|
|
244
|
+
"category": "behavioral",
|
|
245
|
+
"description": "Mutation session:start ceremony finished (cold or re-arm). Local process-cost observability for ceremony wall-clock (#2994 / WWYSYDH pilot). Always-on best-effort local JSONL; not gated on valueFeedback; no remote upload.",
|
|
246
|
+
"trigger": "packages/core/src/session/process-cost.ts::emitSessionStartProcessCost from packages/core/src/session/session-start.ts after cold or re-arm ceremony completes and ritual state is written.",
|
|
247
|
+
"payload": {
|
|
248
|
+
"ceremony_tier": "string enum -- cold | rearm",
|
|
249
|
+
"duration_ms": "integer -- total ceremony wall-clock milliseconds",
|
|
250
|
+
"exit_code": "integer -- 0 when ready, non-zero when a quick step failed",
|
|
251
|
+
"ready": "boolean (optional) -- true when exit_code is 0",
|
|
252
|
+
"optional_network": "boolean (optional) -- whether optional network steps ran (#2991)",
|
|
253
|
+
"steps": "array (optional) -- { name, duration_ms, skipped? } per major phase from session:start --json"
|
|
254
|
+
},
|
|
255
|
+
"consumers": [
|
|
256
|
+
"packages/core/src/session/process-cost.ts -- emit helper",
|
|
257
|
+
"packages/core/src/session/session-start.ts -- cold + re-arm completion call sites",
|
|
258
|
+
"content/commands.md § Process-cost events -- WWYSYDH ceremony label mapping (#2994)"
|
|
259
|
+
]
|
|
260
|
+
},
|
|
261
|
+
{
|
|
262
|
+
"name": "session:ritual-blocked",
|
|
263
|
+
"category": "behavioral",
|
|
264
|
+
"description": "PreToolUse denied a mutation tool because the gated session ritual was not ready (missing/stale/invalid). Local process-cost / friction signal for ceremony blocks (#2994). Always-on best-effort local JSONL; not gated on valueFeedback; no remote upload.",
|
|
265
|
+
"trigger": "packages/core/src/session/process-cost.ts::emitSessionRitualBlockedProcessCost from packages/core/src/hooks/dispatcher.ts::inspectMutationGates when inspectSessionRitual returns non-zero or throws (ritual-not-ready deny path).",
|
|
266
|
+
"payload": {
|
|
267
|
+
"tool_name": "string -- host tool name that was denied",
|
|
268
|
+
"code": "string -- always ritual-not-ready for this event",
|
|
269
|
+
"recovery_tier": "string enum (optional) -- cold | rearm -- preferred recovery path (#2992)",
|
|
270
|
+
"detail": "string (optional) -- one-line inspect message (not the full recovery instruction)"
|
|
271
|
+
},
|
|
272
|
+
"consumers": [
|
|
273
|
+
"packages/core/src/session/process-cost.ts -- emit helper",
|
|
274
|
+
"packages/core/src/hooks/dispatcher.ts -- PreToolUse ritual deny path",
|
|
275
|
+
"content/commands.md § Process-cost events -- WWYSYDH ceremony label mapping (#2994)"
|
|
276
|
+
]
|
|
241
277
|
}
|
|
242
278
|
]
|
|
243
279
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-content",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.90.0",
|
|
4
4
|
"description": "Shippable Directive framework content in the consumer .deft/core/ layout (C1 flatten), plus the engine surfaces (.githooks/, Taskfile.yml, tasks/) the deposit wires. Python-free per #2022 Phase 3. Refs #11, #1669, #1967.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Tool-call taxonomy — explore / commit / verify (#2967)
|
|
2
|
+
|
|
3
|
+
Deterministic activity buckets for swarm and review-cycle operators. Use
|
|
4
|
+
this taxonomy when skimming tool logs, monitor status lines, or batch
|
|
5
|
+
briefs so “ran N tools” becomes a structured mix.
|
|
6
|
+
|
|
7
|
+
Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
|
|
8
|
+
|
|
9
|
+
**Load when:** writing swarm monitor status, review-cycle batch briefs,
|
|
10
|
+
PR evidence one-liners, usage metrics that group tool events, or any
|
|
11
|
+
harness surface that aggregates agent tool calls.
|
|
12
|
+
|
|
13
|
+
**Implementation:** pure rule-first API in
|
|
14
|
+
`packages/core/src/tool-events/` (`classifyToolEvent`,
|
|
15
|
+
`summarizeToolEvents`). No LLM per event.
|
|
16
|
+
|
|
17
|
+
**Related but distinct:**
|
|
18
|
+
- `packages/core/src/hooks/classify/` (#2950) — PreToolUse write-intent
|
|
19
|
+
and host payload identity. Share vocabulary only; do not merge.
|
|
20
|
+
- Causal graph work (#2966) may consume these buckets as node kinds.
|
|
21
|
+
|
|
22
|
+
**⚠️ See also**:
|
|
23
|
+
- [../swarm/swarm.md](../swarm/swarm.md) — multi-agent coordination
|
|
24
|
+
- [../skills/deft-directive-swarm/references/core-phase-4.md](../skills/deft-directive-swarm/references/core-phase-4.md) — monitor status line consumer
|
|
25
|
+
- [../skills/deft-directive-review-cycle/SKILL.md](../skills/deft-directive-review-cycle/SKILL.md) — review batch surfaces
|
|
26
|
+
|
|
27
|
+
## Buckets
|
|
28
|
+
|
|
29
|
+
| Bucket | Meaning | Typical tools / commands |
|
|
30
|
+
|--------|---------|---------------------------|
|
|
31
|
+
| `explore` | Read / search / fetch-for-analysis | `Read`, `Grep`, `Glob`, `list_dir`, `SemanticSearch`, `web_search`, `git status`/`log`/`diff`, `gh … view`/`list`, `rg`, `ghx` |
|
|
32
|
+
| `commit` | Mutate product or SCM state | `Write`, `Edit`, `StrReplace`, `ApplyPatch`, `Delete`, `git add`/`commit`/`push`, `gh pr create`, mutating `gh api -X POST` |
|
|
33
|
+
| `verify` | Run a **proven** gate or test | `vitest`, `pytest`, `go test`, `cargo test`, `npm test`, `task check`, `task verify:*`, `tsc`, `biome`, `eslint`, `task pr:watch` |
|
|
34
|
+
| `coordinate` | Session / swarm / handoff | `Task`, `spawn_subagent`, `start_agent`, `sessions_spawn`, `TodoWrite`, `AskQuestion`, `task swarm:*`, `task scope:*` |
|
|
35
|
+
| `unknown` | Explicit residual | Missing name, shell without command, ambiguous names, unlisted bins |
|
|
36
|
+
|
|
37
|
+
## Misclassification policy
|
|
38
|
+
|
|
39
|
+
- ! MUST prefer `unknown` over a wrong `verify`. False-positive verify
|
|
40
|
+
hides “shipped without gates”; residual unknown is recoverable.
|
|
41
|
+
- ! MUST classify as `verify` only when the tool name or shell command
|
|
42
|
+
**honestly proves** a test/lint/typecheck/doctor/check/watch gate.
|
|
43
|
+
- ⊗ MUST NOT map bare names that merely contain `test` / `lint` /
|
|
44
|
+
`check` (e.g. `TestHelper`, `npm run build`, `make install`, custom
|
|
45
|
+
scripts) to `verify`.
|
|
46
|
+
- ~ SHOULD leave novel MCP server tools as `unknown` until a nested
|
|
47
|
+
segment matches a known name (`mcp__host__Read` → explore).
|
|
48
|
+
|
|
49
|
+
## Anomalies (derived from counts)
|
|
50
|
+
|
|
51
|
+
`summarizeToolEvents` derives conservative anomaly codes:
|
|
52
|
+
|
|
53
|
+
| Code | When |
|
|
54
|
+
|------|------|
|
|
55
|
+
| `commit-without-explore` | `commit > 0` and `explore === 0` |
|
|
56
|
+
| `verify-skipped` | `commit > 0` and `verify === 0` |
|
|
57
|
+
| `explore-only` | `explore > 0`, `commit === 0`, `verify === 0`, and total events ≥ 3 |
|
|
58
|
+
|
|
59
|
+
## Status line format
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
tools: explore=N commit=N verify=N coordinate=N unknown=N
|
|
63
|
+
tools: explore=0 commit=2 verify=0 coordinate=0 unknown=0 | anomalies: commit-without-explore,verify-skipped
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Produced by `formatToolEventStatusLine` / `summarizeToolEvents`.statusLine.
|
|
67
|
+
|
|
68
|
+
## Non-goals
|
|
69
|
+
|
|
70
|
+
- ⊗ LLM classification per tool event (cost/drift kills ROI)
|
|
71
|
+
- ⊗ Proving a verify command was the *correct* test suite
|
|
72
|
+
- ⊗ Semantic code understanding of what was written
|
|
73
|
+
- ⊗ Replacing hooks write-path / authz classifiers (#2950 / #2944)
|
|
@@ -40,6 +40,26 @@ Track each agent through these stages:
|
|
|
40
40
|
6. **PR Created** — PR visible via `gh pr list --head <branch>`
|
|
41
41
|
7. **Review Cycling** — additional commits after PR creation (Greptile fix rounds)
|
|
42
42
|
|
|
43
|
+
### Tool-event mix status line (#2967)
|
|
44
|
+
|
|
45
|
+
! When the monitor has a sequence of tool names (and optional shell commands) for a leaf — host transcript, heartbeat sidecar, or operator-supplied log — classify with the pure `#2967` taxonomy and include the status line in the **next monitor status** (chat heartbeat or sticky cohort note). Do not invent counts; only report when events are available.
|
|
46
|
+
|
|
47
|
+
Buckets: `explore` | `commit` | `verify` | `coordinate` | `unknown`. Misclassification policy: prefer `unknown` over wrong `verify`. Canonical docs: [`content/patterns/tool-call-taxonomy.md`](../../../patterns/tool-call-taxonomy.md). API: `@deftai/directive-core/tool-events` (`classifyToolEvent`, `summarizeToolEvents`).
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
# Status line shape (from summarizeToolEvents(...).statusLine)
|
|
51
|
+
tools: explore=12 commit=4 verify=2 coordinate=1 unknown=0
|
|
52
|
+
tools: explore=0 commit=3 verify=0 coordinate=0 unknown=1 | anomalies: commit-without-explore,verify-skipped
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
! Surface anomalies when present:
|
|
56
|
+
- `commit-without-explore` — mutators without any explore events (possible blind edit)
|
|
57
|
+
- `verify-skipped` — commit events with zero verify gates (ship without check/test)
|
|
58
|
+
- `explore-only` — thrash signal (explore-only, no commit/verify, ≥3 events)
|
|
59
|
+
|
|
60
|
+
~ Pair the status line with worktree git checks and `task pr:merge-ready` so operators see progress **and** tool mix without reading raw tool logs.
|
|
61
|
+
⊗ Treat raw “ran N tools” as a structured mix — always bucket when events are available (#2967).
|
|
62
|
+
|
|
43
63
|
### Takeover Triggers
|
|
44
64
|
|
|
45
65
|
! **Pre-spawn verification:** Before spawning a replacement agent, verify the original is truly unresponsive by waiting for an idle/blocked lifecycle event — verified via worktree state (`git status`, `git log --oneline -3`) and sub-agent lifecycle signals showing no in-flight work (for grok-build / spawn_subagent agents: polling is via worktree state + `get_command_or_subagent_output` rather than tab observation; for openclaw / sessions_spawn agents: worktree state + parent completion announce / heartbeat records, not Grok Build poll output). Do NOT spawn a replacement based solely on message timing, absence of recent commits, or a perceived delay — original agents (Warp tabs, spawn_subagent processes, or OpenClaw sessions) can resume after apparent failure, and spawning a new agent creates two concurrent agents on the same worktree (see Duplicate-Tab Failure Mode below).
|
|
@@ -31,6 +31,10 @@ Live miss: operator said “use review skill” + URL; agent stayed on host free
|
|
|
31
31
|
⊗ Answer Deft-shaped intent with freestyle tools only when a Directive skill is indexed for that intent.
|
|
32
32
|
⊗ Skip project-root resolution and improvise from workspace home outside the target checkout.
|
|
33
33
|
|
|
34
|
+
### Pin wire into OpenClaw workspace skills (#3001)
|
|
35
|
+
|
|
36
|
+
Package install alone does not put always-pins into `~/.openclaw/workspace/skills`. Operators / agents SHOULD run `deft doctor` (detect) and `deft doctor --fix` (symlink or copy the four pins) when main-workspace pins are missing. Multi-seat only with `--openclaw-all-agents`. Operator steps: [`../../docs/openclaw-agent-host.md`](../../docs/openclaw-agent-host.md) § Wire skills into OpenClaw workspace.
|
|
37
|
+
|
|
34
38
|
## Hard isolation before spawn (#2929)
|
|
35
39
|
|
|
36
40
|
! For **parallel** OpenClaw leaves (cohort size > 1):
|
package/tasks/engine.yml
CHANGED
|
@@ -97,6 +97,7 @@ tasks:
|
|
|
97
97
|
is_runtime_verb=0
|
|
98
98
|
case " ${first_token} " in
|
|
99
99
|
" session:start "|" session-start "|\
|
|
100
|
+
" session:ready "|" session-ready "|\
|
|
100
101
|
" lifecycle:event "|" lifecycle-event "|\
|
|
101
102
|
" verify:session-ritual "|" verify-session-ritual "|\
|
|
102
103
|
" verify:tools "|" verify-tools "|\
|
package/tasks/lifecycle.yml
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
version: '3'
|
|
2
2
|
|
|
3
|
-
# tasks/lifecycle.yml -- behavioral framework event recorder (#2631 / #635)
|
|
3
|
+
# tasks/lifecycle.yml -- behavioral framework event recorder (#2631 / #635)
|
|
4
|
+
# and lifecycle folder stats (#2995).
|
|
4
5
|
# Consumer npm deposits invoke via engine:invoke without a local build (#2181).
|
|
5
6
|
#
|
|
6
7
|
# Review-cycle merge-gate approval uses `task lifecycle:event -- emit plan:approved ...`.
|
|
8
|
+
# Weekly process rollups use `task lifecycle:stats -- --since=7d [--json]`.
|
|
7
9
|
# Per conventions/task-caching.md: no sources/generates because the task forwards
|
|
8
10
|
# user-facing flags via CLI_ARGS.
|
|
9
11
|
|
|
@@ -21,3 +23,14 @@ tasks:
|
|
|
21
23
|
- task: :engine:invoke
|
|
22
24
|
vars:
|
|
23
25
|
ENGINE_CMD: 'lifecycle:event {{.CLI_ARGS}}'
|
|
26
|
+
|
|
27
|
+
stats:
|
|
28
|
+
desc: "Local xBRIEF lifecycle folder counts for process rollups (#2995). -- task lifecycle:stats -- --since=7d [--json] [--project-root <path>]"
|
|
29
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
30
|
+
deps: [':engine:_ts-build']
|
|
31
|
+
env:
|
|
32
|
+
PYTHONUTF8: "1"
|
|
33
|
+
cmds:
|
|
34
|
+
- task: :engine:invoke
|
|
35
|
+
vars:
|
|
36
|
+
ENGINE_CMD: 'lifecycle:stats --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
|
package/tasks/session.yml
CHANGED
|
@@ -19,3 +19,14 @@ tasks:
|
|
|
19
19
|
- task: :engine:invoke
|
|
20
20
|
vars:
|
|
21
21
|
ENGINE_CMD: 'session:start --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
|
|
22
|
+
|
|
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"
|
|
25
|
+
dir: '{{.USER_WORKING_DIR}}'
|
|
26
|
+
# Runtime/session dispatch: no engine:_ts-build / pnpm build (#2181).
|
|
27
|
+
env:
|
|
28
|
+
PYTHONUTF8: "1"
|
|
29
|
+
cmds:
|
|
30
|
+
- task: :engine:invoke
|
|
31
|
+
vars:
|
|
32
|
+
ENGINE_CMD: 'session:ready --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
|