@deftai/directive-content 0.95.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.
Files changed (42) hide show
  1. package/QUICK-START.md +2 -0
  2. package/Taskfile.yml +28 -0
  3. package/UPGRADING.md +69 -0
  4. package/commands.md +30 -5
  5. package/contracts/test-boundary.md +18 -0
  6. package/docs/consumer-check-contract.md +27 -0
  7. package/docs/consumer-issue-label-kit.md +211 -0
  8. package/docs/delivery-attempt.md +173 -0
  9. package/docs/getting-started.md +2 -0
  10. package/docs/openclaw-agent-host.md +58 -7
  11. package/docs/operator-log-hygiene-checklist.md +57 -0
  12. package/docs/operator-log-hygiene-consumer-pack-stub.md +75 -0
  13. package/docs/scope-provenance.md +54 -0
  14. package/docs/test-boundary.md +43 -0
  15. package/main.md +29 -0
  16. package/package.json +1 -1
  17. package/packs/patterns/patterns-pack-0.1.json +10 -0
  18. package/packs/skills/skills-pack-0.1.json +8 -11
  19. package/patterns/operator-log-hygiene.md +130 -0
  20. package/scm/github.md +35 -3
  21. package/skills/deft-directive-article-review/SKILL.md +17 -6
  22. package/skills/deft-directive-build/SKILL.md +41 -0
  23. package/skills/deft-directive-refinement/SKILL.md +1 -3
  24. package/skills/deft-directive-review-cycle/SKILL.md +166 -12
  25. package/skills/deft-directive-swarm/SKILL.md +36 -11
  26. package/skills/deft-directive-swarm/references/core-ops.md +16 -3
  27. package/skills/deft-directive-swarm/references/core-phase-0.md +40 -15
  28. package/skills/deft-directive-swarm/references/core-phase-3.md +18 -9
  29. package/skills/deft-directive-swarm/references/core-phase-4.md +21 -2
  30. package/skills/deft-directive-swarm/references/core-phase-5-6.md +18 -1
  31. package/skills/deft-directive-swarm/references/host-claude-code.md +86 -0
  32. package/skills/deft-directive-swarm/references/host-cursor.md +1 -1
  33. package/skills/deft-directive-swarm/references/host-openclaw.md +12 -4
  34. package/skills/deft-directive-triage/SKILL.md +19 -6
  35. package/skills/deft-directive-xbrief/SKILL.md +0 -1
  36. package/tasks/cache.yml +31 -0
  37. package/tasks/engine-invoke.cjs +22 -17
  38. package/tasks/engine-invoke.test.cjs +30 -0
  39. package/tasks/verify.yml +30 -0
  40. package/templates/agent-prompt-preamble.md +15 -4
  41. package/templates/agents-entry.md +11 -0
  42. package/templates/swarm-greptile-poller-prompt.md +4 -2
@@ -80,6 +80,8 @@ checks tools without rewriting consumer-managed files.
80
80
 
81
81
  If you are adopting Deft on a project that already has an issue tracker (existing repo, brownfield migration, an upstream bug list that has been accumulating), you do not have to start from an empty `xbrief/proposed/`. The refinement skill's **Phase 0 triage workflow** lets you walk an existing backlog locally, decide what to keep, and let only the **accepted** items land in `xbrief/proposed/`. Trigger words: **"triage"**, **"work the cache"**, **"pre-ingest"**, **"action menu"**.
82
82
 
83
+ **Labels first:** capacity and triage matchers only help when labels exist. For a bare or thin label set, adopt the [consumer issue-label kit](./consumer-issue-label-kit.md) (#2611) before you rely on ranking or `triage:classify -- --mirror`.
84
+
83
85
  ### Step 1 — Scoped first populate
84
86
 
85
87
  A real-sized backlog can drain the shared GitHub GraphQL bucket if you fetch everything at once (see [#976](https://github.com/deftai/directive/issues/976) for the recurring symptom). Scope the first populate so it lands in seconds rather than minutes:
@@ -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 |
@@ -204,7 +239,7 @@ deft doctor --fix --openclaw-all-agents
204
239
 
205
240
  ---
206
241
 
207
- ## Swarm on OpenClaw (#2929 / #2934 / #2943)
242
+ ## Swarm on OpenClaw (#2929 / #2934 / #2943 / #3131)
208
243
 
209
244
  ! For **parallel** swarm leaves on OpenClaw:
210
245
 
@@ -214,16 +249,20 @@ deft doctor --fix --openclaw-all-agents
214
249
 
215
250
  ! 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…”.
216
251
 
217
- ### Parent-monitor after `subagent_announce` (#2943)
252
+ ### Parent-monitor after `subagent_announce` (#2943 / hard-stop #3131)
218
253
 
219
- 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.
254
+ 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. Soft skill prose alone is **not** enough (#2943 closed; recurrence under production → **#3131**).
220
255
 
221
- ! After any leaf completion event (`subagent_announce` / parent-push completion), the parent’s **first response** MUST be **tool-first** or **yield**:
256
+ ! After any leaf completion event (`subagent_announce` / parent-push completion), the parent’s **first response** MUST be exactly one of:
222
257
 
223
- 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**
224
- 2. **`sessions_yield`** (or host equivalent yield) — leave the turn steerable without narrating unfinished work.
258
+ 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), then one consolidate, **or**
259
+ 2. **`sessions_yield`** (or host equivalent yield / wait) — leave the turn steerable without narrating unfinished work, **or**
260
+ 3. **One short user answer** that is **not** a repeated progress line.
225
261
 
226
262
  ⊗ 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.
263
+ ⊗ Emit **N>2** near-identical assistant sentences (or streaming text chunks) in one turn with no `tool_use` / yield — **FC14 text-repetition hang** (illegal turn shape; hard-stop).
264
+
265
+ ! **Machine check (hard-stop, not prose-only):** `evaluateParentTurnShape` in `@deftai/directive-core` / `@deftai/directive-core/parent-turn-shape` (`packages/core/src/parent-turn-shape/`). Hosts and parents SHOULD feed ordered turn events (`assistant_text` / `tool_use` / `yield`) mid-stream; when `ok === false` and `failClass` is `FC14` (or `progress-only-no-tool` after announce), **abort the turn** / force tool-or-yield — do not burn the output budget. Soft skill text is **not** the sole mitigation.
227
266
 
228
267
  ! **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.
229
268
 
@@ -231,6 +270,16 @@ OpenClaw parents can lock into a **text-only repetition hang** after thin leaf c
231
270
 
232
271
  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.
233
272
 
273
+ ### Operator recovery — FC14 parent hang on current OpenClaw beta pins (#3131)
274
+
275
+ When the Control UI / parent seat is stuck replaying the same progress sentence with no tools:
276
+
277
+ 1. **Abort the parent turn** (Control UI stop / interrupt / cancel generation). Do **not** wait for length-cap.
278
+ 2. **Do not assume leaves failed.** Check worktrees, open PRs, and xBRIEF state with a **tool-first** batch from a fresh parent turn (`gh` / `git` / files). Leaves may already be DONE or mid-review.
279
+ 3. **Resume with a legal shape only:** tool-first ground truth, `sessions_yield`, or one short non-repeated answer. ⊗ Restart by pasting more “checking next…” prose.
280
+ 4. **If the hang returns immediately:** refresh Directive deposit (`npm i -g @deftai/directive@latest` then `directive update` / `deft update` / `deft doctor --fix` for OpenClaw skill pins — see § Wire skills into OpenClaw workspace), re-open the parent with current `openclaw-agent-host` + swarm host adapter text, and re-dispatch only after ground truth.
281
+ 5. **Host pin note:** On OpenClaw beta pins that do not yet call `evaluateParentTurnShape` in the stream, the operator abort in step 1 **is** the hard stop. Directive still ships the machine-check library + skill/docs so soft prose is not the only mitigation once the host wires it (or an agent-side gate evaluates a recorded turn). Surface `FC14` in notes when reporting the incident.
282
+
234
283
  ## Anti-patterns
235
284
 
236
285
  - ⊗ Main-session `gh` poll + **cron** as the default babysit path when the installed skill offers a Tier 1 / background monitor.
@@ -239,9 +288,11 @@ Full rules: [`skills/deft-directive-swarm/references/host-openclaw.md`](../skill
239
288
  - ⊗ Substituting host-native review theater for `deft-directive-review-cycle` on Deft-managed repos.
240
289
  - ⊗ Claiming this doc alone makes `sessions_spawn` a shipped register/matrix primitive — that is epic skill/engine work (#2875 / #2876).
241
290
  - ⊗ Multi-sentence progress-only first response after `subagent_announce` with zero tools / yield (#2943 text-repetition hang).
291
+ - ⊗ N>2 near-identical assistant sentences in one turn with no tool_use / yield (FC14 / #3131 hard-stop).
242
292
  - ⊗ Treating thin DONE (no PR URL / merge evidence) as success (#2943).
243
293
  - ⊗ Assuming package install alone populates OpenClaw `available_skills` — wire main workspace pins via `deft doctor --fix` (#3001).
244
294
  - ⊗ Auto-enumerating every `workspace-*` seat without `--openclaw-all-agents` (#3001).
295
+ - ⊗ Relying on soft skill prose alone as the sole mitigation for the parent hang (#3131).
245
296
 
246
297
  ---
247
298
 
@@ -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.95.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)",