@deftai/directive-runtime 0.126.0-beta.1 → 0.126.0-beta.3

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 (212) hide show
  1. package/UPGRADING.md +4 -3
  2. package/commands.md +9 -6
  3. package/contracts/design-critique.md +39 -1
  4. package/contracts/human-origin-authz.md +14 -8
  5. package/dist/coverage-hotspots.d.ts +3 -0
  6. package/dist/coverage-hotspots.js +42 -2
  7. package/dist/doctor-diagnose.d.ts +1 -1
  8. package/dist/doctor-diagnose.js +29 -3
  9. package/dist/doctor.js +1 -1
  10. package/dist/occupancy-release.d.ts +5 -0
  11. package/dist/occupancy-release.js +11 -3
  12. package/dist/policy.d.ts +2 -0
  13. package/dist/policy.js +6 -0
  14. package/dist/session-start.js +28 -1
  15. package/dist/triage-actions.js +10 -2
  16. package/dist/verify-review-monitor.d.ts +7 -0
  17. package/dist/verify-review-monitor.js +21 -0
  18. package/docs/framework-gap-filing.md +85 -0
  19. package/docs/getting-started.md +13 -1
  20. package/docs/product-signal.md +1 -1
  21. package/package.json +1 -1
  22. package/packs/skills/skills-pack-0.1.json +10 -7
  23. package/packs/strategies/strategies-pack-0.1.json +32 -19
  24. package/scm/github.md +1 -1
  25. package/skills/deft-directive-article-review/SKILL.md +104 -24
  26. package/skills/deft-directive-design-critique/SKILL.md +10 -9
  27. package/skills/deft-directive-feedback/SKILL.md +37 -21
  28. package/skills/deft-directive-pre-pr/SKILL.md +14 -0
  29. package/skills/deft-directive-product-signal/SKILL.md +1 -1
  30. package/skills/deft-directive-review-cycle/SKILL.md +18 -1
  31. package/skills/deft-directive-setup/SKILL.md +41 -11
  32. package/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
  33. package/skills/deft-directive-tutorial/SKILL.md +1 -1
  34. package/strategies/README.md +1 -0
  35. package/strategies/artifact-guards.md +2 -2
  36. package/strategies/design-thinking.md +182 -0
  37. package/strategies/discuss.md +2 -0
  38. package/strategies/interview.md +76 -23
  39. package/strategies/rapid.md +22 -12
  40. package/templates/agents-entry.md +4 -3
  41. package/templates/design-critique-brief.md +5 -1
  42. package/tutorial/beats.json +2 -2
  43. package/vendor/directive-content/UPGRADING.md +4 -3
  44. package/vendor/directive-content/commands.md +9 -6
  45. package/vendor/directive-content/contracts/design-critique.md +39 -1
  46. package/vendor/directive-content/contracts/human-origin-authz.md +14 -8
  47. package/vendor/directive-content/docs/framework-gap-filing.md +85 -0
  48. package/vendor/directive-content/docs/getting-started.md +13 -1
  49. package/vendor/directive-content/docs/product-signal.md +1 -1
  50. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +10 -7
  51. package/vendor/directive-content/packs/strategies/strategies-pack-0.1.json +32 -19
  52. package/vendor/directive-content/scm/github.md +1 -1
  53. package/vendor/directive-content/skills/deft-directive-article-review/SKILL.md +104 -24
  54. package/vendor/directive-content/skills/deft-directive-design-critique/SKILL.md +10 -9
  55. package/vendor/directive-content/skills/deft-directive-feedback/SKILL.md +37 -21
  56. package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +14 -0
  57. package/vendor/directive-content/skills/deft-directive-product-signal/SKILL.md +1 -1
  58. package/vendor/directive-content/skills/deft-directive-review-cycle/SKILL.md +18 -1
  59. package/vendor/directive-content/skills/deft-directive-setup/SKILL.md +41 -11
  60. package/vendor/directive-content/skills/deft-directive-swarm/references/host-grok-build.md +1 -1
  61. package/vendor/directive-content/skills/deft-directive-tutorial/SKILL.md +1 -1
  62. package/vendor/directive-content/strategies/README.md +1 -0
  63. package/vendor/directive-content/strategies/artifact-guards.md +2 -2
  64. package/vendor/directive-content/strategies/design-thinking.md +182 -0
  65. package/vendor/directive-content/strategies/discuss.md +2 -0
  66. package/vendor/directive-content/strategies/interview.md +76 -23
  67. package/vendor/directive-content/strategies/rapid.md +22 -12
  68. package/vendor/directive-content/templates/agents-entry.md +4 -3
  69. package/vendor/directive-content/templates/design-critique-brief.md +5 -1
  70. package/vendor/directive-content/tutorial/beats.json +2 -2
  71. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  72. package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts +11 -1
  73. package/vendor/directive-core/dist/content-contracts/skills/helpers.d.ts.map +1 -1
  74. package/vendor/directive-core/dist/content-contracts/skills/helpers.js +18 -5
  75. package/vendor/directive-core/dist/content-contracts/skills/helpers.js.map +1 -1
  76. package/vendor/directive-core/dist/coverage-applicability/evaluate.d.ts.map +1 -1
  77. package/vendor/directive-core/dist/coverage-applicability/evaluate.js +39 -0
  78. package/vendor/directive-core/dist/coverage-applicability/evaluate.js.map +1 -1
  79. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts +24 -5
  80. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts.map +1 -1
  81. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js +89 -8
  82. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js.map +1 -1
  83. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts +40 -0
  84. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.d.ts.map +1 -1
  85. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js +116 -0
  86. package/vendor/directive-core/dist/design-critique/auto-stamp-path1.js.map +1 -1
  87. package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts +36 -0
  88. package/vendor/directive-core/dist/design-critique/citation-grammar.d.ts.map +1 -1
  89. package/vendor/directive-core/dist/design-critique/citation-grammar.js +60 -3
  90. package/vendor/directive-core/dist/design-critique/citation-grammar.js.map +1 -1
  91. package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts +103 -3
  92. package/vendor/directive-core/dist/design-critique/completed-arc-record.d.ts.map +1 -1
  93. package/vendor/directive-core/dist/design-critique/completed-arc-record.js +127 -5
  94. package/vendor/directive-core/dist/design-critique/completed-arc-record.js.map +1 -1
  95. package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts +27 -0
  96. package/vendor/directive-core/dist/design-critique/ingest-posture.d.ts.map +1 -0
  97. package/vendor/directive-core/dist/design-critique/ingest-posture.js +66 -0
  98. package/vendor/directive-core/dist/design-critique/ingest-posture.js.map +1 -0
  99. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts +106 -7
  100. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.d.ts.map +1 -1
  101. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js +284 -17
  102. package/vendor/directive-core/dist/design-critique/panel-handback-acceptance.js.map +1 -1
  103. package/vendor/directive-core/dist/docs/docs-impact.d.ts +13 -0
  104. package/vendor/directive-core/dist/docs/docs-impact.d.ts.map +1 -1
  105. package/vendor/directive-core/dist/docs/docs-impact.js +49 -4
  106. package/vendor/directive-core/dist/docs/docs-impact.js.map +1 -1
  107. package/vendor/directive-core/dist/doctor/main.d.ts +48 -0
  108. package/vendor/directive-core/dist/doctor/main.d.ts.map +1 -1
  109. package/vendor/directive-core/dist/doctor/main.js +221 -4
  110. package/vendor/directive-core/dist/doctor/main.js.map +1 -1
  111. package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
  112. package/vendor/directive-core/dist/hooks/dispatcher.js +160 -14
  113. package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
  114. package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts +4 -0
  115. package/vendor/directive-core/dist/init-deposit/agent-hooks.d.ts.map +1 -1
  116. package/vendor/directive-core/dist/init-deposit/agent-hooks.js +25 -4
  117. package/vendor/directive-core/dist/init-deposit/agent-hooks.js.map +1 -1
  118. package/vendor/directive-core/dist/init-deposit/skill-discovery-deposit.d.ts.map +1 -1
  119. package/vendor/directive-core/dist/init-deposit/skill-discovery-deposit.js +15 -0
  120. package/vendor/directive-core/dist/init-deposit/skill-discovery-deposit.js.map +1 -1
  121. package/vendor/directive-core/dist/intake/issue-ingest.d.ts +15 -0
  122. package/vendor/directive-core/dist/intake/issue-ingest.d.ts.map +1 -1
  123. package/vendor/directive-core/dist/intake/issue-ingest.js +190 -22
  124. package/vendor/directive-core/dist/intake/issue-ingest.js.map +1 -1
  125. package/vendor/directive-core/dist/pr-closing-keywords/detect.d.ts.map +1 -1
  126. package/vendor/directive-core/dist/pr-closing-keywords/detect.js +52 -7
  127. package/vendor/directive-core/dist/pr-closing-keywords/detect.js.map +1 -1
  128. package/vendor/directive-core/dist/pr-watch/main.d.ts +5 -0
  129. package/vendor/directive-core/dist/pr-watch/main.d.ts.map +1 -1
  130. package/vendor/directive-core/dist/pr-watch/main.js.map +1 -1
  131. package/vendor/directive-core/dist/pr-watch/watch.d.ts.map +1 -1
  132. package/vendor/directive-core/dist/pr-watch/watch.js +5 -0
  133. package/vendor/directive-core/dist/pr-watch/watch.js.map +1 -1
  134. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts.map +1 -1
  135. package/vendor/directive-core/dist/pre-pr-controller/controller.js +118 -12
  136. package/vendor/directive-core/dist/pre-pr-controller/controller.js.map +1 -1
  137. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts +1 -1
  138. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts.map +1 -1
  139. package/vendor/directive-core/dist/pre-pr-controller/index.js +1 -1
  140. package/vendor/directive-core/dist/pre-pr-controller/index.js.map +1 -1
  141. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts +5 -0
  142. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts.map +1 -1
  143. package/vendor/directive-core/dist/pre-pr-controller/phases.js +10 -0
  144. package/vendor/directive-core/dist/pre-pr-controller/phases.js.map +1 -1
  145. package/vendor/directive-core/dist/presentation-ceiling/evaluate.d.ts.map +1 -1
  146. package/vendor/directive-core/dist/presentation-ceiling/evaluate.js +3 -1
  147. package/vendor/directive-core/dist/presentation-ceiling/evaluate.js.map +1 -1
  148. package/vendor/directive-core/dist/release/auto-hatch.d.ts +6 -0
  149. package/vendor/directive-core/dist/release/auto-hatch.d.ts.map +1 -1
  150. package/vendor/directive-core/dist/release/auto-hatch.js +13 -4
  151. package/vendor/directive-core/dist/release/auto-hatch.js.map +1 -1
  152. package/vendor/directive-core/dist/review-monitor/record.d.ts +11 -0
  153. package/vendor/directive-core/dist/review-monitor/record.d.ts.map +1 -1
  154. package/vendor/directive-core/dist/review-monitor/record.js +23 -0
  155. package/vendor/directive-core/dist/review-monitor/record.js.map +1 -1
  156. package/vendor/directive-core/dist/run-summary/emit.d.ts +2 -1
  157. package/vendor/directive-core/dist/run-summary/emit.d.ts.map +1 -1
  158. package/vendor/directive-core/dist/run-summary/emit.js +3 -0
  159. package/vendor/directive-core/dist/run-summary/emit.js.map +1 -1
  160. package/vendor/directive-core/dist/run-summary/index.d.ts +1 -1
  161. package/vendor/directive-core/dist/run-summary/index.d.ts.map +1 -1
  162. package/vendor/directive-core/dist/run-summary/index.js.map +1 -1
  163. package/vendor/directive-core/dist/run-summary/types.d.ts +8 -2
  164. package/vendor/directive-core/dist/run-summary/types.d.ts.map +1 -1
  165. package/vendor/directive-core/dist/run-summary/types.js +1 -0
  166. package/vendor/directive-core/dist/run-summary/types.js.map +1 -1
  167. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +11 -0
  168. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
  169. package/vendor/directive-core/dist/scope/delivery-evidence.js +34 -0
  170. package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
  171. package/vendor/directive-core/dist/scope/promote-from-issue.d.ts +2 -1
  172. package/vendor/directive-core/dist/scope/promote-from-issue.d.ts.map +1 -1
  173. package/vendor/directive-core/dist/scope/promote-from-issue.js +17 -61
  174. package/vendor/directive-core/dist/scope/promote-from-issue.js.map +1 -1
  175. package/vendor/directive-core/dist/session/occupancy-recovery.d.ts +10 -0
  176. package/vendor/directive-core/dist/session/occupancy-recovery.d.ts.map +1 -1
  177. package/vendor/directive-core/dist/session/occupancy-recovery.js +43 -7
  178. package/vendor/directive-core/dist/session/occupancy-recovery.js.map +1 -1
  179. package/vendor/directive-core/dist/session/occupancy.d.ts +148 -1
  180. package/vendor/directive-core/dist/session/occupancy.d.ts.map +1 -1
  181. package/vendor/directive-core/dist/session/occupancy.js +516 -34
  182. package/vendor/directive-core/dist/session/occupancy.js.map +1 -1
  183. package/vendor/directive-core/dist/session/session-start.d.ts.map +1 -1
  184. package/vendor/directive-core/dist/session/session-start.js +6 -1
  185. package/vendor/directive-core/dist/session/session-start.js.map +1 -1
  186. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.d.ts.map +1 -1
  187. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js +5 -1
  188. package/vendor/directive-core/dist/swarm/cohort-review-monitors-cli.js.map +1 -1
  189. package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts +71 -0
  190. package/vendor/directive-core/dist/swarm/cohort-review-monitors.d.ts.map +1 -1
  191. package/vendor/directive-core/dist/swarm/cohort-review-monitors.js +125 -2
  192. package/vendor/directive-core/dist/swarm/cohort-review-monitors.js.map +1 -1
  193. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.d.ts.map +1 -1
  194. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js +9 -0
  195. package/vendor/directive-core/dist/telemetry-coverage/fake-trial.js.map +1 -1
  196. package/vendor/directive-core/dist/telemetry-coverage/kinds.d.ts.map +1 -1
  197. package/vendor/directive-core/dist/telemetry-coverage/kinds.js +2 -0
  198. package/vendor/directive-core/dist/telemetry-coverage/kinds.js.map +1 -1
  199. package/vendor/directive-core/dist/triage/actions/index.d.ts +8 -5
  200. package/vendor/directive-core/dist/triage/actions/index.d.ts.map +1 -1
  201. package/vendor/directive-core/dist/triage/actions/index.js +248 -22
  202. package/vendor/directive-core/dist/triage/actions/index.js.map +1 -1
  203. package/vendor/directive-core/dist/triage/actions/types.d.ts +16 -2
  204. package/vendor/directive-core/dist/triage/actions/types.d.ts.map +1 -1
  205. package/vendor/directive-core/dist/triage/bulk/index.d.ts +8 -1
  206. package/vendor/directive-core/dist/triage/bulk/index.d.ts.map +1 -1
  207. package/vendor/directive-core/dist/triage/bulk/index.js +30 -11
  208. package/vendor/directive-core/dist/triage/bulk/index.js.map +1 -1
  209. package/vendor/directive-core/dist/value/feedback-file.d.ts +54 -6
  210. package/vendor/directive-core/dist/value/feedback-file.d.ts.map +1 -1
  211. package/vendor/directive-core/dist/value/feedback-file.js +470 -43
  212. package/vendor/directive-core/dist/value/feedback-file.js.map +1 -1
package/UPGRADING.md CHANGED
@@ -695,9 +695,10 @@ After Wave 8, live deft gates run through the TypeScript engine. **The consumer
695
695
 
696
696
  ## From v0.53.0–v0.53.1 → v0.53.2 (vitest no longer discovers vendored framework tests, #1878)
697
697
 
698
- - **Applies when (historical):** projects that used **vitest** on v0.53.0 / v0.53.1 when a copied deposit still vendored framework `*.test.ts` / `*.spec.ts` under a legacy install tree. Detection then: vitest discovered ~80+ framework tests via its default include glob and CI failed with `ERR_MODULE_NOT_FOUND` for `@deftai/core`. Current OVPR installs do **not** copy a `.deft/core/` deposit — this bucket is archaeology for mid-upgrade PRs still on those versions.
699
- - **Safe to auto-run:** Yes on current tip. Prefer leaving the legacy deposit era entirely:
700
- - **Commands (current):**
698
+ - **Applies when:** historical — projects that used **vitest** on v0.53.0 / v0.53.1 when a copied deposit still vendored framework `*.test.ts` / `*.spec.ts` under a legacy install tree. Detection then: vitest discovered ~80+ framework tests via its default include glob and CI failed with `ERR_MODULE_NOT_FOUND` for `@deftai/core`. Current OVPR installs do **not** copy a `.deft/core/` deposit — this bucket is archaeology for mid-upgrade PRs still on those versions.
699
+ - **Safe to auto-run:** Yes on current tip. Prefer leaving the legacy deposit era entirely.
700
+ - **Restart required:** No.
701
+ - **Commands:**
701
702
  - `npm i -g @deftai/directive@latest` then `directive upgrade` (or `directive install --repair` when the pin should stay)
702
703
  - Interim manual workaround **only if you are mid-upgrade on a still-red historical v0.53.0/v0.53.1 PR that still has a copied deposit**: exclude the legacy deposit path from vitest, then re-run CI:
703
704
 
package/commands.md CHANGED
@@ -10,16 +10,18 @@ Legend (from RFC2119): !=MUST, ~=SHOULD, ≉=SHOULD NOT, ⊗=MUST NOT, ?=MAY.
10
10
 
11
11
  ## Overview
12
12
 
13
- The active implementation is xBRIEF lifecycle first and Taskfile first:
13
+ The active implementation is xBRIEF lifecycle first and Taskfile first, with `directive` / `deft` as the primary command surface (#4229; Taskfile / `task deft:<verb>` remains an optional parallel include after init):
14
14
 
15
15
  ```mermaid
16
16
  flowchart LR
17
- Proposed["proposed scope"] -->|"task scope:promote"| Pending["pending scope"]
18
- Pending -->|"task scope:activate"| Active["active scope"]
19
- Active -->|"task scope:complete"| Completed["completed scope"]
17
+ Proposed["proposed scope"] -->|"deft scope:promote"| Pending["pending scope"]
18
+ Pending -->|"deft scope:activate"| Active["active scope"]
19
+ Active -->|"deft scope:complete"| Completed["completed scope"]
20
20
  ```
21
21
 
22
- `task --list` is the authoritative command index. This file explains the main command families, the agent slash-command surface, and the older `/deft:directive:change` folder workflow that remains as historical/compatibility guidance.
22
+ The CLI commands listing prints every registered verb (see `directive --help`). After an include-only root Taskfile exists, `task --list` also shows `task deft:<verb>` aliases. This file explains the main command families, the agent slash-command surface, and the older `/deft:directive:change` folder workflow that remains as historical/compatibility guidance.
23
+
24
+ `xbrief:preflight` stays a when-invoked implement lock (not an unconditional host mutation interceptor). Missing go-task stays `#3335` impact=none when gates are CLI-dispatchable; doctor/session may print `status=Taskfile-unavailable; CLI-supported`.
23
25
 
24
26
  ---
25
27
 
@@ -442,7 +444,7 @@ After CLI/deposit upgrade, disk can show the new generation while a long-lived s
442
444
  - ! Default interactive sessions to **read-only posture** until mutation or implementation intent (questions, research, Plan Mode, ticket-shaping). Load AGENTS.md / main.md / USER.md / PROJECT-DEFINITION; confirm alignment with addressing-name; ⊗ do not write `.deft/ritual-state.json`, run install/build side effects, or emit triage welcome, branch-policy, default-branch sync, sync-skill lifecycle checks, or eval/value readback writes unless the operator asks or the task is implementation-ready.
443
445
  - ! **USER.md path (#2544):** resolve via `deft session:start` output (`USER.md resolved …`); default platform paths: Windows `%APPDATA%\deft\USER.md`, Unix `~/.config/deft/USER.md`; override `$DEFT_USER_PATH`; workspace `<project>/.deft/USER.md`. ⊗ Invent or search `~/.config/deft` on Windows — AppData Roaming is canonical.
444
446
  - ! At mutation boundaries (code-writing, scope lifecycle moves, `start_agent`, commits, pushes, PR-from-local-changes, release work): run the mutable quick tier then gated verifier below before proceeding.
445
- - ! **Identity-only + product mutation (#4544):** on the session-routing else-branch (`else main → USER → PROJECT-DEFINITION; ~ sync` then Mutation → `deft session:start`), when live PROJECT-DEFINITION is identity-only (empty `plan.items` and no convention-valid lifecycle scope) AND the live request has product mutation intent, join existing setup Phase 3 Starting-new / Rapid BEFORE that mutation `session:start`. After Phase 3 confirmation: write confirmed `plan.narratives.Overview` (Light narrative merge or an explicit Overview patch before render; Rapid Strategy Gate STOP must not skip that write) plus one `xbrief/proposed/` draft that carries the live request's requirement list through Rapid Step 3 and #3267 capture. Process-only stays an explicit exit. ⊗ Add `session:start --prompt`. ⊗ Auto-write `xbrief/active/` — promote and activate stay the existing verbs. Unmanaged header one-liner is placeholder-only compare-and-set from user-confirmed Overview (not a prompt interpolator; not identity source of truth). Handback reports the actual lifecycle outcome (`proposed <path>`, Process-only, or product-write-with-no-brief as a gate anomaly). Resolve the rapid compose pointer through `contentRoot` / the consumer deposit path. Under rapid, if this session changed product files and no brief exists, `deft check` reports the verify:ac soft-skip as a named warning.
447
+ - ! **Identity-only + product mutation (#4544):** on the session-routing else-branch (`else main → USER → PROJECT-DEFINITION; ~ sync` then Mutation → `deft session:start`), when live PROJECT-DEFINITION is identity-only (empty `plan.items` and no convention-valid lifecycle scope) AND the live request has product mutation intent, join existing setup Phase 3 Starting-new / Rapid BEFORE that mutation `session:start` (identity-only must not suppress Phase 3 when product mutation is requested; #4229). After Phase 3 confirmation: write confirmed `plan.narratives.Overview` (Light narrative merge or an explicit Overview patch before render; Rapid Strategy Gate STOP must not skip that write) plus one `xbrief/proposed/` draft that carries the live request's requirement list through Rapid Step 3 and #3267 capture. Process-only stays an explicit exit. ⊗ Add `session:start --prompt`. ⊗ Auto-write `xbrief/active/` — promote and activate stay the existing verbs. Unmanaged header one-liner is placeholder-only compare-and-set from user-confirmed Overview (not a prompt interpolator; not identity source of truth). Handback reports the actual lifecycle outcome (`proposed <path>`, Process-only, or product-write-with-no-brief as a gate anomaly). Resolve the rapid compose pointer through `contentRoot` / the consumer deposit path. Under rapid, if this session changed product files and no brief exists, `deft check` reports the verify:ac soft-skip as a named warning.
446
448
  - ? Explicit read-only alignment only: `deft session:start --read-only` (no ritual-state write). Task: `task session:start -- --read-only`.
447
449
  - ? Tracked docs/requirements without a story xBRIEF: `deft session:start --posture=requirements` (occupancy claimed; no gated ritual). Token is `requirements`; `docs` remains assist/scratch. Unknown --posture tokens refuse and print the closed set (owner: packages/core/src/session/posture.ts). Forge-only (#4020) is no-ingest with dest worktree permitted -- not a tree-write posture.
448
450
  - ! **Worktree occupancy contract (#3433 / #3604 / #3611 / #3926):** mutation `session:start` / `session:ready` claim a gitignored `.deft/occupancy.json` lease. Occupancy is cooperative host-session routing between processes that follow the protocol, not authentication against another same-user process: hook JSON and local owner IDs are forgeable. Name it for what it is (#3755): a **cooperative bearer-id boundary, not a lineage** — the lease admits whoever presents an id the record itself names, nothing observes parentage, and a dispatched child is admitted only because a grant records it. A live lease allows only a matching presented owner or member and a ritual state whose exact verified owner agrees; missing, conflicting, or mismatched identity fails closed. `--read-only` does not claim. A stored lease whose `worktree_path` is not this checkout is residue, not a holder: first mutation `session:start` claims over it. Same-tree two-session conflict still fails closed.
@@ -616,6 +618,7 @@ Directive does not guess your mix. Either you name the next units in order (**or
616
618
 
617
619
  ### Triage Tasks
618
620
 
621
+ - **Planning order (#5716):** triage write-back → arc or recorded `design-critique: not warranted, because …` → `issue:ingest` → scope. Sole skip is the recorded not-warranted line; silence is not a skip.
619
622
  - `task triage:bootstrap -- [--repo OWNER/NAME] [--limit N] [--state {open|closed|all}] [--batch-size N] [--delay-ms N]` -- seed the local triage cache and audit layer.
620
623
  - `task triage:evaluate -- <N...> [--concurrency N] [--repo OWNER/NAME] [--json]` -- Stage A isolated issue-eval (#3648). Detached `origin/master` worktrees own validity; the parent owns WIP census (`xbrief/active`, `xbrief/pending`, `plan-sequence`); GitHub REST owns open PRs/issues. Verdicts land under `.deft-scratch/issue-eval/<sha12>/<invocation-id>/`. No GitHub writes. Fan-out default 4. Value may set `critique-recommend:`; it must not emit `design-critique: warranted | not warranted, because …`. Decisions stay existing `triage:*` verbs.
621
624
  - `deft triage:queue --limit=10 [--author LOGIN|@me]` -- show ranked candidate work from cache-backed state. Optional `--author` / `--author-mine` filters to cache `author.login` (exact match; `@me` resolves via authenticated `gh`; comma allow-list; missing author disclosed as unknown) (#3129 / #1318 Layer 1). When the cache is empty, auto-populates from GitHub first (#2575) — do not conclude "nothing to do" from xBRIEF folders or live `gh issue list` alone (#2576).
@@ -13,6 +13,11 @@ This contract scaffolds the motion. Only the ADR-005 judgment gate and the conte
13
13
  - ⊗ Pin this contract or `skills/deft-directive-design-critique` into `templates/agents-entry.md` or the AGENTS.md always-pin list. Discovery is on-demand via the Skills Index.
14
14
  - ⊗ Auto-dispatch critics from this contract (#3578 / #1702). Operator (or parent after an operator verb) dispatches the next envelope from the brief template.
15
15
 
16
+ ### Pre-ingest recommendation (#5716)
17
+
18
+ Before `issue:ingest` for every GitHub issue, run the design-critique arc or record `design-critique: not warranted, because …`. ADR-005 is unchanged: no auto-dispatch, no engine refusal of unarced work. The ingest advisory is exit 0 and never blocks. This scaffolds the recommendation; content-contract tests lock the skip-form string. Discovery stays on-demand (no always-pin of this skill or contract path). Issue-less scopes use `## No-issue target archive (#5486)` — this GitHub ingest advisory does not extend there.
19
+
20
+
16
21
  ### The arc
17
22
 
18
23
  **An arc is one recorded motion over one target revision**, from the Stop 1 write-back (or a voluntary dispatch) through accepted synthesis or the halt line. It holds one or more rounds, and therefore one or more ceilings. An arc is per-target, not per-issue: one issue carries several arcs over time, and one arc can span several issues.
@@ -138,6 +143,15 @@ After Handoff, Stop 2 evaluation does not re-select charter from the issue body
138
143
 
139
144
  Default motion after a mechanism-shaped stamp: fresh open critique. N=1 (and N≥3 when recommend says so under panel permission) only after a resolved `n=` token, a recorded ask-answer, or a recorded `spend-recommend:` resolve. If residual remains, one reiterating pass with a fresh critic that reads a disagreement map, then verified synthesis. Resume is optional sharpening ("does my prior finding still hold"), not the default reiterating agent. A permitted N≥3 does not change that default; the parent records the spend when it uses the permission after parseOperatorSpend, an ask-answer, or a panel-permission-lawful `spend-recommend: N≥3`.
140
145
 
146
+ ### Target-kind (#5486)
147
+
148
+ **Target-kind** is what durable identity the arc binds (`issue` | `xbrief` | `envelope-file`). It is orthogonal to `### Target shape` (set-level / against-implementation) and does not select charter or spend.
149
+
150
+ - ! Record `Target-kind:` on the lean when the target is not a GitHub issue. Default remains `issue`.
151
+ - ! Target-digest hashes canonical target bytes for that kind (REST issue body, xBRIEF file bytes, or envelope-file bytes). Protocol / gate / chip state stays outside digested bytes.
152
+ - ! Envelope-file targets need durable bytes before Stop 1.
153
+ - ⊗ Treat Target-kind as a Target shape row or a charter/spend row.
154
+
141
155
  ### Target shape
142
156
 
143
157
  Charter is what the critic is given. **Target shape is what is being critiqued.** The two are independent axes, and target shape selects neither the charter nor the spend, so it is not a row in either table above.
@@ -205,6 +219,21 @@ The three tokens are the blocking, sharpening, and footnote classes `walk all` a
205
219
 
206
220
  The injection / swarm lens is a triggered MUST: it fires only on those target changes. The reviewer-catch rule is a prohibition, not a required recital. Road-not-taken and steelman are SHOULD, and fire only on a real fork.
207
221
 
222
+ ### Ceiling-kind (#5486)
223
+
224
+ **Ceiling-kind** names how same-round isolation is frozen:
225
+
226
+ | Ceiling-kind | Form |
227
+ |---|---|
228
+ | `comment-id` | GitHub comment id (existing issue path) |
229
+ | `dispatch-sha-outbox-manifest` | dispatch-sha + parent-written outbox manifest (stage-(0) file-path) |
230
+
231
+ - ! Stage-(0) file-path admits `PostconditionArtifactClass` `file-path` at the panel-handback caller (`panel-handback-acceptance.ts`). Obligation fields bind target-id/path; `issueNumber` is optional/N/A. Verdict returns non-numeric `boundArtifactId` alongside `boundCommentId`.
232
+ - ! Construct the outbox-manifest artifact in stage (0); do not defer to archive stage (b). Parent-collected exclusive-create per-seat outboxes feed the retained archive.
233
+ - ! Comment-id path stays unchanged. Do not weaken the GitHub-issue arc path.
234
+ - ⊗ Use bare file existence or chat-success as dispatch proof.
235
+ - ⊗ Fake 8+ digit local ids that collide with GitHub. Chosen local id-model is composite `arc-post:<n>` (published before parser accept).
236
+
208
237
  ### Envelope and ceiling
209
238
 
210
239
  The envelope is [`templates/design-critique-brief.md`](../templates/design-critique-brief.md). Fill fields. Do not copy rule bodies from this contract into the envelope.
@@ -733,7 +762,7 @@ Closed cite forms on the successor lean (no third coverage-map type):
733
762
 
734
763
  - `relieves: P1` / `relieves P1`
735
764
  - `does-not-relieve: P1`
736
- - `operator-deferred: P1 #4377` / `operator-deferred: P1 issue 4377`
765
+ - `operator-deferred: P1 #4377`; leftover brief cites `operator-deferred: P1 plan-id github.issue.123` / `operator-deferred: P1 path xbrief/proposed/example.xbrief.json` / `operator-deferred: P1 issue 4377`
737
766
 
738
767
  Uncited ids and `does-not-relieve` stay residual headings (`unrelieved-pain`). Unknown ids and conflicting dispositions fail closed as `malformed-pain`. `operator-deferred` must cite a **different** issue id; same-number leftover is `unrelieved-pain`, not yolo-confirmable leftover, and is halt or a later lean that binds relief, without ingest clearance.
739
768
 
@@ -801,3 +830,12 @@ This motion ingests untrusted issue threads by design.
801
830
  ## Test surface
802
831
 
803
832
  `packages/core/src/content-contracts/standards/design_critique_contract.test.ts` locks required pointer strings, the scaffolds framing, the comment-lead field as model then role from the closed set (not an issue label), the operator-gated loop (successor lean, operator verbs including walk / walk all, dual stop, halt line, exclusive remaining-set replace of the three catalog chips, #3640 auto-stamp on a non-empty all-accept map and no-stamp on stubs, first-lean recording obligation after this round's siblings are posted), the parent-side substantiation token and independence rules, the Stop 1 exclusion (pre-critic premises outside the trigger) and `refutation-target:` field tokens rather than full body sentences, the composed auto-bind conjunct (all-accept map AND zero unresolved audit markers) at Operator verbs and Bind path 1, the variant-table evaluation rule (charter selection and spend permission evaluated independently), the critic-method heading and distinctive obligation tokens (exact class tokens, citations-are-claims, existing mechanisms, injection / swarm trigger nouns, failed-reviewer phrase, finding anatomy) rather than full body sentences, the brief-template forbidden-inputs list, and the thin router skill (existence, line cap, pointer resolution, no-normative-content). `evaluateParentAudit` locks the omission failure modes. This suite locks the SoT MUST and the thin skill pointer for the first-lean recording obligation, including the auto-stamp operator-confirm conjunct and the no-bind-while-unposted-same-round-siblings rule. `evaluateCompletedArcRecord` locks ingest on the completed-arc record rather than a catalog chip. It does not fail-close live parent turns. `packages/core/src/design-critique/citation-grammar.test.ts` locks the `## Citation grammar` closed set, the refused positions, and the diagnostics surface; `packages/core/src/design-critique/completed-arc-record.test.ts` locks one parser for both questions, set membership against the latest lean, and the observation-echoing block details (#3831). Runtime parent-turn detection only if `evaluateParentAudit` is extended; that extension is not required to ship the recording obligation. Panel completeness is locked as contract text only. No predicate observes it on a live arc (#3850). N≥2 round-1 ceiling is the post-panel-deposit snapshot; Envelope Id ceiling stays authoritative; deposit/envelope mismatch is a finding, never a re-ceiling (#4435). Completeness stays unobservable to round-1 critics even with the deposit in envelope. Decomposition MUST plus multi-pointer forbid are locked as contract text; no new grammar and no new evaluator. `evaluatePanelSeatComposition` locks claimed-family composition and PATH paste-ready-first; it is a fixture over claimed families, not a live sibling-count gate, and it does not observe launchability. `evaluateN3LaunchProbe` locks the N≥3 launch-probe fixture: critic argv class with bypass flags, the existing benign pong, no envelope path, amend-spend or dispatch-fail on miss, and no new halt token (#4432). Does not close #3850. `### The arc` and its derived boundaries, the `### Target shape` axis with its twice-run caveat, and the two bind-path-2 non-empty refusals are locked as contract text (#3797). `## Plain-language summary` is locked the same way: the contract test pins the heading token, the MUST-not-SHOULD reasoning, the ADR-006 exemption and its limit, the non-normative marking, and the per-artifact reserved line-start matrix, and `packages/core/src/design-critique/reserved-line-starts.test.ts` exercises each of the five families on each artifact kind against the exported shape predicates and `evaluateCompletedArcRecord`. `packages/core/src/design-critique/handoff.ts` locks `evaluateHandoffPrint`, `evaluateDualStopReservedSlot`, and `postHandoffStop1Writeback`. Do not add `reframe-needed` to `evaluateCompletedArcRecord`. Do not halt Dual-stop on invariant-set equality. `evaluateCompletedArcRecord` observes presence-only `## In plain English` on `citedLeanId` + `synthesisCommentId` (#5415); closed reason `missing-plain-english`. A pointer-only Bound-remedy or comment-id summary is a published miss and stays unobserved by that presence check; both artifacts state the problem then the accepted solution in ordinary language, including auto-posted synthesis-accepted; the thin skill names `## Plain-language summary` and keeps `Plain English first in main-chat` as the widget surface; ingest-open protocol and "Ingest may proceed" stay off this heading. Content-contract tests lock those sentences. No prose-quality parser (#4309). `### Verified-claims table heading`, the closed reason vocabulary, and the re-measured line-start matrix are locked as contract text, and `completed-arc-record.test.ts` exercises the typed refusal partition: the two states, details that differ by more than the id, the untyped null table id, and the seven recorded live arc table ids (#3942). `### Run posture` and `parseOperatorRunPosture` / `evaluateDirectDispatch` lock the closed-token front door, the missing-token ask including yolo, the `session:start --read-only` start verb, stdin posting, SHA-pinned reads, and the no-worktree direct panel; `run-posture.test.ts` exercises those fixtures. `### Spend` and `parseOperatorSpend` / `evaluateSpendRecord` lock the closed-token spend front door, the missing-token ask including yolo, numeric-only resolved tokens, bare panel as ask, colliding classes as ask, Stop 1 `spend-ask: resolved|asked`, and that grok-bot detect does not default spend; `spend.test.ts` exercises those fixtures. Live parent turns stay unenforced (#4705). Does not close #3846. `evaluateCompletedArcRecord` ignores `arc-mode:` (#4072). Yolo standing confirm of a posted all-accept map, the disagree/defer-set refusal, word-boundary parse on the operator chat utterance, and that yolo-confirm is not ingest are locked as contract text plus content-contract tests; live parent turns stay unenforced (#4308). `evaluateAutoStampPath1Write` locks the lean-cite-only unpublished path-1 candidate, the full pain-coverage reason set, skip of ingest-ready remaining-set when path-1 is refused, and that `autoStamp: true` does not return empty verbs when Handoff applies (#4592). English-heading critic after the bind lean with no operative field refuses `writePath1` as `unresolved-pain-audit` (#4648). `packages/core/src/design-critique/leftover-pain.ts` locks yolo leftover-path recommendation, leftover issue-create recording, remainder continue, finish-still-possible, cite honesty and placement, pain-audit follow-through, Dual-stop posts-not-seats default 6 for spend N=1, and asserted reserved-slot coverage (#4593). Pain-audit dispatch fill of operative `audit-targets:` (ids or none), English Pain-audit headings are not targeting, later-arc critic after the bind lean id, footnote-only follow-through is not clearance, and that `buildPainCoverageDeposit` JSDoc does not recut the asserted-marker conjunct (#4648). Dual stop Fingerprint composition with #3448, the Parallel fingerprint working default that no comparable fingerprint exists for a parallel round, and that marker clearance has no verdict field are locked as contract text plus parent-audit tests (#4442). Yolo first-lean cites under standing (#4811) are locked as contract text plus the thin skill pointer: honest pain cites on the bind-capable first all-accept lean, no free-English intermediate hatch, uncited first map stays Handoff, do not recut evaluateHandoffPrint, pain-audit brief after operative first relieves while Dual-stop numbered or reserved slot remains, and Mid-arc EXIT does not default to operator next-envelope after that lean. Live parent turns may stay unenforced. Dual-stop raise stays a raise.
833
+
834
+ ## No-issue target archive (#5486)
835
+
836
+ When no GitHub issue exists, the durable arc record is a parent-owned ordered archive under a main-checkout-resolved root (`.deft/design-critique/archive`), keyed by target-id + arc-id. Dest-relative `.deft-scratch` is staging only, not archive root. Sidecar mirrors are optional with published read precedence; never two live SoTs. Machine-local / single-operator is the supported durability tier; cross-machine replication is deferred. Single-machine no-Issues consumers may use the archive.
837
+
838
+ Write posture (pick one): critics zero in-tree writes and parent collects exclusive-create outboxes into the archive (chosen). Harvest `## Bound remedy` into the same brief via plan-id-keyed idempotent update (`hashBoundRemedyBytes` key); do not use `issue:ingest` as the no-issue harvest path. Promotion keeps the archive authoritative with optional link/mirror and refuses two live arcs over one target.
839
+
840
+ Gate admission for no-issue targets is `evaluateNoIssueGateAdmission`: target identity + authoritative marker + completed-arc proof + live revision via adapter over `GATE_MATCH_PREDICATES` (paths / body-text). Storage fields alone are insufficient. Discovery/recovery or concrete manual-diagnosis path required. No fake GitHub labels.
841
+
@@ -89,17 +89,21 @@ deft authz:uat-suspend
89
89
  deft authz:revoke -- grant-…
90
90
  ```
91
91
 
92
- ## Gate-override hatch (#5542)
92
+ ## Gate-override hatch (#5542 / #5674)
93
93
 
94
94
  Mint + admission APIs for an audited interactive override bound to a coverage-
95
- applicability refuse. **This release ships grant minting and admission only.**
96
- Wiring that turns a live admission into a `waived` / exit-4 result on the pre-PR
97
- `coverage_headroom` / `deft coverage:hotspots` path is a follow-up PR; operators
98
- minting a grant here will still see the refuse until that consumer lands.
95
+ applicability refuse (#5542). Consumer wiring on pre-PR `coverage_headroom` /
96
+ `deft coverage:hotspots` lands as **exit 4** + distinct waived skip token with
97
+ admission-receipt re-verify (#5674). Measured Istanbul floor/headroom failure
98
+ still dominates when a coverage report exists. Exit 4 never maps to pass /
99
+ exit 0. Residual deposit keep-unknowns (run / hooks / codeql / approved-scope)
100
+ stay open on #5677. Classifier exact-path relief for ordinary managed
101
+ stamps/ledgers is #5665 — not this hatch.
99
102
 
100
103
  ```bash
101
104
  deft authz:grant -- --template gate-override --target <refuseCode> \
102
105
  --plan-ref <attemptId> --base-sha <sha> --head-sha <sha> --tree-hash <hash> [--confirm]
106
+ deft coverage:hotspots --attempt-id <attemptId>
103
107
  ```
104
108
 
105
109
  | Rule | Detail |
@@ -107,11 +111,11 @@ deft authz:grant -- --template gate-override --target <refuseCode> \
107
111
  | Mint provenance | `origin.kind=operator-cli` only via live `authz:grant` human-presence; `operator-session` non-admitting; refuse chat/parent/fixture consent |
108
112
  | Binding | gate id + refuse code + `baseSha+headSha+treeHash` + attempt id (+ optional worktree/evaluator) |
109
113
  | Admission | Atomic one-use via claim lock; inspection does **not** consume; same attempt reuses receipt; renew after revoke/expiry replaces under an attempt-id lock |
110
- | Result arms (follow-up) | Planned `waived` / `overridden` on coverage-applicability + pre-PR evidence — **never** map to pass / exit 0; not wired in this authz-only landing |
114
+ | Result arms (#5674) | Live `waived` on coverage-hotspots + pre-PR evidence via exit 4 + waived skip token — **never** map to pass / exit 0; measured floor dominates when a report exists |
111
115
  | Eligible refuse codes | Closed set (`unknown-path`, `dirty-tree`, …); non-overridable authenticity codes (`tree-mismatch`, `invalid-*`) dominate |
112
116
  | Deferred peers | Empty list in v1 |
113
117
  | Push/merge | Grant is `settings` only — no independent push/merge permission |
114
- | Keep-outs | Does not fix #5541 classifier correctness; no fabricate green; no UAT silent suspend; no blanket env override |
118
+ | Keep-outs | Does not fix #5541 / #5665 classifier correctness; no fabricate green; no UAT silent suspend; no blanket env override |
115
119
 
116
120
  Complementary hatches stay separate: `--allow-coverage-debt`, `policy:allow-*`,
117
121
  `DEFT_ALLOW_*`, delivery-attempt `recordOperatorOverride`, `spec-drift-override`.
@@ -125,8 +129,10 @@ Complementary hatches stay separate: `--allow-coverage-debt`, `policy:allow-*`,
125
129
  | Path write fence schema | #516 / #2443 |
126
130
  | AFK session-auth / release verbs | #1095 — see `content/contracts/closed-verb-authz.md` (Wave 4; consumes these grants) |
127
131
  | HMAC / hardware-keyed grants | non-goal for MVP |
128
- | Classifier false-refuse correctness | #5541 (not absorbed by gate-override) |
132
+ | Classifier false-refuse correctness | #5541 / #5665 (not absorbed by gate-override) |
129
133
  | Interactive gate waiver audit | #5542 (this hatch) |
134
+ | Pre-PR/hotspots waived-exit consumer + VERSION/lifecycle gitkeep inert | #5674 (leftover #5665/#5542) |
135
+ | Residual deposit keep-unknowns (run / hooks / codeql / approved-scope) | #5677 |
130
136
 
131
137
  ## Wave 4 consumers
132
138
 
@@ -6,6 +6,9 @@ interface ParsedArgs {
6
6
  baseRef: string | null;
7
7
  pathFilter: string[];
8
8
  useDiffPaths: boolean;
9
+ attemptId: string | null;
10
+ worktree: string | null;
11
+ evaluatorId: string | null;
9
12
  json: boolean;
10
13
  quiet: boolean;
11
14
  error?: string;
@@ -18,6 +18,9 @@ export function parseArgs(argv) {
18
18
  baseRef: null,
19
19
  pathFilter: [],
20
20
  useDiffPaths: true,
21
+ attemptId: null,
22
+ worktree: null,
23
+ evaluatorId: null,
21
24
  json: false,
22
25
  quiet: false,
23
26
  };
@@ -32,6 +35,39 @@ export function parseArgs(argv) {
32
35
  else if (arg === "--no-diff-filter") {
33
36
  parsed.useDiffPaths = false;
34
37
  }
38
+ else if (arg === "--attempt-id") {
39
+ const value = argv[i + 1];
40
+ if (value === undefined) {
41
+ return { ...parsed, error: "argument --attempt-id: expected one argument" };
42
+ }
43
+ parsed.attemptId = value;
44
+ i += 1;
45
+ }
46
+ else if (arg?.startsWith("--attempt-id=")) {
47
+ parsed.attemptId = arg.slice("--attempt-id=".length);
48
+ }
49
+ else if (arg === "--worktree") {
50
+ const value = argv[i + 1];
51
+ if (value === undefined) {
52
+ return { ...parsed, error: "argument --worktree: expected one argument" };
53
+ }
54
+ parsed.worktree = value;
55
+ i += 1;
56
+ }
57
+ else if (arg?.startsWith("--worktree=")) {
58
+ parsed.worktree = arg.slice("--worktree=".length);
59
+ }
60
+ else if (arg === "--evaluator-id") {
61
+ const value = argv[i + 1];
62
+ if (value === undefined) {
63
+ return { ...parsed, error: "argument --evaluator-id: expected one argument" };
64
+ }
65
+ parsed.evaluatorId = value;
66
+ i += 1;
67
+ }
68
+ else if (arg?.startsWith("--evaluator-id=")) {
69
+ parsed.evaluatorId = arg.slice("--evaluator-id=".length);
70
+ }
35
71
  else if (arg === "--project-root") {
36
72
  const value = argv[i + 1];
37
73
  if (value === undefined) {
@@ -126,9 +162,13 @@ export function run(argv) {
126
162
  baseRef: args.baseRef,
127
163
  pathFilter: args.pathFilter.length > 0 ? args.pathFilter : null,
128
164
  useDiffPaths: args.useDiffPaths,
165
+ attemptId: args.attemptId,
166
+ worktree: args.worktree,
167
+ evaluatorId: args.evaluatorId,
129
168
  });
130
- // Exit 3 = authorized coverage N/A (#5421); keep machine-readable artifact on stdout for --json.
131
- if (result.exitCode === 3) {
169
+ // Exit 3 = authorized coverage N/A (#5421); exit 4 = gate-override waived (#5674).
170
+ // Keep machine-readable artifact on stdout for --json. Never map waived to exit 0.
171
+ if (result.exitCode === 3 || result.exitCode === 4) {
132
172
  if (args.json && result.applicability) {
133
173
  process.stdout.write(`${JSON.stringify(result.applicability, null, 2)}\n`);
134
174
  }
@@ -86,6 +86,6 @@ export declare function isNoGitReadinessGap(sync: FullInSyncResult, projectRoot:
86
86
  * Full read-only diagnosis. Never creates/updates files or Git config.
87
87
  */
88
88
  export declare function runDoctorDiagnosis(projectRoot: string, options?: DoctorDiagnosisOptions): DoctorDiagnosis;
89
- /** Human-readable doctor report (AC12.3 / AC12.5 / F-010). */
89
+ /** Human-readable doctor report (AC12.3 / AC12.5 / F-010 / wave 4g). */
90
90
  export declare function formatDoctorReport(diag: DoctorDiagnosis): string;
91
91
  //# sourceMappingURL=doctor-diagnose.d.ts.map
@@ -272,7 +272,7 @@ function line(ok, name, detail) {
272
272
  const mark = ok ? "ok" : "FAIL";
273
273
  return detail ? ` ${name}: ${mark} — ${detail}` : ` ${name}: ${mark}`;
274
274
  }
275
- /** Human-readable doctor report (AC12.3 / AC12.5 / F-010). */
275
+ /** Human-readable doctor report (AC12.3 / AC12.5 / F-010 / wave 4g). */
276
276
  export function formatDoctorReport(diag) {
277
277
  const lines = [];
278
278
  // Header tracks overall health (exitCode), not install-health inSync alone —
@@ -281,12 +281,29 @@ export function formatDoctorReport(diag) {
281
281
  // generic "not in sync" that reads like a broken pin.
282
282
  if (diag.exitCode === 0) {
283
283
  lines.push("directive doctor: in sync");
284
+ lines.push("");
285
+ lines.push("This project's Directive version and wiring look consistent.");
284
286
  }
285
287
  else if (diag.incompleteInstall === "git-precondition") {
286
288
  lines.push("directive doctor: incomplete install (git precondition)");
289
+ lines.push("");
290
+ lines.push("This folder is not a git repository yet, so git hooks were not installed.");
291
+ lines.push("");
292
+ lines.push("Next:");
293
+ lines.push(" git init");
294
+ lines.push(" directive install --repair");
287
295
  }
288
296
  else {
289
297
  lines.push("directive doctor: not in sync");
298
+ lines.push("");
299
+ if (!diag.surfaces.installed.ok || !diag.surfaces.pin.ok) {
300
+ const ver = diag.version ?? "the pinned version";
301
+ lines.push(`The project asks for Directive ${ver}, but that package is missing or the wrong version is installed.`);
302
+ lines.push("");
303
+ lines.push("Next:");
304
+ lines.push(" npm i -g @deftai/directive");
305
+ lines.push(" directive install --repair");
306
+ }
290
307
  }
291
308
  if (diag.version)
292
309
  lines.push(` version: ${diag.version}`);
@@ -317,8 +334,17 @@ export function formatDoctorReport(diag) {
317
334
  if (diag.schemaRemedy) {
318
335
  lines.push(`Next: ${diag.schemaRemedy}`);
319
336
  }
320
- if (diag.remedy) {
321
- lines.push(`Recovery: ${diag.remedy}`);
337
+ if (diag.remedy && diag.incompleteInstall !== "git-precondition") {
338
+ // Avoid duplicating the plain Next: block when we already printed recovery.
339
+ if (diag.exitCode !== 0 && (diag.surfaces.installed.ok && diag.surfaces.pin.ok)) {
340
+ lines.push(`Recovery: ${diag.remedy}`);
341
+ }
342
+ else if (diag.exitCode !== 0 && (!diag.surfaces.installed.ok || !diag.surfaces.pin.ok)) {
343
+ // Plain Next: block already covers AC9.7.
344
+ }
345
+ else {
346
+ lines.push(`Recovery: ${diag.remedy}`);
347
+ }
322
348
  }
323
349
  return `${lines.join("\n")}\n`;
324
350
  }
package/dist/doctor.js CHANGED
@@ -71,7 +71,7 @@ function namesUpdatePruneRecovery(result) {
71
71
  export function renderDepositFileSetHygieneLine(projectRoot, result = evaluateDepositFileSetHygiene(projectRoot)) {
72
72
  const deftDir = join(projectRoot, ".deft", "core");
73
73
  if (!existsSync(deftDir)) {
74
- return "Deposit hygiene: none -- no .deft/core deposit.";
74
+ return "Deposit hygiene: none -- package-based layout (no copied .deft/core tree; expected).";
75
75
  }
76
76
  if (result.skipped) {
77
77
  return ("Deposit hygiene: skip -- @deftai/directive-content is not installed " +
@@ -5,6 +5,11 @@
5
5
  * claim-over and deny-embedded copy-paste remain. host:none / address:none
6
6
  * are unset metadata, not the lock cause. Does not reopen anonymous live
7
7
  * auto-release (#3954).
8
+ *
9
+ * #5544 Prefer-A: pass the supplied --project-root through to releaseOccupancy
10
+ * so the consumer AGENTS.md header check stays at the project directory.
11
+ * Lease file / lock resolution stays inside releaseOccupancy (shared with the
12
+ * Write-hook lease view); denials / already-free print occupancyFile=.
8
13
  */
9
14
  export declare const ABANDONED_OCCUPANCY_LEASE_RECOVERY: string;
10
15
  export declare function formatOccupancyReleaseHelp(): string;
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { resolve } from "node:path";
3
2
  import { releaseOccupancy } from "../vendor/directive-core/dist/session/index.js";
4
3
  import { occupancyUnrecognizedArgument } from "./occupancy-unrecognized.js";
5
4
  /**
@@ -8,17 +7,24 @@ import { occupancyUnrecognizedArgument } from "./occupancy-unrecognized.js";
8
7
  * claim-over and deny-embedded copy-paste remain. host:none / address:none
9
8
  * are unset metadata, not the lock cause. Does not reopen anonymous live
10
9
  * auto-release (#3954).
10
+ *
11
+ * #5544 Prefer-A: pass the supplied --project-root through to releaseOccupancy
12
+ * so the consumer AGENTS.md header check stays at the project directory.
13
+ * Lease file / lock resolution stays inside releaseOccupancy (shared with the
14
+ * Write-hook lease view); denials / already-free print occupancyFile=.
11
15
  */
12
16
  export const ABANDONED_OCCUPANCY_LEASE_RECOVERY = "Abandoned live occupancy lease: bare session:end / occupancy:release without a presented " +
13
17
  "session identity refuses while the lease is live. Immediate recovery: " +
14
18
  "occupancy:release --session-id=<id from .deft/occupancy.json> " +
15
19
  "(read session_id from that file). Or wait for TTL claim-over. " +
16
- "host:none / address:none are ordinary unset metadata, not the lock cause.";
20
+ "host:none / address:none are ordinary unset metadata, not the lock cause. " +
21
+ "Denials and already-free print occupancyFile= for the lease root this CLI resolved.";
17
22
  export function formatOccupancyReleaseHelp() {
18
23
  return [
19
24
  "Usage: deft occupancy:release [--project-root <path>] [--session-id <id>]",
20
25
  "",
21
26
  "Release this worktree occupancy lease (owner live, or expired residue).",
27
+ "Pass the consumer project directory as --project-root (header check uses it; lease file resolves to the Git toplevel when available).",
22
28
  "",
23
29
  ABANDONED_OCCUPANCY_LEASE_RECOVERY,
24
30
  "",
@@ -83,7 +89,9 @@ export function run(argv) {
83
89
  process.stdout.write(formatOccupancyReleaseHelp());
84
90
  return 0;
85
91
  }
86
- const result = releaseOccupancy(resolve(args.projectRoot), {
92
+ // Keep the supplied project directory for the consumer header check; lease
93
+ // root resolution happens inside releaseOccupancy (#5544 Greptile P1).
94
+ const result = releaseOccupancy(args.projectRoot, {
87
95
  sessionId: args.sessionId,
88
96
  env: process.env,
89
97
  });
package/dist/policy.d.ts CHANGED
@@ -23,6 +23,8 @@ interface SetArgs {
23
23
  ceremonyEnabled?: boolean;
24
24
  /** #5350 driftGuard.enforcement target for set-spec-guard-enforcement. */
25
25
  specGuardEnforcement?: SpecGuardEnforcement;
26
+ /** #4375 audited setter for valueFeedback.upstreamPrompt. */
27
+ upstreamPrompt?: boolean;
26
28
  error?: string;
27
29
  }
28
30
  /** Parse policy:show flags (mirrors _policy_show_cli.py). */
package/dist/policy.js CHANGED
@@ -261,11 +261,15 @@ export function parseArgs(argv) {
261
261
  let host;
262
262
  let ceremonyOverride;
263
263
  let ceremonyEnabled;
264
+ let upstreamPrompt;
264
265
  for (let i = 1; i < argv.length; i += 1) {
265
266
  const arg = argv[i];
266
267
  if (arg === "--confirm") {
267
268
  confirm = true;
268
269
  }
270
+ else if (cmd === "enable-value-feedback" && arg === "--upstream-prompt") {
271
+ upstreamPrompt = true;
272
+ }
269
273
  else if (arg === "--actor") {
270
274
  const v = argv[i + 1];
271
275
  if (v === undefined)
@@ -377,6 +381,7 @@ export function parseArgs(argv) {
377
381
  host,
378
382
  ceremonyOverride,
379
383
  ceremonyEnabled,
384
+ upstreamPrompt,
380
385
  };
381
386
  }
382
387
  return makeSetError(`unknown subcommand: ${cmd}`);
@@ -457,6 +462,7 @@ function runEnableValueFeedback(args) {
457
462
  confirm: args.confirm,
458
463
  actor: args.actor,
459
464
  note: args.note,
465
+ subFlags: args.upstreamPrompt === true ? { upstreamPrompt: true } : undefined,
460
466
  });
461
467
  process.stdout.write(result.stdout);
462
468
  return result.exitCode;
@@ -2,7 +2,7 @@
2
2
  import { resolve } from "node:path";
3
3
  import { fileURLToPath } from "node:url";
4
4
  import { CEREMONY_DEPTHS, normalizeCeremonyModelTier, normalizeCeremonyProjectShape, normalizeCeremonyTaskSize, selectCeremonyDepth, } from "../vendor/directive-core/dist/policy/index.js";
5
- import { COLD_CEREMONY_TIER, PRIMARY_CLAIM_EXCEPTIONS, parseDeferrals, parseSessionPostureToken, READ_ONLY_POSTURE, REARM_CEREMONY_TIER, REQUIREMENTS_POSTURE, resolveProductionHostEffortDescriptor, ritualStatePath, runSessionStart, SESSION_CEREMONY_TIERS, } from "../vendor/directive-core/dist/session/index.js";
5
+ import { COLD_CEREMONY_TIER, PRIMARY_CLAIM_EXCEPTIONS, parseDeferrals, parseSessionPostureToken, publishApplyingHostFromCanonicalSessionId, READ_ONLY_POSTURE, REARM_CEREMONY_TIER, REQUIREMENTS_POSTURE, resolveProductionHostEffortDescriptor, ritualStatePath, runSessionStart, SESSION_CEREMONY_TIERS, } from "../vendor/directive-core/dist/session/index.js";
6
6
  function parseCeremonyDepth(raw) {
7
7
  const value = raw.trim().toLowerCase();
8
8
  if (CEREMONY_DEPTHS.includes(value)) {
@@ -523,6 +523,33 @@ export function run(argv) {
523
523
  if (stray) {
524
524
  lines.push(stray);
525
525
  }
526
+ // #5676: read-only may bootstrap the applying-host record; mutation/rearm
527
+ // republishes as reinforcement after a successful ceremony. Skip opt-out /
528
+ // kill-switch disabled results so .no-deft-directive stays write-free.
529
+ const disabled = typeof result.payload === "object" &&
530
+ result.payload !== null &&
531
+ result.payload.disabled === true;
532
+ if (result.code === 0 && !disabled) {
533
+ const owner = args.sessionId?.trim() ||
534
+ (typeof result.payload.occupancy === "object" &&
535
+ result.payload.occupancy !== null &&
536
+ typeof result.payload.occupancy.session_id === "string"
537
+ ? String(result.payload.occupancy.session_id)
538
+ : "") ||
539
+ process.env.DEFT_SESSION_ID?.trim() ||
540
+ "";
541
+ if (owner.length > 0) {
542
+ try {
543
+ const transport = process.env.GROK_HOOK_EVENT?.trim() ? "grok-hook-event" : "native";
544
+ publishApplyingHostFromCanonicalSessionId(projectRoot, owner, {
545
+ transport: owner.startsWith("host:cursor:") ? "native" : transport,
546
+ });
547
+ }
548
+ catch {
549
+ /* ceremony success stays authoritative; applying-host is best-effort */
550
+ }
551
+ }
552
+ }
526
553
  if (args.emitJson) {
527
554
  const sorted = Object.keys(result.payload)
528
555
  .sort()
@@ -152,13 +152,21 @@ export function run(argv) {
152
152
  const repo = args.repo;
153
153
  try {
154
154
  if (args.cmd === "accept") {
155
- const decisionId = accept(n, repo, deps, {
155
+ const outcome = accept(n, repo, deps, {
156
156
  actor: args.actor,
157
157
  projectRoot,
158
158
  autoPromote: args.autoPromote === true,
159
159
  force: args.force === true,
160
160
  });
161
- process.stdout.write(`${formatAcceptOutput(n, repo, decisionId, { autoPromote: args.autoPromote === true })}\n`);
161
+ process.stdout.write(`${formatAcceptOutput(n, repo, outcome.decisionId, {
162
+ autoPromote: args.autoPromote === true,
163
+ disposition: outcome.disposition,
164
+ relativePath: outcome.relativePath,
165
+ ingestMessage: outcome.ingestMessage,
166
+ })}\n`);
167
+ if (outcome.disposition === "refused") {
168
+ return 1;
169
+ }
162
170
  }
163
171
  else if (args.cmd === "reject") {
164
172
  const decisionId = reject(n, repo, args.reason ?? "", deps, {
@@ -13,6 +13,13 @@ interface ParsedArgs {
13
13
  mergePathArm: boolean;
14
14
  liveWait: boolean;
15
15
  explicitFinish: boolean;
16
+ /**
17
+ * Product mint-gate BLOCKED — refuse --explicit-finish write (#5690).
18
+ * Pass-through to writeMergePathExplicitFinishAttestation.mintGateBlocked.
19
+ */
20
+ mintGateBlocked: boolean;
21
+ /** Optional attestation reason; mint markers also refuse the write (#5690). */
22
+ reason: string | null;
16
23
  stickyLease: boolean;
17
24
  /** DeliveryAttemptRecord.startedAt for Approach 1 arm-startup halt (#5278 P3). */
18
25
  dispatchStartedAt: string | null;
@@ -24,6 +24,8 @@ export function parseVerifyReviewMonitorArgs(argv) {
24
24
  mergePathArm: false,
25
25
  liveWait: false,
26
26
  explicitFinish: false,
27
+ mintGateBlocked: false,
28
+ reason: null,
27
29
  stickyLease: false,
28
30
  dispatchStartedAt: null,
29
31
  help: false,
@@ -45,6 +47,20 @@ export function parseVerifyReviewMonitorArgs(argv) {
45
47
  else if (arg === "--explicit-finish") {
46
48
  acc.explicitFinish = true;
47
49
  }
50
+ else if (arg === "--mint-gate-blocked") {
51
+ acc.mintGateBlocked = true;
52
+ }
53
+ else if (arg === "--reason") {
54
+ const value = argv[i + 1];
55
+ if (value === undefined) {
56
+ return { ...acc, error: "argument --reason: expected one argument" };
57
+ }
58
+ acc.reason = value;
59
+ i += 1;
60
+ }
61
+ else if (arg?.startsWith("--reason=")) {
62
+ acc.reason = arg.slice("--reason=".length);
63
+ }
48
64
  else if (arg === "--sticky-lease") {
49
65
  acc.stickyLease = true;
50
66
  }
@@ -159,6 +175,9 @@ export function run(argv) {
159
175
  " pr:watch CLEAN attestation — #5219;\n" +
160
176
  " parent-shell pr:watch (parent_id=pr-watch) does not arm.\n" +
161
177
  " --explicit-finish Attest option-C BLOCKED/FAILED finish for this PR\n" +
178
+ " --mint-gate-blocked Refuse --explicit-finish write for product mint-gate\n" +
179
+ " BLOCKED (non-option-C; #5690)\n" +
180
+ " --reason TEXT Attestation reason; mint markers also refuse write (#5690)\n" +
162
181
  " --sticky-lease Attest a fresh sticky lease (not sufficient alone)\n" +
163
182
  " --dispatch-started-at DeliveryAttemptRecord.startedAt ISO for Approach 1\n" +
164
183
  " arm-startup halt (#5278); when merge-path-arm stays\n" +
@@ -202,6 +221,8 @@ export function run(argv) {
202
221
  else {
203
222
  const written = writeMergePathExplicitFinishAttestation(resolve(args.projectRoot), args.pr, {
204
223
  source: "verify:review-monitor --explicit-finish",
224
+ reason: args.reason ?? undefined,
225
+ mintGateBlocked: args.mintGateBlocked,
205
226
  });
206
227
  if (!written.ok) {
207
228
  process.stderr.write(`verify_review_monitor: ${written.reason}