@deftai/directive-content 0.96.0 → 0.97.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Taskfile.yml +6 -0
- package/commands.md +14 -1
- package/contracts/test-boundary.md +18 -0
- package/docs/consumer-check-contract.md +27 -0
- package/docs/delivery-attempt.md +173 -0
- package/docs/openclaw-agent-host.md +36 -1
- package/docs/operator-log-hygiene-checklist.md +57 -0
- package/docs/operator-log-hygiene-consumer-pack-stub.md +75 -0
- package/docs/scope-provenance.md +54 -0
- package/docs/test-boundary.md +43 -0
- package/main.md +29 -0
- package/package.json +1 -1
- package/packs/patterns/patterns-pack-0.1.json +10 -0
- package/packs/skills/skills-pack-0.1.json +4 -4
- package/patterns/operator-log-hygiene.md +130 -0
- package/scm/github.md +26 -0
- package/skills/deft-directive-article-review/SKILL.md +17 -6
- package/skills/deft-directive-build/SKILL.md +41 -0
- package/skills/deft-directive-review-cycle/SKILL.md +150 -0
- package/skills/deft-directive-swarm/SKILL.md +14 -0
- package/skills/deft-directive-swarm/references/core-ops.md +14 -2
- package/skills/deft-directive-swarm/references/core-phase-0.md +34 -1
- package/skills/deft-directive-swarm/references/core-phase-3.md +6 -0
- package/skills/deft-directive-swarm/references/core-phase-4.md +21 -2
- package/skills/deft-directive-swarm/references/core-phase-5-6.md +17 -0
- package/skills/deft-directive-swarm/references/host-openclaw.md +4 -0
- package/tasks/engine-invoke.cjs +22 -17
- package/tasks/engine-invoke.test.cjs +30 -0
- package/tasks/verify.yml +30 -0
- package/templates/agent-prompt-preamble.md +8 -0
- package/templates/agents-entry.md +10 -0
- package/templates/swarm-greptile-poller-prompt.md +4 -2
package/Taskfile.yml
CHANGED
|
@@ -421,6 +421,9 @@ tasks:
|
|
|
421
421
|
- verify:branch
|
|
422
422
|
- verify:encoding
|
|
423
423
|
- verify:forward-coverage
|
|
424
|
+
- verify:test-boundary
|
|
425
|
+
- verify:scope-provenance
|
|
426
|
+
- verify:consumer-check-contract
|
|
424
427
|
- verify:vbrief-conformance
|
|
425
428
|
- verify:destructive-gh-verbs
|
|
426
429
|
- verify:scm-boundary
|
|
@@ -461,6 +464,9 @@ tasks:
|
|
|
461
464
|
- verify:cache-fresh
|
|
462
465
|
- verify:wip-cap
|
|
463
466
|
- verify:orphan-active
|
|
467
|
+
- verify:test-boundary
|
|
468
|
+
- verify:scope-provenance
|
|
469
|
+
- verify:consumer-check-contract
|
|
464
470
|
- vbrief:validate
|
|
465
471
|
- verify-strategy-output
|
|
466
472
|
cmds:
|
package/commands.md
CHANGED
|
@@ -300,7 +300,20 @@ When the workflow needs an Approach 1 monitor, scope the Cursor leaf `stop-at: p
|
|
|
300
300
|
- Repair missing/drifted entries: `deft update`.
|
|
301
301
|
- **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.
|
|
302
302
|
- **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.
|
|
303
|
-
- **Compact re-arm (#2113 / #2992 / #2993
|
|
303
|
+
- **Compact re-arm + soft AGENTS re-bind (#2113 / #2992 / #2993 / #3171 / #2769):** post-compact posture is **two surfaces**:
|
|
304
|
+
- **Hard (Tier-1):** Cursor `preCompact` and Claude/Grok `PreCompact`/`PostCompact` call `deft-hook --event session.compact` to mark the gated session ritual stale (`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`. Soft **never** replaces or weakens hard deny for writes.
|
|
305
|
+
- **Soft:** the same hook path (and `session.start`) injects a **shared** AGENTS re-bind checklist (re-read AGENTS.md → confirm key rules → deposit integrity → summary≠SoT → operational-ask trap → mutation vs read-only). Soft fires without requiring a write tool; read-only/operational turns do **not** force full cold `session:start`. Soft never authorizes skipping the mutation ritual for writes.
|
|
306
|
+
- **Per-host matrix (#3171):**
|
|
307
|
+
|
|
308
|
+
| Host | Hard compact | Soft re-bind | Wire |
|
|
309
|
+
|------|--------------|--------------|------|
|
|
310
|
+
| **Cursor** | Yes (`preCompact`) | Required | compact `user_message` + SessionStart `additional_context` |
|
|
311
|
+
| **Claude Code** | Yes (`PreCompact`/`PostCompact`) | Required | compact + SessionStart `additionalContext` |
|
|
312
|
+
| **Grok Build** | Yes | Required (#3161 dogfood) | compact + SessionStart soft cue |
|
|
313
|
+
| **Codex** | **No** native compact | Docs + best-effort | SessionStart soft cue only; operators re-arm mutation ritual manually after compaction |
|
|
314
|
+
| **OpenClaw** | Not file-host hooks | Required | durable workspace skill `deft-directive-post-compact-rebind` via `deft doctor --fix` / init; see [openclaw-agent-host.md](./docs/openclaw-agent-host.md) |
|
|
315
|
+
|
|
316
|
+
- Shared checklist SoT: `packages/core/src/session/compact-ritual.ts` (all host deposits derive from it).
|
|
304
317
|
- Codex project hooks are trust-gated by Codex. Directive can verify structural registration and command functionality, but reports trust separately as `manual-review-required` and interception as `not-directly-verified`; after an install or changed hook hash, open `/hooks` in Codex and review/approve the exact project hook commands. Runtime trust and real host interception cannot be inferred from the file or live shim probe alone.
|
|
305
318
|
- 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).
|
|
306
319
|
- 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`.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Contract: test-boundary (#3145)
|
|
2
|
+
|
|
3
|
+
## Normative requirements
|
|
4
|
+
|
|
5
|
+
- ! `verify:test-boundary` MUST reject recognized test files under declared `sourceRoots` when they are not under `testRoots` and not allowlisted.
|
|
6
|
+
- ! Recognized patterns MUST include at least: Python `test_*.py` / `*_test.py`, C# `*Tests.cs` / `*Test.cs`, TypeScript/JavaScript `*.test.*` / `*.spec.*`, Go `*_test.go`.
|
|
7
|
+
- ! When `productionMayReferenceTestRoots` is false, production source and deployment/infra scripts MUST NOT reference `testRoots` or `fixtureRoots` path prefixes.
|
|
8
|
+
- ! Allow entries MUST support `kind: exception` and `kind: production-liveness` with recorded reason.
|
|
9
|
+
- ! Failures MUST identify path, violated boundary, and remediation.
|
|
10
|
+
- ! Defaults without authored policy MUST use warn-only discovery (`enforcementMode: warn`) for migration.
|
|
11
|
+
- ⊗ Infer safety solely because a path was listed in an active xBRIEF.
|
|
12
|
+
|
|
13
|
+
## Surfaces
|
|
14
|
+
|
|
15
|
+
- Core: `packages/core/src/test-boundary/`
|
|
16
|
+
- CLI: `deft verify:test-boundary` / `task verify:test-boundary`
|
|
17
|
+
- Policy: `.deft/test-boundary.policy.json` or `plan.policy.testBoundary`
|
|
18
|
+
- Docs: `content/docs/test-boundary.md`
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Consumer check contract (`verify:consumer-check-contract`)
|
|
2
|
+
|
|
3
|
+
Refs: #3145 · Related: #3070 consumer gate integrity, #1519 check:consumer
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
A consumer could omit Directive enforcement gates from its `check` task and CI while local and CI success still looked green. Composition was not machine-checked.
|
|
8
|
+
|
|
9
|
+
## Contract
|
|
10
|
+
|
|
11
|
+
`task verify:consumer-check-contract` requires these gates to be defined under `tasks/verify.yml` and composed into consumer/framework check aggregates:
|
|
12
|
+
|
|
13
|
+
- `verify:test-boundary`
|
|
14
|
+
- `verify:scope-provenance`
|
|
15
|
+
- `verify:consumer-check-contract`
|
|
16
|
+
|
|
17
|
+
It fails with a concrete repair path when definitions or explicit check deps omit them. CI workflows that neither invoke the gates nor a composing entrypoint (`task check` / `deft check`) produce **warnings** by default (migration).
|
|
18
|
+
|
|
19
|
+
## Repair path
|
|
20
|
+
|
|
21
|
+
1. Restore deposit Taskfiles: `deft update` (includes `tasks/verify.yml`)
|
|
22
|
+
2. Ensure `check:consumer` / `check:framework-source` deps list the three gates (framework source already ships this wiring)
|
|
23
|
+
3. Prefer CI that runs `task check` or `deft check` rather than a partial custom graph
|
|
24
|
+
|
|
25
|
+
## Relation to #3070
|
|
26
|
+
|
|
27
|
+
`consumer-gate-integrity` proves Taskfile includes resolve. This gate proves the **required enforcement set** is present and composed — not merely that a random verify task exists.
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# Delivery-attempt circuit breaker (#3143)
|
|
2
|
+
|
|
3
|
+
Deterministic pre-dispatch gate and durable attempt ledger for autonomous
|
|
4
|
+
**delivery** and **operational-acceptance** loops.
|
|
5
|
+
|
|
6
|
+
This is the mechanical enforcement surface for the delivery/acceptance subset of
|
|
7
|
+
the dual-stop principle (#2442). Skill defaults (build / swarm / review-cycle)
|
|
8
|
+
remain behavioral; hosts and orchestrators that dispatch delivery workflows
|
|
9
|
+
MUST evaluate this gate before automatic retry or re-dispatch.
|
|
10
|
+
|
|
11
|
+
## Module
|
|
12
|
+
|
|
13
|
+
| Path | Role |
|
|
14
|
+
|------|------|
|
|
15
|
+
| `packages/core/src/delivery-attempt/` | Library (types, fingerprint, material-delta, ledger, evaluate, handoff) |
|
|
16
|
+
| `@deftai/directive-core/delivery-attempt` | Package subpath export |
|
|
17
|
+
| `.deft/delivery-attempts/` | On-disk unit ledgers (project-local) |
|
|
18
|
+
|
|
19
|
+
## Pre-dispatch decisions
|
|
20
|
+
|
|
21
|
+
`evaluatePreDispatch(ledger, input)` returns one of:
|
|
22
|
+
|
|
23
|
+
| Decision | Meaning |
|
|
24
|
+
|----------|---------|
|
|
25
|
+
| `ALLOW_FIRST_ATTEMPT` | No open failure identity for the unit |
|
|
26
|
+
| `ALLOW_TRANSIENT_RETRY` | Bounded retry after a transient (or under-threshold unknown) failure |
|
|
27
|
+
| `ALLOW_MATERIAL_PROGRESS` | Relevant material delta addresses the failing invariant |
|
|
28
|
+
| `ALLOW_OVERRIDE` / `ALLOW_RESUME` | Audited override or satisfied resume condition |
|
|
29
|
+
| `DENY_DUPLICATE_ACTIVE` | Queued/running attempt already exists for the unit |
|
|
30
|
+
| `BLOCK_NON_RETRYABLE` | Deterministic failure without progress |
|
|
31
|
+
| `BLOCK_NO_MATERIAL_PROGRESS` | Same failure class, no relevant delta |
|
|
32
|
+
| `BLOCK_REPEATED_UNKNOWN` | Identical unknown failures hit the threshold |
|
|
33
|
+
| `BLOCK_ATTEMPT_BUDGET` | Failed-dispatch budget for the phase exhausted |
|
|
34
|
+
| `BLOCK_ELAPSED_BUDGET` | Wall-clock budget exhausted |
|
|
35
|
+
| `BLOCK_TOOL_OR_TOKEN_BUDGET` | Tool-call (or host-token when telemetried) budget exhausted |
|
|
36
|
+
|
|
37
|
+
Once a **block** decision is emitted, automatic re-dispatch MUST stop until a
|
|
38
|
+
declared resume condition is satisfied or an audited operator override is
|
|
39
|
+
recorded. Persist the terminal handoff (`buildTerminalHandoff` /
|
|
40
|
+
`formatHandoffReport`) before the worker exits.
|
|
41
|
+
|
|
42
|
+
## Unit key and durability
|
|
43
|
+
|
|
44
|
+
Logical unit: `scopeId + targetId + workflowId`.
|
|
45
|
+
|
|
46
|
+
Counters (`failedAttemptCount`, `sameFailureCounts`, elapsed/tool/token totals)
|
|
47
|
+
survive:
|
|
48
|
+
|
|
49
|
+
- worker replacement / takeover
|
|
50
|
+
- session restart and context compaction
|
|
51
|
+
- new source revisions (fingerprint counters do **not** reset)
|
|
52
|
+
|
|
53
|
+
Raw logs, credentials, and secret-bearing payloads MUST NOT be stored in the
|
|
54
|
+
ledger. Failure fingerprints redact volatile ids, paths, timestamps, and
|
|
55
|
+
secret-like values (`computeFailureFingerprint`).
|
|
56
|
+
|
|
57
|
+
## Material progress
|
|
58
|
+
|
|
59
|
+
Material progress means verifiable state changed in a way that can resolve or
|
|
60
|
+
advance beyond the current failure (code/config/evidence/external-state/stage
|
|
61
|
+
that **addresses** the failing invariant).
|
|
62
|
+
|
|
63
|
+
Not material progress by themselves:
|
|
64
|
+
|
|
65
|
+
- new revision identifiers alone
|
|
66
|
+
- repeating the same dispatch
|
|
67
|
+
- restating analysis
|
|
68
|
+
- replacing the worker
|
|
69
|
+
- compaction / session restart
|
|
70
|
+
- evidence bound to an intermediate revision when evaluating a later revision
|
|
71
|
+
|
|
72
|
+
## Safe defaults (`DEFAULT_DELIVERY_BUDGET_POLICY`)
|
|
73
|
+
|
|
74
|
+
| Knob | Default |
|
|
75
|
+
|------|---------|
|
|
76
|
+
| max active (queued+running) | 1 |
|
|
77
|
+
| max automatic transient retries | 1 |
|
|
78
|
+
| identical unknown without progress → block | 2 |
|
|
79
|
+
| failed dispatches per phase → block | 3 |
|
|
80
|
+
| max elapsed seconds | 3600 |
|
|
81
|
+
| max tool calls | 500 |
|
|
82
|
+
| max host tokens | null (enforce only when host exposes usage **and** policy sets a cap) |
|
|
83
|
+
|
|
84
|
+
Missing host token telemetry does **not** disable the circuit breaker — elapsed
|
|
85
|
+
and tool-call budgets still apply.
|
|
86
|
+
|
|
87
|
+
## Operator override
|
|
88
|
+
|
|
89
|
+
`recordOperatorOverride` requires actor, rationale, timestamp, bounded
|
|
90
|
+
`allowedAttempts`, and optional expiry. Overrides do **not** erase attempt
|
|
91
|
+
history.
|
|
92
|
+
|
|
93
|
+
## Skill routing
|
|
94
|
+
|
|
95
|
+
| Surface | Role |
|
|
96
|
+
|---------|------|
|
|
97
|
+
| `main.md` Dual Stop Rule (#2442) | Principle; points here for delivery/acceptance |
|
|
98
|
+
| build / swarm / review-cycle skills | Behavioral dual-stop defaults; point here for mechanical gate |
|
|
99
|
+
| swarm `core-ops` / `core-phase-4` | Prompt + monitor envelopes; do not invent a second ledger |
|
|
100
|
+
|
|
101
|
+
## Typical call shape
|
|
102
|
+
|
|
103
|
+
Use the **locked disk APIs** for concurrent-safe begin/complete. Do not evaluate
|
|
104
|
+
on a stale in-memory snapshot and then `saveUnitLedger` without the unit lock.
|
|
105
|
+
|
|
106
|
+
```ts
|
|
107
|
+
import {
|
|
108
|
+
beginAttemptOnDisk,
|
|
109
|
+
completeAttemptOnDisk,
|
|
110
|
+
buildFailureInfo,
|
|
111
|
+
} from "@deftai/directive-core/delivery-attempt";
|
|
112
|
+
|
|
113
|
+
// beginAttemptOnDisk: exclusive lock → reload → evaluatePreDispatch → begin → save
|
|
114
|
+
let attempt;
|
|
115
|
+
try {
|
|
116
|
+
const begun = beginAttemptOnDisk(projectRoot, {
|
|
117
|
+
scopeId,
|
|
118
|
+
targetId,
|
|
119
|
+
workflowId,
|
|
120
|
+
sourceRevision,
|
|
121
|
+
trigger: "automatic",
|
|
122
|
+
anticipatedFailure: lastFailure,
|
|
123
|
+
materialDelta: claims,
|
|
124
|
+
});
|
|
125
|
+
attempt = begun.attempt;
|
|
126
|
+
} catch (err) {
|
|
127
|
+
// DENY_*/BLOCK_* — handoff already persisted when blocked
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// ... run workflow ...
|
|
132
|
+
|
|
133
|
+
// completeAttemptOnDisk: exclusive lock → reload → complete → save
|
|
134
|
+
const closed = completeAttemptOnDisk(projectRoot, {
|
|
135
|
+
scopeId,
|
|
136
|
+
targetId,
|
|
137
|
+
workflowId,
|
|
138
|
+
attemptId: attempt.attemptId,
|
|
139
|
+
status: "failed",
|
|
140
|
+
failure: buildFailureInfo({ stage, code, message, retryability }),
|
|
141
|
+
});
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
Pure in-memory helpers (`evaluatePreDispatch`, `beginAttempt`, `completeAttempt`)
|
|
145
|
+
remain for tests and single-threaded hosts. Multi-worker orchestration MUST use
|
|
146
|
+
`beginAttemptOnDisk` / `completeAttemptOnDisk` (or `withUnitLock` around an
|
|
147
|
+
equivalent sequence). Abandoned unit locks are reclaimed **only** when the owner
|
|
148
|
+
PID is dead or the lock record is corrupt/unreadable. A live owner PID is never
|
|
149
|
+
time-reclaimed (including long critical sections and event-loop stalls). Reclaim
|
|
150
|
+
is serialized via an exclusive `*.lock.reclaim` ticket so concurrent reclaimers
|
|
151
|
+
cannot unlink a live replacement lock. If a lock remains stuck after process
|
|
152
|
+
death with PID reuse (or a hung live holder), delete the matching `.lock` /
|
|
153
|
+
`.lock.reclaim` files under `.deft/delivery-attempts/` manually.
|
|
154
|
+
|
|
155
|
+
Ledger load is **fail-closed on corruption**: a present but invalid ledger file
|
|
156
|
+
throws (does not create an empty unit). Only a truly missing file creates a new
|
|
157
|
+
empty ledger. Operators must repair or remove a corrupt file deliberately before
|
|
158
|
+
dispatch can resume for that unit.
|
|
159
|
+
|
|
160
|
+
## Observability
|
|
161
|
+
|
|
162
|
+
Every evaluation emits a structured `PreDispatchDecisionEvent`
|
|
163
|
+
(`decision`, `reasonCode`, retryability, fingerprint, counters, material-delta
|
|
164
|
+
class, resume condition, override id). Aggregate metrics can count duplicate
|
|
165
|
+
denies, deterministic blocks, and budget savings from early halt.
|
|
166
|
+
|
|
167
|
+
## Non-goals
|
|
168
|
+
|
|
169
|
+
- Weakening validation, review, or deploy safety gates
|
|
170
|
+
- Treating every different downstream failure as the same failure
|
|
171
|
+
- Preventing deliberate audited overrides
|
|
172
|
+
- Provider-specific CI/CD lock-in
|
|
173
|
+
- Prompt-only thrashing control (use dual-stop skill defaults for that class)
|
|
@@ -56,7 +56,7 @@ Bodies stay **thin** (L5): frontmatter + short dispatch pointer to the same cont
|
|
|
56
56
|
4. Opt-out: `plan.policy.openClawProductCommands: false` — removes **managed** L2 thin skills only; preserves consumer custom skills at the same slug.
|
|
57
57
|
5. After deposit: **restart the OpenClaw gateway or start a new session** so `available_skills` refreshes.
|
|
58
58
|
|
|
59
|
-
Always-pin skills (`deft-directive-build`, `pre-pr`, `review-cycle`, `swarm`) remain a **different** surface from L2 product commands (`/deft:directive:run:interview`, `/deft:continue`, …).
|
|
59
|
+
Always-pin skills (`deft-directive-build`, `pre-pr`, `review-cycle`, `swarm`) remain a **different** surface from L2 product commands (`/deft:directive:run:interview`, `/deft:continue`, …). Soft post-compact re-bind (`deft-directive-post-compact-rebind`, #3171) is a third surface — see § Soft post-compact AGENTS re-bind below.
|
|
60
60
|
|
|
61
61
|
Inspect policy:
|
|
62
62
|
|
|
@@ -66,6 +66,41 @@ deft policy:show --field=openClawProductCommands
|
|
|
66
66
|
|
|
67
67
|
---
|
|
68
68
|
|
|
69
|
+
## Soft post-compact AGENTS re-bind (#3171 / #2769)
|
|
70
|
+
|
|
71
|
+
OpenClaw is a **Family-2** session host. Soft AGENTS re-bind after compaction / long-session amnesia is **required** on OpenClaw and is **not** claimed via Cursor/Claude/Grok file-host `PreCompact` hooks alone.
|
|
72
|
+
|
|
73
|
+
| Surface | OpenClaw posture |
|
|
74
|
+
|---------|------------------|
|
|
75
|
+
| **Hard** compact re-arm (file-host PreToolUse stale → deny writes) | **Not** provided by file-host compact hooks on OpenClaw. Mutation still requires `session:start` / `session:ready` / gated ritual via CLI/skills before gated writes. |
|
|
76
|
+
| **Soft** AGENTS re-bind | **Required** durable workspace skill from the **shared checklist SoT** (`packages/core/src/session/compact-ritual.ts`). |
|
|
77
|
+
|
|
78
|
+
### Checklist obligations (same SoT as file hosts)
|
|
79
|
+
|
|
80
|
+
1. Re-read managed `AGENTS.md` session routing (#2176) — summary ≠ SoT.
|
|
81
|
+
2. Confirm-what-you-learned (brief) in the user-visible reply.
|
|
82
|
+
3. Deposit integrity: `deft` on PATH ≠ healthy `.deft/core` deposit.
|
|
83
|
+
4. Summary/runbook (demo DBs, “start the app”) are hypotheses — re-verify PROJECT-DEFINITION / USER.md / local config.
|
|
84
|
+
5. Operational-ask trap: “open/start/run the app” is still session-routed (#3161).
|
|
85
|
+
6. Read-only → soft only; mutation → soft **plus** hard re-arm where supported. Soft **never** authorizes skipping the mutation ritual for writes.
|
|
86
|
+
|
|
87
|
+
### Deposit / amnesia boundary
|
|
88
|
+
|
|
89
|
+
| Step | Action |
|
|
90
|
+
|------|--------|
|
|
91
|
+
| Detect / fix | `deft doctor` warns when OpenClaw is detected and the managed skill is missing/stale; `deft doctor --fix` deposits it (multi-seat: `--openclaw-all-agents`) |
|
|
92
|
+
| init / update | Deposits when OpenClaw signals are present (fail-closed otherwise) |
|
|
93
|
+
| Skill id | `deft-directive-post-compact-rebind` under the OpenClaw workspace skills root |
|
|
94
|
+
| After deposit | **Restart the OpenClaw gateway or start a new session** so skills reload |
|
|
95
|
+
| Trigger | Session start / resume, gateway restart, long-session amnesia, operational asks after summary resume |
|
|
96
|
+
|
|
97
|
+
⊗ Claim OpenClaw soft coverage from file-host hook deposits alone.
|
|
98
|
+
⊗ Treat “pins present” as “session ritual completed.”
|
|
99
|
+
|
|
100
|
+
Shared dual-surface + five-host matrix: [commands.md](../commands.md) § Agent-host hooks → Compact re-arm + soft AGENTS re-bind.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
69
104
|
## Mental model (host class)
|
|
70
105
|
|
|
71
106
|
| Host | Host-native background spawn (typical) | Directive review-monitor role |
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# Operator-log hygiene checklist (#1940)
|
|
2
|
+
|
|
3
|
+
Copy-paste block for **story acceptance criteria** and **probe locked
|
|
4
|
+
decisions**. Full pattern:
|
|
5
|
+
[`patterns/operator-log-hygiene.md`](../patterns/operator-log-hygiene.md).
|
|
6
|
+
|
|
7
|
+
Legend (RFC2119): `!`=MUST, `~`=SHOULD, `⊗`=MUST NOT, `?`=MAY.
|
|
8
|
+
|
|
9
|
+
**Load when:** building operator-facing services, adding WARN/ERROR paths
|
|
10
|
+
operators triage, multi-process workers, or probing logging decisions.
|
|
11
|
+
|
|
12
|
+
## Story AC / probe locked decisions (copy-paste)
|
|
13
|
+
|
|
14
|
+
Use as-is in scope xBRIEF acceptance, probe locked decisions, or PR
|
|
15
|
+
checklist. Mark N/A only with a one-line reason.
|
|
16
|
+
|
|
17
|
+
```markdown
|
|
18
|
+
### Operator-log hygiene (#1940)
|
|
19
|
+
|
|
20
|
+
Legend: ! = MUST, ~ = SHOULD, ? = MAY (from patterns/operator-log-hygiene.md)
|
|
21
|
+
|
|
22
|
+
- [ ] ! Terminal / completion events on **all** exit paths (success, skip,
|
|
23
|
+
timeout, supersede, cancel, failure) — not happy path only
|
|
24
|
+
- [ ] ! Correlation IDs for multi-process / pool designs (job id, slot,
|
|
25
|
+
phase, parent id as applicable)
|
|
26
|
+
- [ ] ! Infrastructure paths (rotation, flush-before-exit, IPC handoff,
|
|
27
|
+
boot supervision) fail-open where possible and emit structured
|
|
28
|
+
events when they degrade
|
|
29
|
+
- [ ] ~ Operator-visible WARN/ERROR use a stable, queryable shape
|
|
30
|
+
(consumer-owned fields; e.g. stable event id + short operator
|
|
31
|
+
summary) — not ticket numbers alone
|
|
32
|
+
- [ ] ~ Operator glossary / plain-English docs updated in the **same PR**
|
|
33
|
+
when operator-facing log lines change
|
|
34
|
+
- [ ] ? Optional: wire consumer-owned validator into *your* check aggregate
|
|
35
|
+
(see docs/operator-log-hygiene-consumer-pack-stub.md) — not core default
|
|
36
|
+
- [ ] Explicit non-goals respected: no assumption that core `deft check`
|
|
37
|
+
enforces this; log shape stays consumer-owned
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Agent rules when applying the checklist
|
|
41
|
+
|
|
42
|
+
- ! MUST run this checklist before claiming "logging done" on an
|
|
43
|
+
operator-visible lifecycle path
|
|
44
|
+
- ! MUST keep log field names and schemas **project-owned** unless the
|
|
45
|
+
consumer already defined them
|
|
46
|
+
- ~ SHOULD attach the checklist under probe locked decisions when the plan
|
|
47
|
+
introduces or changes operator-facing logs
|
|
48
|
+
- ⊗ MUST NOT invent a framework-wide required field set (`operatorSummary`,
|
|
49
|
+
etc.) from this checklist alone
|
|
50
|
+
- ⊗ MUST NOT treat Product Insights (#2603) or LLM telemetry (#481) as
|
|
51
|
+
substitutes for operator-log hygiene
|
|
52
|
+
|
|
53
|
+
## Related
|
|
54
|
+
|
|
55
|
+
- Pattern: `content/patterns/operator-log-hygiene.md`
|
|
56
|
+
- Optional consumer pack stub: `content/docs/operator-log-hygiene-consumer-pack-stub.md`
|
|
57
|
+
- External case study (reference only): deftai/slizard operator-log hygiene docs and `operator-log:validate` — do not import schema into core
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# Operator-log hygiene — optional consumer pack stub (#1940)
|
|
2
|
+
|
|
3
|
+
Skeleton for **consumer projects** that want a ship-gate for operator-facing
|
|
4
|
+
logs. Wire this into *your* check aggregate only if you opt in.
|
|
5
|
+
|
|
6
|
+
Full pattern: [`patterns/operator-log-hygiene.md`](../patterns/operator-log-hygiene.md).
|
|
7
|
+
Checklist: [`operator-log-hygiene-checklist.md`](./operator-log-hygiene-checklist.md).
|
|
8
|
+
|
|
9
|
+
## Settled boundaries
|
|
10
|
+
|
|
11
|
+
| Topic | Rule |
|
|
12
|
+
|-------|------|
|
|
13
|
+
| Default-on | **Off.** Directive core does not enable this for all services. |
|
|
14
|
+
| Schema | **Consumer-owned.** You define fields and glossary path. |
|
|
15
|
+
| Framework `deft check` | **Does not** hard-fail consumers who never opted in. |
|
|
16
|
+
| External refs | SLizard `task operator-log:validate` is a **reference** only. |
|
|
17
|
+
|
|
18
|
+
## Suggested Taskfile target name
|
|
19
|
+
|
|
20
|
+
Prefer a project-local name so it does not imply framework ownership:
|
|
21
|
+
|
|
22
|
+
```yaml
|
|
23
|
+
# tasks/observability.yml (consumer-owned example — not shipped by core)
|
|
24
|
+
version: "3"
|
|
25
|
+
|
|
26
|
+
tasks:
|
|
27
|
+
operator-log:validate:
|
|
28
|
+
desc: Validate operator-facing log shape / glossary (consumer-owned)
|
|
29
|
+
cmds:
|
|
30
|
+
- echo "Implement inventory + schema checks for YOUR log contract"
|
|
31
|
+
# - node scripts/validate-operator-log.mjs --strict
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Optional aliases consumers sometimes use:
|
|
35
|
+
|
|
36
|
+
- `observability:validate`
|
|
37
|
+
- `ops-log:check`
|
|
38
|
+
|
|
39
|
+
Pick one name and keep it stable in your repo.
|
|
40
|
+
|
|
41
|
+
## Validator skeleton (comments only)
|
|
42
|
+
|
|
43
|
+
```js
|
|
44
|
+
// scripts/validate-operator-log.mjs (consumer-owned skeleton)
|
|
45
|
+
//
|
|
46
|
+
// 1. Inventory: find operator-facing log call sites (WARN/ERROR + terminal events).
|
|
47
|
+
// 2. Schema: load YOUR glossary / field contract (path from project config).
|
|
48
|
+
// 3. Strict mode: fail if new events lack required consumer fields.
|
|
49
|
+
// 4. Exit 0 when clean; exit 1 with actionable paths when not.
|
|
50
|
+
//
|
|
51
|
+
// ⊗ Do not import SLizard glossary JSON as universal SoT.
|
|
52
|
+
// ⊗ Do not expect @deftai/directive to ship or enforce this script.
|
|
53
|
+
//
|
|
54
|
+
// Reference shape (external): deftai/slizard task operator-log:validate
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Wire into *your* check (optional)
|
|
58
|
+
|
|
59
|
+
```yaml
|
|
60
|
+
# In the consumer Taskfile check aggregate — only if you want hard-fail
|
|
61
|
+
tasks:
|
|
62
|
+
check:
|
|
63
|
+
deps:
|
|
64
|
+
- operator-log:validate
|
|
65
|
+
# ...other consumer gates...
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- ! MUST document the gate as **project policy** when enabled
|
|
69
|
+
- ⊗ MUST NOT claim framework `deft check` mandates this target by default
|
|
70
|
+
- ? MAY keep the script warn-only until glossary coverage is good enough
|
|
71
|
+
|
|
72
|
+
## Related
|
|
73
|
+
|
|
74
|
+
- #1940 thin v1 — content + checklist + this stub
|
|
75
|
+
- Pattern non-goals: no `plan.observability` core schema, no default-on
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Approved-scope provenance (`verify:scope-provenance`)
|
|
2
|
+
|
|
3
|
+
Refs: #3145 · Related: #1310, #2944 human-origin grants, #516 file scope
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
An implementation PR could edit its own active xBRIEF to add new paths, after which one-way forward-coverage still passed. The modified xBRIEF became its own authorization source.
|
|
8
|
+
|
|
9
|
+
## Contract
|
|
10
|
+
|
|
11
|
+
At activation or operator approval, record an immutable **approved-scope digest** under:
|
|
12
|
+
|
|
13
|
+
```text
|
|
14
|
+
.deft/approved-scope/<plan-id>.json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Shape:
|
|
18
|
+
|
|
19
|
+
```json
|
|
20
|
+
{
|
|
21
|
+
"schemaVersion": 1,
|
|
22
|
+
"xbriefRelPath": "xbrief/active/….xbrief.json",
|
|
23
|
+
"planId": "…",
|
|
24
|
+
"approvedAt": "2026-08-06T00:00:00Z",
|
|
25
|
+
"fileScope": ["packages/core/src/foo.ts"],
|
|
26
|
+
"fileScopeDigest": "<sha256 of sorted paths>",
|
|
27
|
+
"humanApproval": {
|
|
28
|
+
"kind": "operator",
|
|
29
|
+
"actor": "scott",
|
|
30
|
+
"mintedAt": "2026-08-06T00:00:00Z"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
`task verify:scope-provenance` compares the live active xBRIEF `plan.metadata.swarm.file_scope` to the digest when that xBRIEF is modified in the current change set.
|
|
36
|
+
|
|
37
|
+
| Outcome | Behavior |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| No expansion | Pass |
|
|
40
|
+
| Expansion + renewed human stamp / re-recorded matching digest | Pass |
|
|
41
|
+
| Expansion without renewal | **Fail** — self-authorizing scope |
|
|
42
|
+
| Modified active xBRIEF, no digest yet | **Warn** by default; `--enforce` fails closed |
|
|
43
|
+
|
|
44
|
+
Agent-shaped stamps (`kind: agent`, `actor: agent:…`) never count as renewal.
|
|
45
|
+
|
|
46
|
+
## Migration path
|
|
47
|
+
|
|
48
|
+
1. Ship gate in warn mode (missing digests do not fail)
|
|
49
|
+
2. Start recording digests on activation / promote
|
|
50
|
+
3. Enable `--enforce` or project policy when ready
|
|
51
|
+
|
|
52
|
+
## Remediation
|
|
53
|
+
|
|
54
|
+
Re-record the approved-scope file after human review of the expanded `file_scope`. Editing the xBRIEF alone does not authorize new implementation paths.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Test / source boundary (`verify:test-boundary`)
|
|
2
|
+
|
|
3
|
+
Refs: #3145 · Related: #1310 forward-coverage, testing layout guidance
|
|
4
|
+
|
|
5
|
+
## Problem
|
|
6
|
+
|
|
7
|
+
Directive accepted test harnesses, fixtures, and smoke orchestration under production-owned roots (`src/**`, `infra/**`, `Tools/**`, …) while gates stayed green. Placement guidance was prose-only.
|
|
8
|
+
|
|
9
|
+
## Contract
|
|
10
|
+
|
|
11
|
+
`task verify:test-boundary` / `deft verify:test-boundary` enforces a typed policy:
|
|
12
|
+
|
|
13
|
+
| Field | Meaning |
|
|
14
|
+
| --- | --- |
|
|
15
|
+
| `sourceRoots` | Production-owned path globs |
|
|
16
|
+
| `testRoots` | Allowed test roots |
|
|
17
|
+
| `fixtureRoots` | Fixture roots |
|
|
18
|
+
| `testFilePatterns` | Conventional test basenames (`test_*.py`, `*Tests.cs`, `*.test.ts`, `*.spec.ts`, …) |
|
|
19
|
+
| `productionMayReferenceTestRoots` | Default `false` — production must not reference test/fixture roots |
|
|
20
|
+
| `allow` | Narrow exceptions (`kind: exception` or `production-liveness`) |
|
|
21
|
+
| `enforcementMode` | `warn` (migration/discovery) or `enforce` |
|
|
22
|
+
|
|
23
|
+
## Policy sources (first wins)
|
|
24
|
+
|
|
25
|
+
1. `--policy <path>`
|
|
26
|
+
2. `.deft/test-boundary.policy.json`
|
|
27
|
+
3. `plan.policy.testBoundary` in `xbrief/PROJECT-DEFINITION.xbrief.json`
|
|
28
|
+
4. **Defaults** (conventional roots + patterns, `enforcementMode: warn`)
|
|
29
|
+
|
|
30
|
+
## Migration path
|
|
31
|
+
|
|
32
|
+
1. Run with defaults (warn-only): `task verify:test-boundary`
|
|
33
|
+
2. Review findings; move test artifacts under declared test roots or classify production liveness/canaries in `allow`
|
|
34
|
+
3. Persist reviewed policy under `.deft/test-boundary.policy.json` or `plan.policy.testBoundary` with `enforcementMode: "enforce"`
|
|
35
|
+
4. Wire stays green via `task check` / consumer deposit
|
|
36
|
+
|
|
37
|
+
## Production liveness carve-out
|
|
38
|
+
|
|
39
|
+
Health probes, canaries, and operational evidence collectors may live under production roots when listed in `allow` with `kind: "production-liveness"` and a recorded reason. Do not use the word “smoke” alone as classification.
|
|
40
|
+
|
|
41
|
+
## Remediation
|
|
42
|
+
|
|
43
|
+
Failures name the path, violated boundary, and next step (move under test root, allow entry, or reclassify). See `content/contracts/test-boundary.md`.
|
package/main.md
CHANGED
|
@@ -71,6 +71,35 @@ See #634, #642. See [ADR-001](./docs/decisions/ADR-001.md) for the token-economi
|
|
|
71
71
|
- ⊗ Continue executing a skill past its explicit instruction boundary — when a skill's steps are complete, stop and return to the calling context; do not drift into adjacent work (#198)
|
|
72
72
|
- ! The end of a skill's final step is an exit condition — do not continue into adjacent work, even if it seems related or trivial
|
|
73
73
|
|
|
74
|
+
## Dual Stop Rule (#2442)
|
|
75
|
+
|
|
76
|
+
Loop engineering requires **two** stop conditions on multi-iteration autonomous work: a **success stop** (goal / AC / checker met) and a **failure or budget stop** (retries exhausted, no progress, or time/token budget). Directive already has strong success-shaped gates (`task check`, acceptance criteria, STOP on plan precondition mismatch -- #1613). This section requires the complementary failure envelope so agents escalate instead of thrashing forever.
|
|
77
|
+
|
|
78
|
+
**Applies to:** multi-iteration autonomous loops -- build quality / implement-fix loops, pre-PR polish cycles, swarm repair and monitor loops, research fan-out, review fix cycles, and similar retrying work.
|
|
79
|
+
|
|
80
|
+
**Does not apply to:** single-turn tasks (one shot answer, one file edit, one status probe). Not every task is a loop; do not invent iteration caps where there is no multi-step retry envelope.
|
|
81
|
+
|
|
82
|
+
**Required stops on every multi-iteration loop:**
|
|
83
|
+
|
|
84
|
+
1. ! **Success stop** -- goal, acceptance criteria, or checker is met; exit the loop and continue the skill or report done.
|
|
85
|
+
2. ! **Failure stop** -- at least one of:
|
|
86
|
+
- **max iterations** (task-class default; e.g. a short quality-fix class vs a longer research class)
|
|
87
|
+
- **no-progress** (same outcome or same failure fingerprint N times in a row with no material change)
|
|
88
|
+
- **explicit budget** (time, tool-call, or token budget when the host exposes it)
|
|
89
|
+
|
|
90
|
+
**On failure stop:**
|
|
91
|
+
|
|
92
|
+
- ! Halt the loop. Do not silently continue, re-dispatch, or open a new identical attempt without an operator decision.
|
|
93
|
+
- ! Emit an **operator-visible halt report** that states: (a) what was tried, (b) what is still missing or failing, (c) what human decision is needed next (scope change, unblock, override, or abandon).
|
|
94
|
+
- ⊗ Keep iterating after the failure envelope is exhausted because "one more try" might work.
|
|
95
|
+
- ⊗ Reset iteration counters solely by creating a new revision, swapping workers, or compacting context when the same failure class remains.
|
|
96
|
+
|
|
97
|
+
**Relation to other rules:**
|
|
98
|
+
|
|
99
|
+
- #1613 covers STOP when plan **preconditions** fail (reality mismatch). Dual stop covers the case where the plan is still "valid" but the agent must quit after N failed attempts, N identical no-progress outcomes, or a budget limit.
|
|
100
|
+
- Skills name concrete defaults: `skills/deft-directive-build/SKILL.md` (implement / pre-PR loops), `skills/deft-directive-swarm/SKILL.md` and its Phase 4 / core-ops references (repair / monitor loops).
|
|
101
|
+
- **Delivery / acceptance mechanical enforcement** (durable attempt ledger, material-progress circuit breaker, cross-revision budgets) is **#3143** — library: `packages/core/src/delivery-attempt/` (`evaluatePreDispatch`, unit ledger under `.deft/delivery-attempts/`). Docs: `content/docs/delivery-attempt.md`. #2442 is the principle + skill defaults; #3143 is the deterministic pre-dispatch gate. Route delivery/acceptance loops through that surface rather than inventing a parallel ledger.
|
|
102
|
+
|
|
74
103
|
**Adaptive Teaching:**
|
|
75
104
|
- ~ When a recommendation is accepted without question, be concise
|
|
76
105
|
- ! When a recommendation is questioned or overridden, explain the reasoning
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deftai/directive-content",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.97.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",
|
|
@@ -35,6 +35,16 @@
|
|
|
35
35
|
"path": "patterns/llm-app.md",
|
|
36
36
|
"body": null
|
|
37
37
|
},
|
|
38
|
+
{
|
|
39
|
+
"id": "operator-log-hygiene",
|
|
40
|
+
"title": "Operator-log hygiene (#1940)",
|
|
41
|
+
"description": "Consumer guidance for structured, operator-facing logs: six failure modes, anti-patterns, positive rules, explicit non-goals (no core schema, no default-on, not Insights/LLM telemetry). SLizard is external reference only. Checklist and optional consumer pack stub under docs/.",
|
|
42
|
+
"triggers": [
|
|
43
|
+
"operator-log-hygiene"
|
|
44
|
+
],
|
|
45
|
+
"path": "patterns/operator-log-hygiene.md",
|
|
46
|
+
"body": null
|
|
47
|
+
},
|
|
38
48
|
{
|
|
39
49
|
"id": "multi-agent",
|
|
40
50
|
"title": "Multi-agent identity separation pattern (#983)",
|