@deftai/directive-runtime 0.127.0 → 0.128.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 (230) hide show
  1. package/.githooks/_directive-run.sh +30 -0
  2. package/.githooks/pre-commit +4 -24
  3. package/.githooks/pre-push +11 -17
  4. package/Taskfile.yml +16 -15
  5. package/contracts/design-critique.md +5 -0
  6. package/dist/cli-router/route-argv.js +1 -0
  7. package/dist/coverage-hotspots.js +2 -2
  8. package/dist/dispatch.d.ts +1 -1
  9. package/dist/dispatch.js +7 -0
  10. package/dist/policy.d.ts +4 -2
  11. package/dist/policy.js +101 -2
  12. package/dist/pre-pr-run.d.ts +2 -0
  13. package/dist/pre-pr-run.js +40 -0
  14. package/dist/render-cli/capability-map-cli.d.ts +3 -0
  15. package/dist/render-cli/capability-map-cli.js +6 -0
  16. package/dist/setup-wiring.d.ts +2 -0
  17. package/dist/setup-wiring.js +14 -0
  18. package/docs/getting-started.md +2 -0
  19. package/docs/known-limitations.md +1 -0
  20. package/docs/launcher.md +10 -0
  21. package/package.json +1 -1
  22. package/packs/skills/skills-pack-0.1.json +1 -1
  23. package/skills/deft-directive-pre-pr/SKILL.md +13 -3
  24. package/tasks/agent.yml +0 -2
  25. package/tasks/cache.yml +0 -16
  26. package/tasks/capacity.yml +0 -4
  27. package/tasks/change.yml +0 -4
  28. package/tasks/codebase.yml +0 -10
  29. package/tasks/commit.yml +0 -2
  30. package/tasks/coverage.yml +0 -2
  31. package/tasks/decision.yml +0 -4
  32. package/tasks/directive.yml +0 -1
  33. package/tasks/docs.yml +6 -10
  34. package/tasks/engine-invoke.cjs +79 -0
  35. package/tasks/engine-invoke.test.cjs +84 -0
  36. package/tasks/engine.yml +27 -88
  37. package/tasks/eval.yml +0 -8
  38. package/tasks/feedback.yml +0 -2
  39. package/tasks/install.yml +0 -4
  40. package/tasks/issue.yml +0 -3
  41. package/tasks/lifecycle.yml +0 -1
  42. package/tasks/materialize.cjs +246 -0
  43. package/tasks/materialize.test.cjs +103 -0
  44. package/tasks/materialize.yml +13 -0
  45. package/tasks/migrate.yml +0 -6
  46. package/tasks/packs.yml +0 -16
  47. package/tasks/plan-sequence.yml +0 -8
  48. package/tasks/policy.yml +0 -24
  49. package/tasks/pr.yml +0 -6
  50. package/tasks/prd.yml +0 -2
  51. package/tasks/product-signal.yml +0 -10
  52. package/tasks/project.yml +0 -8
  53. package/tasks/reconcile.yml +0 -2
  54. package/tasks/review-monitor.yml +0 -4
  55. package/tasks/roadmap.yml +0 -4
  56. package/tasks/scm.yml +0 -32
  57. package/tasks/scope.yml +0 -30
  58. package/tasks/slice.yml +0 -4
  59. package/tasks/spec.yml +0 -6
  60. package/tasks/subagent.yml +0 -4
  61. package/tasks/swarm.yml +0 -7
  62. package/tasks/toolchain.yml +0 -4
  63. package/tasks/triage-actions.yml +0 -8
  64. package/tasks/triage-bootstrap.yml +0 -1
  65. package/tasks/triage-bulk.yml +0 -5
  66. package/tasks/triage-classify.yml +0 -2
  67. package/tasks/triage-evaluate.yml +0 -1
  68. package/tasks/triage-metrics.yml +0 -2
  69. package/tasks/triage-queue.yml +0 -3
  70. package/tasks/triage-reconcile.yml +0 -1
  71. package/tasks/triage-scope-drift.yml +0 -1
  72. package/tasks/triage-scope.yml +0 -1
  73. package/tasks/triage-smoketest.yml +0 -1
  74. package/tasks/triage-subscribe.yml +0 -2
  75. package/tasks/tutorial.yml +0 -20
  76. package/tasks/umbrella.yml +0 -2
  77. package/tasks/value.yml +0 -2
  78. package/tasks/vbrief.yml +0 -12
  79. package/tasks/verify.yml +0 -140
  80. package/tasks/xbrief.yml +0 -6
  81. package/templates/design-critique-brief.md +3 -0
  82. package/vendor/directive-content/.githooks/_directive-run.sh +30 -0
  83. package/vendor/directive-content/.githooks/pre-commit +4 -24
  84. package/vendor/directive-content/.githooks/pre-push +11 -17
  85. package/vendor/directive-content/Taskfile.yml +16 -15
  86. package/vendor/directive-content/contracts/design-critique.md +5 -0
  87. package/vendor/directive-content/docs/getting-started.md +2 -0
  88. package/vendor/directive-content/docs/known-limitations.md +1 -0
  89. package/vendor/directive-content/docs/launcher.md +10 -0
  90. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +1 -1
  91. package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +13 -3
  92. package/vendor/directive-content/tasks/agent.yml +0 -2
  93. package/vendor/directive-content/tasks/cache.yml +0 -16
  94. package/vendor/directive-content/tasks/capacity.yml +0 -4
  95. package/vendor/directive-content/tasks/change.yml +0 -4
  96. package/vendor/directive-content/tasks/codebase.yml +0 -10
  97. package/vendor/directive-content/tasks/commit.yml +0 -2
  98. package/vendor/directive-content/tasks/coverage.yml +0 -2
  99. package/vendor/directive-content/tasks/decision.yml +0 -4
  100. package/vendor/directive-content/tasks/directive.yml +0 -1
  101. package/vendor/directive-content/tasks/docs.yml +6 -10
  102. package/vendor/directive-content/tasks/engine-invoke.cjs +79 -0
  103. package/vendor/directive-content/tasks/engine-invoke.test.cjs +84 -0
  104. package/vendor/directive-content/tasks/engine.yml +27 -88
  105. package/vendor/directive-content/tasks/eval.yml +0 -8
  106. package/vendor/directive-content/tasks/feedback.yml +0 -2
  107. package/vendor/directive-content/tasks/install.yml +0 -4
  108. package/vendor/directive-content/tasks/issue.yml +0 -3
  109. package/vendor/directive-content/tasks/lifecycle.yml +0 -1
  110. package/vendor/directive-content/tasks/materialize.cjs +246 -0
  111. package/vendor/directive-content/tasks/materialize.test.cjs +103 -0
  112. package/vendor/directive-content/tasks/materialize.yml +13 -0
  113. package/vendor/directive-content/tasks/migrate.yml +0 -6
  114. package/vendor/directive-content/tasks/packs.yml +0 -16
  115. package/vendor/directive-content/tasks/plan-sequence.yml +0 -8
  116. package/vendor/directive-content/tasks/policy.yml +0 -24
  117. package/vendor/directive-content/tasks/pr.yml +0 -6
  118. package/vendor/directive-content/tasks/prd.yml +0 -2
  119. package/vendor/directive-content/tasks/product-signal.yml +0 -10
  120. package/vendor/directive-content/tasks/project.yml +0 -8
  121. package/vendor/directive-content/tasks/reconcile.yml +0 -2
  122. package/vendor/directive-content/tasks/review-monitor.yml +0 -4
  123. package/vendor/directive-content/tasks/roadmap.yml +0 -4
  124. package/vendor/directive-content/tasks/scm.yml +0 -32
  125. package/vendor/directive-content/tasks/scope.yml +0 -30
  126. package/vendor/directive-content/tasks/slice.yml +0 -4
  127. package/vendor/directive-content/tasks/spec.yml +0 -6
  128. package/vendor/directive-content/tasks/subagent.yml +0 -4
  129. package/vendor/directive-content/tasks/swarm.yml +0 -7
  130. package/vendor/directive-content/tasks/toolchain.yml +0 -4
  131. package/vendor/directive-content/tasks/triage-actions.yml +0 -8
  132. package/vendor/directive-content/tasks/triage-bootstrap.yml +0 -1
  133. package/vendor/directive-content/tasks/triage-bulk.yml +0 -5
  134. package/vendor/directive-content/tasks/triage-classify.yml +0 -2
  135. package/vendor/directive-content/tasks/triage-evaluate.yml +0 -1
  136. package/vendor/directive-content/tasks/triage-metrics.yml +0 -2
  137. package/vendor/directive-content/tasks/triage-queue.yml +0 -3
  138. package/vendor/directive-content/tasks/triage-reconcile.yml +0 -1
  139. package/vendor/directive-content/tasks/triage-scope-drift.yml +0 -1
  140. package/vendor/directive-content/tasks/triage-scope.yml +0 -1
  141. package/vendor/directive-content/tasks/triage-smoketest.yml +0 -1
  142. package/vendor/directive-content/tasks/triage-subscribe.yml +0 -2
  143. package/vendor/directive-content/tasks/tutorial.yml +0 -20
  144. package/vendor/directive-content/tasks/umbrella.yml +0 -2
  145. package/vendor/directive-content/tasks/value.yml +0 -2
  146. package/vendor/directive-content/tasks/vbrief.yml +0 -12
  147. package/vendor/directive-content/tasks/verify.yml +0 -140
  148. package/vendor/directive-content/tasks/xbrief.yml +0 -6
  149. package/vendor/directive-content/templates/design-critique-brief.md +3 -0
  150. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  151. package/vendor/directive-core/dist/content-root.d.ts.map +1 -1
  152. package/vendor/directive-core/dist/content-root.js +8 -1
  153. package/vendor/directive-core/dist/content-root.js.map +1 -1
  154. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts +13 -5
  155. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts.map +1 -1
  156. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js +60 -2
  157. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js.map +1 -1
  158. package/vendor/directive-core/dist/doctor/checks.d.ts.map +1 -1
  159. package/vendor/directive-core/dist/doctor/checks.js +5 -3
  160. package/vendor/directive-core/dist/doctor/checks.js.map +1 -1
  161. package/vendor/directive-core/dist/index.d.ts +1 -0
  162. package/vendor/directive-core/dist/index.d.ts.map +1 -1
  163. package/vendor/directive-core/dist/index.js +1 -0
  164. package/vendor/directive-core/dist/index.js.map +1 -1
  165. package/vendor/directive-core/dist/init-deposit/scaffold.d.ts +1 -1
  166. package/vendor/directive-core/dist/init-deposit/scaffold.d.ts.map +1 -1
  167. package/vendor/directive-core/dist/init-deposit/scaffold.js +1 -1
  168. package/vendor/directive-core/dist/init-deposit/scaffold.js.map +1 -1
  169. package/vendor/directive-core/dist/policy/coverage-mode.d.ts +84 -0
  170. package/vendor/directive-core/dist/policy/coverage-mode.d.ts.map +1 -0
  171. package/vendor/directive-core/dist/policy/coverage-mode.js +226 -0
  172. package/vendor/directive-core/dist/policy/coverage-mode.js.map +1 -0
  173. package/vendor/directive-core/dist/policy/index.d.ts +2 -0
  174. package/vendor/directive-core/dist/policy/index.d.ts.map +1 -1
  175. package/vendor/directive-core/dist/policy/index.js +60 -40
  176. package/vendor/directive-core/dist/policy/index.js.map +1 -1
  177. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts.map +1 -1
  178. package/vendor/directive-core/dist/pr-closing-keywords/main.js +137 -7
  179. package/vendor/directive-core/dist/pr-closing-keywords/main.js.map +1 -1
  180. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts +2 -0
  181. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts.map +1 -1
  182. package/vendor/directive-core/dist/pre-pr-controller/controller.js +109 -14
  183. package/vendor/directive-core/dist/pre-pr-controller/controller.js.map +1 -1
  184. package/vendor/directive-core/dist/pre-pr-controller/evaluate.d.ts +2 -0
  185. package/vendor/directive-core/dist/pre-pr-controller/evaluate.d.ts.map +1 -1
  186. package/vendor/directive-core/dist/pre-pr-controller/evaluate.js +11 -1
  187. package/vendor/directive-core/dist/pre-pr-controller/evaluate.js.map +1 -1
  188. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts +1 -1
  189. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts.map +1 -1
  190. package/vendor/directive-core/dist/pre-pr-controller/index.js +1 -1
  191. package/vendor/directive-core/dist/pre-pr-controller/index.js.map +1 -1
  192. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts +10 -0
  193. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts.map +1 -1
  194. package/vendor/directive-core/dist/pre-pr-controller/phases.js +15 -1
  195. package/vendor/directive-core/dist/pre-pr-controller/phases.js.map +1 -1
  196. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts +20 -1
  197. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts.map +1 -1
  198. package/vendor/directive-core/dist/pre-pr-controller/types.js +2 -0
  199. package/vendor/directive-core/dist/pre-pr-controller/types.js.map +1 -1
  200. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts +40 -3
  201. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts.map +1 -1
  202. package/vendor/directive-core/dist/preflight-gh/pre-push.js +340 -27
  203. package/vendor/directive-core/dist/preflight-gh/pre-push.js.map +1 -1
  204. package/vendor/directive-core/dist/render/project-render.d.ts.map +1 -1
  205. package/vendor/directive-core/dist/render/project-render.js +1 -0
  206. package/vendor/directive-core/dist/render/project-render.js.map +1 -1
  207. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.d.ts +21 -0
  208. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.d.ts.map +1 -0
  209. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.js +95 -0
  210. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.js.map +1 -0
  211. package/vendor/directive-core/dist/swarm/launch-cli.d.ts.map +1 -1
  212. package/vendor/directive-core/dist/swarm/launch-cli.js +12 -0
  213. package/vendor/directive-core/dist/swarm/launch-cli.js.map +1 -1
  214. package/vendor/directive-core/dist/swarm/launch.d.ts +6 -0
  215. package/vendor/directive-core/dist/swarm/launch.d.ts.map +1 -1
  216. package/vendor/directive-core/dist/swarm/launch.js +11 -0
  217. package/vendor/directive-core/dist/swarm/launch.js.map +1 -1
  218. package/vendor/directive-core/dist/swarm/leftover-before-activation.d.ts +27 -0
  219. package/vendor/directive-core/dist/swarm/leftover-before-activation.d.ts.map +1 -0
  220. package/vendor/directive-core/dist/swarm/leftover-before-activation.js +31 -0
  221. package/vendor/directive-core/dist/swarm/leftover-before-activation.js.map +1 -0
  222. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.d.ts +3 -3
  223. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.d.ts.map +1 -1
  224. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.js +7 -11
  225. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.js.map +1 -1
  226. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.d.ts.map +1 -1
  227. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.js +1 -0
  228. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.js.map +1 -1
  229. package/.githooks/_deft-run.sh +0 -47
  230. package/vendor/directive-content/.githooks/_deft-run.sh +0 -47
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env sh
2
+ # Package-relative Directive git-hook helper (AC9.9).
3
+ # Sourced by pre-commit/pre-push; defines run_directive.
4
+ if [ -z "${REPO_ROOT:-}" ]; then
5
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
6
+ fi
7
+ if [ -z "$REPO_ROOT" ]; then
8
+ echo "directive hooks: unable to resolve repo root." >&2
9
+ exit 1
10
+ fi
11
+ RUNTIME_BIN="$REPO_ROOT/node_modules/@deftai/directive-runtime/dist/bin.js"
12
+ if [ ! -f "$RUNTIME_BIN" ]; then
13
+ echo "directive hooks: missing $RUNTIME_BIN" >&2
14
+ echo "Recovery: npm i -g @deftai/directive, then directive install --repair" >&2
15
+ exit 1
16
+ fi
17
+ run_directive() {
18
+ # #3039 / #5543: root local kill-switch — skip CLI spawn when flag is present,
19
+ # not a symlink, and not tracked by git (tracked flag must not disable clones).
20
+ _kill="$REPO_ROOT/.deft-directive-disable"
21
+ if [ -f "$_kill" ] && [ ! -L "$_kill" ]; then
22
+ if ! git -C "$REPO_ROOT" ls-files --error-unmatch -- .deft-directive-disable >/dev/null 2>&1; then
23
+ echo "Directive is DISABLED for this project via root .deft-directive-disable (test/local kill-switch)." >&2
24
+ echo "Git hooks skipping Directive CLI spawn (#5543 / #3039). Deposit may remain." >&2
25
+ echo "Recovery: rm .deft-directive-disable && start a new agent session." >&2
26
+ return 0
27
+ fi
28
+ fi
29
+ node "$RUNTIME_BIN" "$@"
30
+ }
@@ -1,25 +1,5 @@
1
1
  #!/usr/bin/env sh
2
- # .githooks/pre-commit -- deft CLI gates (#2049 / #747 / #798 / #1620).
3
- #
4
- # Activated by `git config core.hooksPath .githooks` via `task setup` or the
5
- # deft installer (#1463). Pure POSIX shell; prefers global `deft` on PATH,
6
- # falls back to local packages/runtime/dist/bin.js in the maintainer monorepo (#2067).
7
-
8
- REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
9
- if [ -z "$REPO_ROOT" ]; then
10
- echo "deft pre-commit: unable to resolve repo root via 'git rev-parse'." >&2
11
- exit 1
12
- fi
13
-
14
- . "$REPO_ROOT/.githooks/_deft-run.sh"
15
-
16
- run_deft verify:branch --project-root "$REPO_ROOT" || exit $?
17
-
18
- run_deft verify:encoding --staged --project-root "$REPO_ROOT" || exit $?
19
-
20
- run_deft verify:forward-coverage --staged --project-root "$REPO_ROOT" || exit $?
21
-
22
- if [ -d "$REPO_ROOT/xbrief" ] || [ -d "$REPO_ROOT/vbrief" ]; then
23
- run_deft verify:vbrief-conformance --staged --project-root "$REPO_ROOT" || exit $?
24
- run_deft verify:xbrief-drift --staged --project-root "$REPO_ROOT" || exit $?
25
- fi
2
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 1
3
+ # shellcheck source=/dev/null
4
+ . "$REPO_ROOT/.githooks/_directive-run.sh"
5
+ run_directive verify:encoding --staged --project-root "$REPO_ROOT" || exit $?
@@ -1,18 +1,12 @@
1
1
  #!/usr/bin/env sh
2
- # .githooks/pre-push -- refspec-aware default-branch push gate (#2049 / #1019 / #1814).
3
- #
4
- # Pre-push does NOT invoke verify:branch (#747). HEAD-only default-branch
5
- # protection remains on pre-commit; pre-push relies on preflight-gh for
6
- # refspec-aware protection (#1814 Option A). Pure POSIX shell; prefers global
7
- # `deft` on PATH, falls back to local packages/runtime/dist/bin.js (#2067).
8
-
9
- REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
10
- if [ -z "$REPO_ROOT" ]; then
11
- echo "deft pre-push: unable to resolve repo root via 'git rev-parse'." >&2
12
- exit 1
13
- fi
14
-
15
- . "$REPO_ROOT/.githooks/_deft-run.sh"
16
-
17
- run_deft preflight-gh --pre-push-stdin --project-root "$REPO_ROOT"
18
- exit $?
2
+ # deft:pre-pr-bound-push-v1 — refuse-to-downgrade marker (#5804); marker-aware ensureGitHooks only
3
+ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 1
4
+ # shellcheck source=/dev/null
5
+ . "$REPO_ROOT/.githooks/_directive-run.sh"
6
+ run_directive verify:branch --project-root "$REPO_ROOT" || exit $?
7
+ # Enrolled bound pre-PR arm: sole-stdin (do not redirect shared run_directive to /dev/null)
8
+ # Pins older than #5804 lack --push-admit: keep the pre-#5804 hook there (verify:branch only).
9
+ _pre_pr_help="$(run_directive pre-pr:run --help </dev/null 2>&1)" || exit $?
10
+ case "$_pre_pr_help" in
11
+ *--push-admit*) run_directive pre-pr:run --push-admit --project-root "$REPO_ROOT" || exit $? ;;
12
+ esac
package/Taskfile.yml CHANGED
@@ -69,6 +69,9 @@ env:
69
69
  UV_PROJECT: '{{.TASKFILE_DIR}}'
70
70
 
71
71
  includes:
72
+ deft:
73
+ taskfile: ./node_modules/@deftai/directive-runtime/Taskfile.yml
74
+ optional: true
72
75
  docs:
73
76
  taskfile: ./tasks/docs.yml
74
77
  optional: true
@@ -393,6 +396,10 @@ includes:
393
396
  engine:
394
397
  taskfile: ./tasks/engine.yml
395
398
  optional: true
399
+ # #5805: tip-without-publish materialize into checkout pin.
400
+ materialize:
401
+ taskfile: ./tasks/materialize.yml
402
+ optional: true
396
403
 
397
404
  tasks:
398
405
  default:
@@ -405,8 +412,7 @@ tasks:
405
412
  check:
406
413
  desc: "Run the context-appropriate pre-commit gate: full framework self-check in this repo, consumer-safe gate from vendored installs (#1519)."
407
414
  dir: '{{.USER_WORKING_DIR}}'
408
- deps:
409
- - task: engine:_ts-build
415
+ # #5805: no engine:_ts-build — pin-exclusive ordinary invoke.
410
416
  cmds:
411
417
  - task: engine:invoke
412
418
  vars:
@@ -419,8 +425,7 @@ tasks:
419
425
 
420
426
  check:merge:
421
427
  desc: "Merge chokepoint gate — explicit alias for check:framework-source (#1704). CI and PR gates SHOULD invoke this (or task check) as the single SoT so discrete workflow steps cannot drift."
422
- deps:
423
- - task: engine:_ts-build
428
+ # #5805: no engine:_ts-build here — ordinary/merge invoke uses the checkout pin, not tip dist.
424
429
  cmds:
425
430
  - task: check:framework-source
426
431
 
@@ -452,6 +457,8 @@ tasks:
452
457
  - verify:bridge-drift
453
458
  - verify:branch
454
459
  - verify:encoding
460
+ # Keep local uncached closing-keyword checks (#5736 Greptile); CI branch-gate
461
+ # still owns --mode both for merge-base / commit-range.
455
462
  - verify:closing-keywords
456
463
  - verify:forward-coverage
457
464
  - verify:changelog-unreleased
@@ -595,8 +602,6 @@ tasks:
595
602
  verify-strategy-output:
596
603
  desc: "Deterministic v0.20 strategy output shape gate (#1166 s2). Fails on non-date-prefixed vBRIEFs in lifecycle dirs, missing PROJECT-DEFINITION.vbrief.json, or legacy specification.vbrief.json in user projects."
597
604
  dir: '{{.USER_WORKING_DIR}}'
598
- deps:
599
- - task: engine:_ts-build
600
605
  cmds:
601
606
  - task: engine:invoke
602
607
  vars:
@@ -618,8 +623,6 @@ tasks:
618
623
 
619
624
  verify:no-task-runtime:
620
625
  desc: "Fail when runtime Python code hard-depends on go-task (#1659)."
621
- deps:
622
- - task: engine:_ts-build
623
626
  cmds:
624
627
  # Oracle/fallback (parity): scripts/verify_no_task_runtime.py (#1854 s3).
625
628
  - task: engine:invoke
@@ -649,7 +652,7 @@ tasks:
649
652
  # User-facing upgrade entrypoint (#1061). Aliases the install:upgrade
650
653
  # wrapper. As of #2064 the native deft-ts install-upgrade handler is a thin
651
654
  # redirect onto `directive update` -- the single canonical upgrade verb that
652
- # file-swaps the vendored .deft/core payload, rewrites the install manifest,
655
+ # file-swaps the vendored runtime payload, rewrites the install manifest,
653
656
  # and regenerates .deft-version. Prefer `deft update` directly; this alias is
654
657
  # retained for compatibility. Cited by the doctor's failure prose and
655
658
  # docs/install-manifest.md as the post-drift repair entrypoint.
@@ -659,7 +662,7 @@ tasks:
659
662
  - task: install:upgrade
660
663
 
661
664
  # #1272: canonical doctor surface -- thin shim that forwards to
662
- # ``.deft/core/run doctor``. The ``run`` CLI owns the diagnostic
665
+ # the runtime doctor entry. The doctor CLI owns the diagnostic
663
666
  # logic (system deps, framework layout, root Taskfile.yml include
664
667
  # health) and the optional interactive repair path. The task
665
668
  # accepts user-facing flags (``--session`` / ``--fix`` / ``--json``
@@ -680,8 +683,6 @@ tasks:
680
683
  setup:
681
684
  desc: "Idempotent local-dev setup: configure git hooks (#747); detect-and-prompt ghx (#884). Sets core.hooksPath=.githooks so .githooks/pre-commit + .githooks/pre-push run."
682
685
  dir: '{{.USER_WORKING_DIR}}'
683
- deps:
684
- - task: engine:_ts-build
685
686
  env:
686
687
  PYTHONUTF8: "1"
687
688
  cmds:
@@ -758,8 +759,6 @@ tasks:
758
759
  setup:ghx:
759
760
  desc: "Consent-gated ghx (brunoborges/ghx) installer (#884) -- task setup:ghx [-- --yes]"
760
761
  dir: '{{.USER_WORKING_DIR}}'
761
- deps:
762
- - task: engine:_ts-build
763
762
  # Per `conventions/task-caching.md` (#574): no `sources:` / `generates:`
764
763
  # because the script forwards user-facing flags via {{.CLI_ARGS}}
765
764
  # (notably --yes for non-interactive CI / scripted approval).
@@ -806,7 +805,9 @@ tasks:
806
805
  cmds:
807
806
  - task: engine:invoke
808
807
  vars:
809
- ENGINE_CMD: 'release {{.CLI_ARGS}}'
808
+ # #5805: the pin's default project root is its own package dir, so pass the
809
+ # operator root explicitly (an operator --project-root in CLI_ARGS still wins).
810
+ ENGINE_CMD: 'release --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
810
811
 
811
812
  release:publish:
812
813
  desc: "Flip a draft GitHub release to public (#716) -- task release:publish -- <version> [--dry-run] [--repo OWNER/REPO]"
@@ -208,6 +208,7 @@ Strengths are not one level. Token presence is not behavioral evidence. Classifi
208
208
 
209
209
  - ! Re-verify the triage's anchors by running checks. Line cites are claims, not evidence. On a process-only dest, use the recorded `verification-path:` (default pin-read `git show <dispatch-sha>:`; provisioned runnable path only when a check must execute fixtures/tests). Launch-probe is not that path.
210
210
  - ! Inventory existing mechanisms before proposing new ones.
211
+ - ! Prefer-A Bound / Bound-remedy size obeys Thin Fail-Closed (#3265): keep `## Bound remedy` a short mechanism list. Optional complexity is leftover-pain, footnote, or an implementation note — not a second design essay.
211
212
  - ! Classify every finding with the exact three tokens: `blocks-the-design`, `sharpens-framing`, or `footnote`.
212
213
  - ! Every classified finding names evidence, a concrete failure mode, and the disposition consequence — or it is a footnote.
213
214
 
@@ -369,6 +370,8 @@ After this round's same-round siblings are posted, parent posts a successor `**L
369
370
  - ! When the next-build contract is not this body, stamp a Lean-family line-start `Spec-path:` on that successor lean. Nine spellings: zero to two asterisks counted independently on each side, the same wrapping as `Lean:`. `Spec-path:` is a lean token, not a chip. `resolveAutoStampCatalogChip` remaining-set-replaces `ingest-ready` after the completed-arc record exists. It does not parse lean English and does not map Spec-path to a chip.
370
371
  - ! Spec-path token plus a completed-arc record means harvest that closed Bound-remedy heading slice on the cited successor lean. Missing heading or empty list refuses, nothing written. No token stays the #4237 Outcome:ready body-is-normative path. ⊗ Let Spec-path mean both a later arc and a harvest path.
371
372
  - ! Bound-remedy harvest is a Lean-family heading token (`## Bound remedy`, same class as `## In plain English`) plus parseListItems on that slice of the cited successor lean only. ⊗ Bind that harvest as reuse extractPlanItems. Empty on that lean refuses. A numbered list without that heading is not enough.
373
+ - ! `## Bound remedy` stays Thin Fail-Closed (#3265): short mechanism list only. Optional complexity is leftover-pain, footnote, or an implementation note. ⊗ Grow Bound remedy into a second design essay.
374
+ - ! Remint a `## Bound remedy` (new Spec-path / Recut lean) when the mechanism or fail-closed association changes. ⊗ Remint solely to absorb footnote-class pain-audit text (writing bar #3368). Reuse existing leftover-pain / footnote / non-remint branches; do not invent parallel H2 names Prefer-A Bound or pain-audit harvest.
372
375
  - ! Point that harvest source at plan.items, literal capture, derived-clause taskStatement, and Overview. When Spec-path harvest is present, Overview MUST NOT contain the refused GitHub body. Omit Overview, or replace it with a framework-authored remainder (harvest sourceText). Persist the refused body under plan.metadata on a sibling of issueCommentThread. ⊗ Close with an items-only patch. ⊗ Keep the refused GitHub body in Overview as historical described content.
373
376
  - ⊗ Classify the path selector by NLP of the lean.
374
377
 
@@ -727,6 +730,8 @@ The `unshaped-table-cite` detail names the heading because the diagnostics rule
727
730
 
728
731
  Named Stop 1 warrant pains are a bind conjunct on `evaluateCompletedArcRecord`. Critic-heading all-accept is not coverage. Catalog chip `design-critique:ingest-ready` is list state, not clearance. Do not grow `resolveAutoStampCatalogChip` as this gate. Do not restore `design-critique:recut-needed`.
729
732
 
733
+ - ! Writing-bar (#3368) footnote-class pain-audit posture: naming, docs, alias, and dispose-wording default to `footnote` with `harvest-changed: false` unless the `## Bound remedy` mechanism changes. Reuse existing footnote / non-remint / leftover-pain branches. ⊗ Invent parallel H2 names Prefer-A Bound or pain-audit harvest for that posture.
734
+
730
735
  #### Yolo leftover-pain (#4593)
731
736
 
732
737
  In yolo mode, when named pain is uncited or `does-not-relieve` and a recut still has a deliverable remainder: recommend one leftover path in prose on the thread (file a new issue for the unmet part, or halt). If the operator confirms the split as a live turn, file that issue. Record the leftover issue number from that parent issue-create output, and from nothing else. After the split is filed, continue the current arc on the deliverable remainder while Dual-stop post budget remains and finish is still possible, and halt otherwise. Finish is still possible while each pain-audit returns strictly fewer blocking findings than the last. Halt on a repeat of the primary blocking heading, not only on the post cap.
@@ -98,6 +98,7 @@ export const SUBCOMMAND_ROUTES = {
98
98
  "policy:enable-value-feedback": ["policy", "enable-value-feedback"],
99
99
  "policy:disable-host-hooks": ["policy", "disable-host-hooks"],
100
100
  "policy:set-ceremony-dial": ["policy", "set-ceremony-dial"],
101
+ "policy:set-coverage-mode": ["policy", "set-coverage-mode"],
101
102
  "policy:set-spec-guard-enforcement": ["policy", "set-spec-guard-enforcement"],
102
103
  "policy:clear-value-feedback": ["policy", "clear-value-feedback"],
103
104
  "authz:show": ["authz", "show"],
@@ -166,9 +166,9 @@ export function run(argv) {
166
166
  worktree: args.worktree,
167
167
  evaluatorId: args.evaluatorId,
168
168
  });
169
- // Exit 3 = authorized coverage N/A (#5421); exit 4 = gate-override waived (#5674).
169
+ // Exit 3 = authorized coverage N/A (#5421); exit 4 = gate-override waived (#5674); exit 5 = coverageMode posture (#5791).
170
170
  // Keep machine-readable artifact on stdout for --json. Never map waived to exit 0.
171
- if (result.exitCode === 3 || result.exitCode === 4) {
171
+ if (result.exitCode === 3 || result.exitCode === 4 || result.exitCode === 5) {
172
172
  if (args.json && result.applicability) {
173
173
  process.stdout.write(`${JSON.stringify(result.applicability, null, 2)}\n`);
174
174
  }
@@ -12,7 +12,7 @@ export interface DispatchIo {
12
12
  /** CLI modules in packages/cli/src (excluding parity harnesses and bin/index). */
13
13
  export declare const CLI_MODULE_VERBS: readonly ["agents-refresh", "cache", "check", "capacity-backfill", "capacity-show", "codebase-default-extractor", "codebase-map", "codebase-map-fresh", "codebase-projection-registry", "codebase-provider", "doctor", "ownership-doctor", "ownership-fix", "verify-ownership", "install-upgrade", "install-uninstall", "migrate-preflight", "migrate-xbrief", "migrate-category-b", "framework-check-updates", "hook-dispatch", "umbrella-current-shape", "changelog-check", "change-init", "commit-lint", "coverage-hotspots", "policy", "authz", "escalation-cli", "pr-closing-keywords", "pr-merge-readiness", "pr-monitor", "pr-protected-issues", "pr-wait-mergeable", "pr-watch", "pr-finish-loop", "directive-finish-loop", "pre-pr-run", "preflight-cache", "preflight-gh", "probe-session", "release", "release-e2e", "release-publish", "release-rollback", "release-wait-npm", "scope-lifecycle", "scope-record-approved-scope", "scope-record-observable-scope", "scope-record-intent-constraint", "scm-sync-default", "lifecycle-event", "lifecycle-stats", "session-start", "session-ready", "occupancy-steal", "occupancy-release", "occupancy-heartbeat", "occupancy-grant", "plan-sequence", "slice", "subagent-monitor", "toolchain-check", "triage-actions", "triage-bootstrap", "triage-bulk", "triage-classify", "triage-strip-withdrawn", "triage-evaluate", "triage-help", "triage-queue", "triage-reconcile", "triage-refresh", "triage-scope", "triage-scope-drift", "triage-smoketest", "triage-subscribe", "triage-summary", "triage-welcome", "ts-check-lane", "vbrief-activate", "vbrief-build", "vbrief-preflight", "vbrief-reconcile", "vbrief-validate", "vbrief-validation", "xbrief-create", "xbrief-verify", "xbrief-adopt-stored-plan-id", "verify-branch", "verify-encoding", "verify-forward-coverage", "verify-test-boundary", "verify-class-checks", "verify-presentation-coverage", "verify-scope-provenance", "verify-consumer-check-contract", "verify-hooks-installed", "verify-investigation", "verify-judgment-gates", "verify-no-task-runtime", "validate-links", "validate-strategy-output", "verify-biome-config", "verify-bridge-drift", "verify-capacity", "verify-contained-writes", "verify-telemetry-coverage", "verify-content-manifest", "verify-deposit-closure", "verify-consumer-hard-stops", "verify-closing-keywords", "verify-skill-external-fetch-gate", "verify-semantic-single-source", "verify-contract-drift", "verify-cursor-tier1", "verify-openclaw-tier1", "verify-go-freeze", "verify-scm-boundary", "verify-session-ritual", "verify-plan-sequence", "verify-stubs", "verify-xbrief-drift", "verify-spec-prd-fresh", "verify-spec-drift", "rule-ownership-lint", "verify-story-ready", "verify-review-monitor", "verify-cohort-review-monitors", "verify-l4-owner", "verify-subagent-alive", "verify-subagent-steer", "subagent-pre-cancel", "subagent-steer-write", "design-critique-spend-resolve", "review-monitor-register", "review-monitor-release", "verify-tools", "verify-wip-cap", "verify-orphan-active", "verify-pr-closeout-attestable", "verify-lifecycle-visible", "verify-completed-tracked", "verify-completed-write-guard", "verify-literal-ac", "verify-ac", "verify-agents-md-budget", "verify-consumer-header-placeholder", "verify-agents-md-advisory", "verify-persisted-planning-narratives", "verify-eval-health-relocation", "verify-eval-triggers-relocation", "verify-evaluator-surface", "verify-observable-scope", "verify-operator-scope-limit", "verify-presentation-ceiling", "verify-intent-constraint", "verify-durable-effect-acquisition", "verify-consumer-test-lane", "eval-health", "eval-run", "eval-report", "eval-triggers"];
14
14
  /** Core-only CLI entrypoints without a packages/cli wrapper. */
15
- export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "spec-render", "spec-reconstruct", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "tutorial", "migrate-clause-ids", "migrate-confidence", "rule-to-verb-parity"];
15
+ export declare const CORE_MODULE_VERBS: readonly ["scm", "scm-readiness", "github-auth-modes", "github-body", "issue-emit", "issue-ingest", "issue-sync-from-xbrief", "reconcile-issues", "swarm-launch", "swarm-complete-cohort", "swarm-finalize-cohort", "swarm-finalize-owed", "swarm-pre-dispatch", "swarm-readiness", "swarm-routing-verify", "swarm-routing-set", "swarm-verify-review-clean", "swarm-worktrees", "framework-commands", "pack-render", "packs-slice", "prd-render", "export-spec", "project-render", "project-write-narratives", "roadmap-render", "rule-map", "capability-map", "spec-render", "spec-reconstruct", "spec-validate", "code-structure-validate", "pack-migrate-skills", "pack-migrate-rules", "pack-migrate-strategies", "pack-migrate-patterns", "pack-migrate-swarm-spec", "policy-set", "setup-ghx", "scope-undo", "scope-demote", "scope-decompose", "changelog-resolve-unreleased", "architecture-preflight-sor", "feedback-file", "value-readback", "product-signal", "freshness-report", "decision-write", "decision-list", "docs-impact", "tutorial", "migrate-clause-ids", "migrate-confidence", "rule-to-verb-parity"];
16
16
  /** Colon aliases for triage-actions (mirrors cli-router SUBCOMMAND_ROUTES). */
17
17
  export declare const TRIAGE_ACTION_ALIAS_SUBCOMMANDS: Readonly<Record<string, string>>;
18
18
  /** Colon aliases for policy subcommands (mirrors cli-router SUBCOMMAND_ROUTES). */
package/dist/dispatch.js CHANGED
@@ -220,6 +220,7 @@ export const CORE_MODULE_VERBS = [
220
220
  "project-write-narratives",
221
221
  "roadmap-render",
222
222
  "rule-map",
223
+ "capability-map",
223
224
  "spec-render",
224
225
  "spec-reconstruct",
225
226
  "spec-validate",
@@ -272,6 +273,7 @@ export const POLICY_ACTION_ALIAS_SUBCOMMANDS = {
272
273
  "policy:set-spec-guard-enforcement": "set-spec-guard-enforcement",
273
274
  "policy:disable-host-hooks": "disable-host-hooks",
274
275
  "policy:set-ceremony-dial": "set-ceremony-dial",
276
+ "policy:set-coverage-mode": "set-coverage-mode",
275
277
  "policy:clear-value-feedback": "clear-value-feedback",
276
278
  "policy:disable-directive": "disable-directive",
277
279
  "policy:enable-directive": "enable-directive",
@@ -476,6 +478,7 @@ export const VERB_ALIASES = {
476
478
  "project:render": "project-render",
477
479
  "project:write-narratives": "project-write-narratives",
478
480
  "docs:rule-map": "rule-map",
481
+ "docs:capability-map": "capability-map",
479
482
  "project:export-spec": "export-spec",
480
483
  "pr:watch": "pr-watch",
481
484
  "pr:finish-loop": "pr-finish-loop",
@@ -2596,6 +2599,10 @@ async function loadCoreModuleHandler(verb, io) {
2596
2599
  const { runRuleMapCli } = await import("./render-cli/rule-map-cli.js");
2597
2600
  return (argv) => runRuleMapCli(argv);
2598
2601
  }
2602
+ case "capability-map": {
2603
+ const { runCapabilityMapCli } = await import("./render-cli/capability-map-cli.js");
2604
+ return (argv) => runCapabilityMapCli(argv);
2605
+ }
2599
2606
  case "export-spec": {
2600
2607
  const { runExportSpecCli } = await import("./render-cli/export-spec-cli.js");
2601
2608
  return (argv) => runExportSpecCli(argv);
package/dist/policy.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { type CeremonyDepth, type HookHost, type SpecGuardEnforcement } from "@deftai/directive-core/policy";
2
+ import { type CeremonyDepth, type CoverageMode, type HookHost, type SpecGuardEnforcement } from "@deftai/directive-core/policy";
3
3
  interface ShowArgs {
4
4
  format: "text" | "json";
5
5
  changedOnly: boolean;
@@ -8,7 +8,7 @@ interface ShowArgs {
8
8
  error?: string;
9
9
  }
10
10
  interface SetArgs {
11
- cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-destructive-gh-verbs" | "enforce-destructive-gh-verbs" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "set-spec-guard-enforcement" | "disable-host-hooks" | "disable-directive" | "enable-directive" | "resolve";
11
+ cmd: "show" | "enforce-branches" | "allow-direct-commits" | "allow-destructive-gh-verbs" | "enforce-destructive-gh-verbs" | "allow-bot-merge" | "enable-value-feedback" | "clear-value-feedback" | "set-ceremony-dial" | "set-coverage-mode" | "set-spec-guard-enforcement" | "disable-host-hooks" | "disable-directive" | "enable-directive" | "resolve";
12
12
  confirm: boolean;
13
13
  actor: string;
14
14
  note: string;
@@ -21,6 +21,8 @@ interface SetArgs {
21
21
  ceremonyOverride?: CeremonyDepth | null;
22
22
  /** #3214 ceremony dial enabled flag for set-ceremony-dial. */
23
23
  ceremonyEnabled?: boolean;
24
+ /** #5791 coverageMode target for set-coverage-mode. */
25
+ coverageMode?: CoverageMode;
24
26
  /** #5350 driftGuard.enforcement target for set-spec-guard-enforcement. */
25
27
  specGuardEnforcement?: SpecGuardEnforcement;
26
28
  /** #4375 audited setter for valueFeedback.upstreamPrompt. */
package/dist/policy.js CHANGED
@@ -6,7 +6,7 @@
6
6
  import { existsSync } from "node:fs";
7
7
  import { resolve as pathResolve, relative } from "node:path";
8
8
  import { fileURLToPath } from "node:url";
9
- import { ALLOW_BOT_MERGE_CAPABILITY_COST, ALLOW_DESTRUCTIVE_GH_VERBS_CAPABILITY_COST, CEREMONY_DEPTHS, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disableHostHooks, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, POLICY_AUDIT_NOOP_STDOUT, parseHookHost, policyColonInvocation, projectDefinitionPath, promoteSpecGuardDriftEnforcement, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, SPEC_GUARD_ENFORCEMENTS, setAllowDestructiveGhVerbs, setCeremonyDial, setPolicy, setRequireHumanMerge, } from "../vendor/directive-core/dist/policy/index.js";
9
+ import { ALLOW_BOT_MERGE_CAPABILITY_COST, ALLOW_DESTRUCTIVE_GH_VERBS_CAPABILITY_COST, CEREMONY_DEPTHS, COVERAGE_MODES, clearValueFeedback, createNoDeftDirectiveFlag, describeShadowedPlanExtension, detectNoDeftDirective, detectShadowedPlanExtensions, disableHostHooks, disclosureLine, enableValueFeedback, FIELD_VALUE_FEEDBACK, FIELD_VALUE_FEEDBACK_CLI_ALIAS, formatValueFeedbackStatusLine, humanMergeDisclosureLine, inspectAllPolicies, inspectOnePolicy, loadProjectDefinition, NO_DEFT_DIRECTIVE_DISABLED_MESSAGE, NO_DEFT_DIRECTIVE_FLAG_NAME, NO_DEFT_DIRECTIVE_INCONSISTENT_MESSAGE, POLICY_AUDIT_NOOP_STDOUT, parseHookHost, policyColonInvocation, projectDefinitionPath, promoteSpecGuardDriftEnforcement, pythonListRepr, pythonStringRepr, registeredPolicyNames, removeNoDeftDirectiveFlag, renderJson, renderText, resolveHumanMergePolicy, resolvePolicy, resolveValueFeedback, SPEC_GUARD_ENFORCEMENTS, setAllowDestructiveGhVerbs, setCeremonyDial, setCoverageMode, setPolicy, setRequireHumanMerge, } from "../vendor/directive-core/dist/policy/index.js";
10
10
  const CAPABILITY_COST_DISCLOSURE = "\u26a0 Capability-cost disclosure -- enabling direct commits to the default " +
11
11
  "branch turns OFF the deft branch-protection policy.\n" +
12
12
  " \u2022 Pre-commit + pre-push hooks will no longer block default-branch " +
@@ -114,10 +114,87 @@ export function parseShowArgs(argv) {
114
114
  /** Parse argv for the policy CLI (show + set subcommands). */
115
115
  export function parseArgs(argv) {
116
116
  if (argv.length === 0) {
117
- const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-destructive-gh-verbs|enforce-destructive-gh-verbs|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|set-spec-guard-enforcement|disable-host-hooks|disable-directive|enable-directive|resolve] ...";
117
+ const usage = "usage: policy [show|enforce-branches|allow-direct-commits|allow-destructive-gh-verbs|enforce-destructive-gh-verbs|allow-bot-merge|enable-value-feedback|clear-value-feedback|set-ceremony-dial|set-coverage-mode|set-spec-guard-enforcement|disable-host-hooks|disable-directive|enable-directive|resolve] ...";
118
118
  return makeSetError(usage);
119
119
  }
120
120
  const cmd = argv[0];
121
+ if (cmd === "set-coverage-mode") {
122
+ let confirm = false;
123
+ let actor = policyColonInvocation("set-coverage-mode");
124
+ let note = "";
125
+ let projectRoot = ".";
126
+ let coverageMode;
127
+ for (let i = 1; i < argv.length; i += 1) {
128
+ const arg = argv[i];
129
+ if (arg === "--confirm") {
130
+ confirm = true;
131
+ }
132
+ else if (arg === "--actor") {
133
+ const v = argv[i + 1];
134
+ if (v === undefined)
135
+ return makeSetError("argument --actor: expected one argument");
136
+ actor = v;
137
+ i += 1;
138
+ }
139
+ else if (arg?.startsWith("--actor=")) {
140
+ actor = arg.slice("--actor=".length);
141
+ }
142
+ else if (arg === "--note") {
143
+ const v = argv[i + 1];
144
+ if (v === undefined)
145
+ return makeSetError("argument --note: expected one argument");
146
+ note = v;
147
+ i += 1;
148
+ }
149
+ else if (arg?.startsWith("--note=")) {
150
+ note = arg.slice("--note=".length);
151
+ }
152
+ else if (arg === "--mode") {
153
+ const v = argv[i + 1];
154
+ if (v === undefined) {
155
+ return makeSetError("argument --mode: expected initial|disabled|full");
156
+ }
157
+ if (!COVERAGE_MODES.includes(v)) {
158
+ return makeSetError("argument --mode: expected initial|disabled|full, got " + JSON.stringify(v));
159
+ }
160
+ coverageMode = v;
161
+ i += 1;
162
+ }
163
+ else if (arg?.startsWith("--mode=")) {
164
+ const v = arg.slice("--mode=".length);
165
+ if (!COVERAGE_MODES.includes(v)) {
166
+ return makeSetError("argument --mode: expected initial|disabled|full, got " + JSON.stringify(v));
167
+ }
168
+ coverageMode = v;
169
+ }
170
+ else if (arg === "--project-root") {
171
+ const v = argv[i + 1];
172
+ if (v === undefined)
173
+ return makeSetError("argument --project-root: expected one argument");
174
+ projectRoot = v;
175
+ i += 1;
176
+ }
177
+ else if (arg?.startsWith("--project-root=")) {
178
+ projectRoot = arg.slice("--project-root=".length);
179
+ }
180
+ else if (arg === "--") {
181
+ }
182
+ else {
183
+ return makeSetError("unrecognized argument: " + arg);
184
+ }
185
+ }
186
+ return {
187
+ cmd: "set-coverage-mode",
188
+ confirm,
189
+ actor,
190
+ note,
191
+ projectRoot,
192
+ format: "text",
193
+ changedOnly: false,
194
+ field: null,
195
+ coverageMode,
196
+ };
197
+ }
121
198
  if (cmd === "set-spec-guard-enforcement") {
122
199
  let confirm = false;
123
200
  let actor = policyColonInvocation("set-spec-guard-enforcement");
@@ -691,6 +768,9 @@ export function run(argv) {
691
768
  if (args.cmd === "set-ceremony-dial") {
692
769
  return runSetCeremonyDial(args);
693
770
  }
771
+ if (args.cmd === "set-coverage-mode") {
772
+ return runSetCoverageMode(args);
773
+ }
694
774
  if (args.cmd === "set-spec-guard-enforcement") {
695
775
  return runSetSpecGuardEnforcement(args);
696
776
  }
@@ -720,6 +800,25 @@ function runSetSpecGuardEnforcement(args) {
720
800
  process.stdout.write(result.stdout);
721
801
  return result.exitCode;
722
802
  }
803
+ /** Persist plan.policy.coverageMode (#5791). */
804
+ function runSetCoverageMode(args) {
805
+ const root = pathResolve(args.projectRoot);
806
+ if (args.coverageMode === undefined) {
807
+ process.stdout.write("usage: policy set-coverage-mode -- --mode initial|disabled|full [--confirm] [--project-root PATH]\n" +
808
+ " Inspect: " +
809
+ policyColonInvocation("show", " --field=coverageMode") +
810
+ "\n");
811
+ return 1;
812
+ }
813
+ const result = setCoverageMode(root, {
814
+ mode: args.coverageMode,
815
+ confirm: args.confirm,
816
+ actor: args.actor,
817
+ note: args.note,
818
+ });
819
+ process.stdout.write(result.stdout);
820
+ return result.exitCode;
821
+ }
723
822
  /** Persist plan.policy.ceremonyDial override/enabled (#3214). */
724
823
  function runSetCeremonyDial(args) {
725
824
  const root = pathResolve(args.projectRoot);
@@ -29,6 +29,8 @@ interface ParsedArgs {
29
29
  markComplete: boolean;
30
30
  skillOpen: boolean;
31
31
  evaluate: boolean;
32
+ pushAdmit: boolean;
33
+ projectRoot: string | null;
32
34
  json: boolean;
33
35
  help: boolean;
34
36
  error?: string;
@@ -4,7 +4,9 @@
4
4
  * `deft pre-pr:run` starts the prescribed workflow. Opening the skill file
5
5
  * is not completion. Generic mark-complete cannot mint a pass.
6
6
  */
7
+ import { readFileSync } from "node:fs";
7
8
  import { completeRun, computeControllerObservedHash, controllerPublisher, digestApprovedCriteria, evaluateLivePrePrCheck, getDefaultPrePrStore, markComplete, noteSkillFileOpen, observeCommandPhase, PRE_PR_PHASE_IDS, phaseSpec, resolveRecordFromStore, startControllerRun, submitReviewerReport, } from "../vendor/directive-core/dist/pre-pr-controller/index.js";
9
+ import { evaluatePrePush, parsePrePushStdin } from "../vendor/directive-core/dist/preflight/index.js";
8
10
  import { isDirectEntrypoint } from "./entrypoint.js";
9
11
  const USAGE = `Usage: deft pre-pr:run [options]
10
12
 
@@ -42,6 +44,8 @@ Options:
42
44
  --mark-complete always refuses; cannot mint a pass
43
45
  --skill-open always refuses; opening the skill is not completion
44
46
  --evaluate evaluate live binding against the private store
47
+ --push-admit enrolled push admission (#5804); reads pre-push stdin
48
+ --project-root <path> project root for --push-admit / store resolution
45
49
  --json
46
50
  --help
47
51
  `;
@@ -76,6 +80,8 @@ export function parseArgs(argv) {
76
80
  markComplete: false,
77
81
  skillOpen: false,
78
82
  evaluate: false,
83
+ pushAdmit: false,
84
+ projectRoot: null,
79
85
  json: false,
80
86
  help: false,
81
87
  };
@@ -205,6 +211,18 @@ export function parseArgs(argv) {
205
211
  else if (arg === "--evaluate") {
206
212
  parsed.evaluate = true;
207
213
  }
214
+ else if (arg === "--push-admit") {
215
+ parsed.pushAdmit = true;
216
+ }
217
+ else if (arg === "--project-root" || arg?.startsWith("--project-root=")) {
218
+ const value = arg === "--project-root" ? argv[i + 1] : arg.slice("--project-root=".length);
219
+ if (value === undefined) {
220
+ return { ...parsed, error: "argument --project-root: expected one argument" };
221
+ }
222
+ parsed.projectRoot = value;
223
+ if (arg === "--project-root")
224
+ i += 1;
225
+ }
208
226
  else if (arg === "--repo" || arg?.startsWith("--repo=")) {
209
227
  const value = arg === "--repo" ? argv[i + 1] : arg.slice("--repo=".length);
210
228
  if (value === undefined)
@@ -346,6 +364,27 @@ export function run(argv) {
346
364
  process.stderr.write(`pre_pr_run: ${args.error}\n`);
347
365
  return 2;
348
366
  }
367
+ if (args.pushAdmit) {
368
+ const projectRoot = args.projectRoot?.trim() || process.cwd();
369
+ let rawStdin = "";
370
+ try {
371
+ rawStdin = readFileSync(0, "utf8");
372
+ }
373
+ catch {
374
+ rawStdin = "";
375
+ }
376
+ const refs = parsePrePushStdin(rawStdin);
377
+ const [code, msg] = evaluatePrePush(refs, {
378
+ projectRoot,
379
+ enrolledBoundPrePr: true,
380
+ rawStdin,
381
+ });
382
+ if (code === 0)
383
+ process.stdout.write(`${msg}\n`);
384
+ else
385
+ process.stderr.write(`${msg}\n`);
386
+ return code;
387
+ }
349
388
  if (args.skillOpen) {
350
389
  const d = noteSkillFileOpen();
351
390
  emit(args.json, d, d.message, true);
@@ -377,6 +416,7 @@ export function run(argv) {
377
416
  process.stderr.write("pre_pr_run: --observe-command requires --exit-code\n");
378
417
  return 2;
379
418
  }
419
+ // #5814 / #5791: mode-skip pairs use non-zero exit (lint_iteration exit 5 + LINT_ITERATION_MODE_SKIP).
380
420
  if (args.skipReason !== null && args.skipReason.length > 0 && args.exitCode === 0) {
381
421
  process.stderr.write("pre_pr_run: skip requires a non-zero --exit-code plus --skip-reason\n");
382
422
  return 2;
@@ -0,0 +1,3 @@
1
+ /** Thin dispatch wrapper for `capability-map` (#5841); mirrors rule-map-cli. */
2
+ export declare function runCapabilityMapCli(argv: readonly string[]): number;
3
+ //# sourceMappingURL=capability-map-cli.d.ts.map
@@ -0,0 +1,6 @@
1
+ import { capabilityMapMain } from "../../vendor/directive-core/dist/docs/capability-map.js";
2
+ /** Thin dispatch wrapper for `capability-map` (#5841); mirrors rule-map-cli. */
3
+ export function runCapabilityMapCli(argv) {
4
+ return capabilityMapMain(argv);
5
+ }
6
+ //# sourceMappingURL=capability-map-cli.js.map
@@ -80,6 +80,8 @@ export declare function ensureHostHooks(projectRoot: string, hostHooksPolicy?: H
80
80
  created: string[];
81
81
  modified: string[];
82
82
  };
83
+ /** Monotonic refuse-to-downgrade marker for marker-aware ensureGitHooks (#5804). */
84
+ export declare const PRE_PUSH_BOUND_PRE_PR_MARKER = "deft:pre-pr-bound-push-v1";
83
85
  /** AC8.6 / AC2.5 / F-008 — disclosed when hooks files exist but core.hooksPath cannot activate. */
84
86
  export declare const GIT_HOOKS_INACTIVE_NO_GIT = "Git hooks inactive until git init + eligible repair/self-complete (core.hooksPath not set)";
85
87
  export declare function ensureGitHooks(projectRoot: string): {
@@ -705,11 +705,16 @@ REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 1
705
705
  run_directive verify:encoding --staged --project-root "$REPO_ROOT" || exit $?
706
706
  `;
707
707
  const PRE_PUSH = `#!/usr/bin/env sh
708
+ # deft:pre-pr-bound-push-v1 — refuse-to-downgrade marker (#5804); marker-aware ensureGitHooks only
708
709
  REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)" || exit 1
709
710
  # shellcheck source=/dev/null
710
711
  . "$REPO_ROOT/.githooks/_directive-run.sh"
711
712
  run_directive verify:branch --project-root "$REPO_ROOT" || exit $?
713
+ # Enrolled bound pre-PR arm: sole-stdin (do not redirect shared run_directive to /dev/null)
714
+ run_directive pre-pr:run --push-admit --project-root "$REPO_ROOT" || exit $?
712
715
  `;
716
+ /** Monotonic refuse-to-downgrade marker for marker-aware ensureGitHooks (#5804). */
717
+ export const PRE_PUSH_BOUND_PRE_PR_MARKER = "deft:pre-pr-bound-push-v1";
713
718
  /**
714
719
  * Current OVPR helpers plus supported latest-legacy Directive git hooks
715
720
  * (`_deft-run.sh` / `run_deft` / copied-core era). True third-party hooks
@@ -751,6 +756,15 @@ export function ensureGitHooks(projectRoot) {
751
756
  conflicts.push(`${file.rel}: existing hook is not Directive-managed; refusing to overwrite (chain or remove manually)`);
752
757
  continue;
753
758
  }
759
+ // Refuse-to-downgrade: marker-aware installer will not replace a newer enrolled
760
+ // pre-push arm with an older body that lacks the monotonic marker (#5804).
761
+ if (file.rel === ".githooks/pre-push" &&
762
+ prior !== null &&
763
+ prior.includes(PRE_PUSH_BOUND_PRE_PR_MARKER) &&
764
+ !next.includes(PRE_PUSH_BOUND_PRE_PR_MARKER)) {
765
+ conflicts.push(`${file.rel}: refuse-to-downgrade enrolled bound pre-PR arm (${PRE_PUSH_BOUND_PRE_PR_MARKER}); keeping newer hook`);
766
+ continue;
767
+ }
754
768
  const change = trackChange(projectRoot, file.rel, next);
755
769
  if (change.created)
756
770
  created.push(file.rel);
@@ -39,6 +39,8 @@ Two published packages: global **`@deftai/directive`** (launcher) and project-pi
39
39
 
40
40
  Framework maintainers of this repository use a separate Node 24 pin; see [CONTRIBUTING.md](../../CONTRIBUTING.md).
41
41
 
42
+ Maintainer execution on this repo: after `git pull` / FF, hooks and ordinary `task <verb>` use the pin under `node_modules/@deftai/directive-runtime`. Tip dogfood without publishing is an explicit `task materialize:runtime` into **this** checkout only (each worktree installs/materializes its own pin). See [launcher.md](./launcher.md).
43
+
42
44
  ---
43
45
 
44
46
  ## Installation