@deftai/directive-runtime 0.127.0 → 0.129.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 (264) 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/contract-entry.js +2 -0
  8. package/dist/coverage-hotspots.js +2 -2
  9. package/dist/dispatch.d.ts +1 -1
  10. package/dist/dispatch.js +7 -0
  11. package/dist/policy.d.ts +4 -2
  12. package/dist/policy.js +101 -2
  13. package/dist/pre-pr-run.d.ts +2 -0
  14. package/dist/pre-pr-run.js +40 -0
  15. package/dist/render-cli/capability-map-cli.d.ts +3 -0
  16. package/dist/render-cli/capability-map-cli.js +6 -0
  17. package/dist/setup-wiring.d.ts +16 -1
  18. package/dist/setup-wiring.js +47 -3
  19. package/dist/setup.d.ts +4 -0
  20. package/dist/setup.js +7 -1
  21. package/dist/verify-ac.js +29 -2
  22. package/docs/getting-started.md +2 -0
  23. package/docs/known-limitations.md +1 -0
  24. package/docs/launcher.md +10 -0
  25. package/package.json +1 -1
  26. package/packs/skills/skills-pack-0.1.json +1 -1
  27. package/skills/deft-directive-pre-pr/SKILL.md +13 -3
  28. package/tasks/agent.yml +0 -2
  29. package/tasks/cache.yml +0 -16
  30. package/tasks/capacity.yml +0 -4
  31. package/tasks/change.yml +0 -4
  32. package/tasks/codebase.yml +0 -10
  33. package/tasks/commit.yml +0 -2
  34. package/tasks/coverage.yml +0 -2
  35. package/tasks/decision.yml +0 -4
  36. package/tasks/directive.yml +0 -1
  37. package/tasks/docs.yml +6 -10
  38. package/tasks/engine-invoke.cjs +79 -0
  39. package/tasks/engine-invoke.test.cjs +84 -0
  40. package/tasks/engine.yml +27 -88
  41. package/tasks/eval.yml +0 -8
  42. package/tasks/feedback.yml +0 -2
  43. package/tasks/install.yml +0 -4
  44. package/tasks/issue.yml +0 -3
  45. package/tasks/lifecycle.yml +0 -1
  46. package/tasks/materialize.cjs +246 -0
  47. package/tasks/materialize.test.cjs +103 -0
  48. package/tasks/materialize.yml +13 -0
  49. package/tasks/migrate.yml +0 -6
  50. package/tasks/packs.yml +0 -16
  51. package/tasks/plan-sequence.yml +0 -8
  52. package/tasks/policy.yml +0 -24
  53. package/tasks/pr.yml +0 -6
  54. package/tasks/prd.yml +0 -2
  55. package/tasks/product-signal.yml +0 -10
  56. package/tasks/project.yml +0 -8
  57. package/tasks/reconcile.yml +0 -2
  58. package/tasks/review-monitor.yml +0 -4
  59. package/tasks/roadmap.yml +0 -4
  60. package/tasks/scm.yml +0 -32
  61. package/tasks/scope.yml +0 -30
  62. package/tasks/slice.yml +0 -4
  63. package/tasks/spec.yml +0 -6
  64. package/tasks/subagent.yml +0 -4
  65. package/tasks/swarm.yml +0 -7
  66. package/tasks/toolchain.yml +0 -4
  67. package/tasks/triage-actions.yml +0 -8
  68. package/tasks/triage-bootstrap.yml +0 -1
  69. package/tasks/triage-bulk.yml +0 -5
  70. package/tasks/triage-classify.yml +0 -2
  71. package/tasks/triage-evaluate.yml +0 -1
  72. package/tasks/triage-metrics.yml +0 -2
  73. package/tasks/triage-queue.yml +0 -3
  74. package/tasks/triage-reconcile.yml +0 -1
  75. package/tasks/triage-scope-drift.yml +0 -1
  76. package/tasks/triage-scope.yml +0 -1
  77. package/tasks/triage-smoketest.yml +0 -1
  78. package/tasks/triage-subscribe.yml +0 -2
  79. package/tasks/tutorial.yml +0 -20
  80. package/tasks/umbrella.yml +0 -2
  81. package/tasks/value.yml +0 -2
  82. package/tasks/vbrief.yml +0 -12
  83. package/tasks/verify.yml +0 -140
  84. package/tasks/xbrief.yml +0 -6
  85. package/templates/design-critique-brief.md +3 -0
  86. package/vendor/directive-content/.githooks/_directive-run.sh +30 -0
  87. package/vendor/directive-content/.githooks/pre-commit +4 -24
  88. package/vendor/directive-content/.githooks/pre-push +11 -17
  89. package/vendor/directive-content/Taskfile.yml +16 -15
  90. package/vendor/directive-content/contracts/design-critique.md +5 -0
  91. package/vendor/directive-content/docs/getting-started.md +2 -0
  92. package/vendor/directive-content/docs/known-limitations.md +1 -0
  93. package/vendor/directive-content/docs/launcher.md +10 -0
  94. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +1 -1
  95. package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +13 -3
  96. package/vendor/directive-content/tasks/agent.yml +0 -2
  97. package/vendor/directive-content/tasks/cache.yml +0 -16
  98. package/vendor/directive-content/tasks/capacity.yml +0 -4
  99. package/vendor/directive-content/tasks/change.yml +0 -4
  100. package/vendor/directive-content/tasks/codebase.yml +0 -10
  101. package/vendor/directive-content/tasks/commit.yml +0 -2
  102. package/vendor/directive-content/tasks/coverage.yml +0 -2
  103. package/vendor/directive-content/tasks/decision.yml +0 -4
  104. package/vendor/directive-content/tasks/directive.yml +0 -1
  105. package/vendor/directive-content/tasks/docs.yml +6 -10
  106. package/vendor/directive-content/tasks/engine-invoke.cjs +79 -0
  107. package/vendor/directive-content/tasks/engine-invoke.test.cjs +84 -0
  108. package/vendor/directive-content/tasks/engine.yml +27 -88
  109. package/vendor/directive-content/tasks/eval.yml +0 -8
  110. package/vendor/directive-content/tasks/feedback.yml +0 -2
  111. package/vendor/directive-content/tasks/install.yml +0 -4
  112. package/vendor/directive-content/tasks/issue.yml +0 -3
  113. package/vendor/directive-content/tasks/lifecycle.yml +0 -1
  114. package/vendor/directive-content/tasks/materialize.cjs +246 -0
  115. package/vendor/directive-content/tasks/materialize.test.cjs +103 -0
  116. package/vendor/directive-content/tasks/materialize.yml +13 -0
  117. package/vendor/directive-content/tasks/migrate.yml +0 -6
  118. package/vendor/directive-content/tasks/packs.yml +0 -16
  119. package/vendor/directive-content/tasks/plan-sequence.yml +0 -8
  120. package/vendor/directive-content/tasks/policy.yml +0 -24
  121. package/vendor/directive-content/tasks/pr.yml +0 -6
  122. package/vendor/directive-content/tasks/prd.yml +0 -2
  123. package/vendor/directive-content/tasks/product-signal.yml +0 -10
  124. package/vendor/directive-content/tasks/project.yml +0 -8
  125. package/vendor/directive-content/tasks/reconcile.yml +0 -2
  126. package/vendor/directive-content/tasks/review-monitor.yml +0 -4
  127. package/vendor/directive-content/tasks/roadmap.yml +0 -4
  128. package/vendor/directive-content/tasks/scm.yml +0 -32
  129. package/vendor/directive-content/tasks/scope.yml +0 -30
  130. package/vendor/directive-content/tasks/slice.yml +0 -4
  131. package/vendor/directive-content/tasks/spec.yml +0 -6
  132. package/vendor/directive-content/tasks/subagent.yml +0 -4
  133. package/vendor/directive-content/tasks/swarm.yml +0 -7
  134. package/vendor/directive-content/tasks/toolchain.yml +0 -4
  135. package/vendor/directive-content/tasks/triage-actions.yml +0 -8
  136. package/vendor/directive-content/tasks/triage-bootstrap.yml +0 -1
  137. package/vendor/directive-content/tasks/triage-bulk.yml +0 -5
  138. package/vendor/directive-content/tasks/triage-classify.yml +0 -2
  139. package/vendor/directive-content/tasks/triage-evaluate.yml +0 -1
  140. package/vendor/directive-content/tasks/triage-metrics.yml +0 -2
  141. package/vendor/directive-content/tasks/triage-queue.yml +0 -3
  142. package/vendor/directive-content/tasks/triage-reconcile.yml +0 -1
  143. package/vendor/directive-content/tasks/triage-scope-drift.yml +0 -1
  144. package/vendor/directive-content/tasks/triage-scope.yml +0 -1
  145. package/vendor/directive-content/tasks/triage-smoketest.yml +0 -1
  146. package/vendor/directive-content/tasks/triage-subscribe.yml +0 -2
  147. package/vendor/directive-content/tasks/tutorial.yml +0 -20
  148. package/vendor/directive-content/tasks/umbrella.yml +0 -2
  149. package/vendor/directive-content/tasks/value.yml +0 -2
  150. package/vendor/directive-content/tasks/vbrief.yml +0 -12
  151. package/vendor/directive-content/tasks/verify.yml +0 -140
  152. package/vendor/directive-content/tasks/xbrief.yml +0 -6
  153. package/vendor/directive-content/templates/design-critique-brief.md +3 -0
  154. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  155. package/vendor/directive-core/dist/content-root.d.ts.map +1 -1
  156. package/vendor/directive-core/dist/content-root.js +8 -1
  157. package/vendor/directive-core/dist/content-root.js.map +1 -1
  158. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts +13 -5
  159. package/vendor/directive-core/dist/coverage-hotspots/evaluate.d.ts.map +1 -1
  160. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js +60 -2
  161. package/vendor/directive-core/dist/coverage-hotspots/evaluate.js.map +1 -1
  162. package/vendor/directive-core/dist/doctor/checks.d.ts.map +1 -1
  163. package/vendor/directive-core/dist/doctor/checks.js +5 -3
  164. package/vendor/directive-core/dist/doctor/checks.js.map +1 -1
  165. package/vendor/directive-core/dist/hooks/scope.d.ts +57 -0
  166. package/vendor/directive-core/dist/hooks/scope.d.ts.map +1 -1
  167. package/vendor/directive-core/dist/hooks/scope.js +171 -0
  168. package/vendor/directive-core/dist/hooks/scope.js.map +1 -1
  169. package/vendor/directive-core/dist/index.d.ts +1 -0
  170. package/vendor/directive-core/dist/index.d.ts.map +1 -1
  171. package/vendor/directive-core/dist/index.js +1 -0
  172. package/vendor/directive-core/dist/index.js.map +1 -1
  173. package/vendor/directive-core/dist/init-deposit/scaffold.d.ts +1 -1
  174. package/vendor/directive-core/dist/init-deposit/scaffold.d.ts.map +1 -1
  175. package/vendor/directive-core/dist/init-deposit/scaffold.js +1 -1
  176. package/vendor/directive-core/dist/init-deposit/scaffold.js.map +1 -1
  177. package/vendor/directive-core/dist/packs/pack-render.d.ts +6 -1
  178. package/vendor/directive-core/dist/packs/pack-render.d.ts.map +1 -1
  179. package/vendor/directive-core/dist/packs/pack-render.js +103 -78
  180. package/vendor/directive-core/dist/packs/pack-render.js.map +1 -1
  181. package/vendor/directive-core/dist/packs/packs-root.d.ts +53 -0
  182. package/vendor/directive-core/dist/packs/packs-root.d.ts.map +1 -0
  183. package/vendor/directive-core/dist/packs/packs-root.js +83 -0
  184. package/vendor/directive-core/dist/packs/packs-root.js.map +1 -0
  185. package/vendor/directive-core/dist/packs/packs-slice.d.ts.map +1 -1
  186. package/vendor/directive-core/dist/packs/packs-slice.js +6 -6
  187. package/vendor/directive-core/dist/packs/packs-slice.js.map +1 -1
  188. package/vendor/directive-core/dist/policy/coverage-mode.d.ts +84 -0
  189. package/vendor/directive-core/dist/policy/coverage-mode.d.ts.map +1 -0
  190. package/vendor/directive-core/dist/policy/coverage-mode.js +226 -0
  191. package/vendor/directive-core/dist/policy/coverage-mode.js.map +1 -0
  192. package/vendor/directive-core/dist/policy/index.d.ts +2 -0
  193. package/vendor/directive-core/dist/policy/index.d.ts.map +1 -1
  194. package/vendor/directive-core/dist/policy/index.js +60 -40
  195. package/vendor/directive-core/dist/policy/index.js.map +1 -1
  196. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts.map +1 -1
  197. package/vendor/directive-core/dist/pr-closing-keywords/main.js +137 -7
  198. package/vendor/directive-core/dist/pr-closing-keywords/main.js.map +1 -1
  199. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts +2 -0
  200. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts.map +1 -1
  201. package/vendor/directive-core/dist/pre-pr-controller/controller.js +109 -14
  202. package/vendor/directive-core/dist/pre-pr-controller/controller.js.map +1 -1
  203. package/vendor/directive-core/dist/pre-pr-controller/evaluate.d.ts +2 -0
  204. package/vendor/directive-core/dist/pre-pr-controller/evaluate.d.ts.map +1 -1
  205. package/vendor/directive-core/dist/pre-pr-controller/evaluate.js +11 -1
  206. package/vendor/directive-core/dist/pre-pr-controller/evaluate.js.map +1 -1
  207. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts +1 -1
  208. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts.map +1 -1
  209. package/vendor/directive-core/dist/pre-pr-controller/index.js +1 -1
  210. package/vendor/directive-core/dist/pre-pr-controller/index.js.map +1 -1
  211. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts +10 -0
  212. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts.map +1 -1
  213. package/vendor/directive-core/dist/pre-pr-controller/phases.js +15 -1
  214. package/vendor/directive-core/dist/pre-pr-controller/phases.js.map +1 -1
  215. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts +20 -1
  216. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts.map +1 -1
  217. package/vendor/directive-core/dist/pre-pr-controller/types.js +2 -0
  218. package/vendor/directive-core/dist/pre-pr-controller/types.js.map +1 -1
  219. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts +40 -3
  220. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts.map +1 -1
  221. package/vendor/directive-core/dist/preflight-gh/pre-push.js +353 -27
  222. package/vendor/directive-core/dist/preflight-gh/pre-push.js.map +1 -1
  223. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts +1 -1
  224. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts.map +1 -1
  225. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js +1 -1
  226. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js.map +1 -1
  227. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts +1 -1
  228. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts.map +1 -1
  229. package/vendor/directive-core/dist/product-first-done-gate/index.js +1 -1
  230. package/vendor/directive-core/dist/product-first-done-gate/index.js.map +1 -1
  231. package/vendor/directive-core/dist/release/main.d.ts.map +1 -1
  232. package/vendor/directive-core/dist/release/main.js +3 -2
  233. package/vendor/directive-core/dist/release/main.js.map +1 -1
  234. package/vendor/directive-core/dist/release/version.d.ts +14 -0
  235. package/vendor/directive-core/dist/release/version.d.ts.map +1 -1
  236. package/vendor/directive-core/dist/release/version.js +28 -0
  237. package/vendor/directive-core/dist/release/version.js.map +1 -1
  238. package/vendor/directive-core/dist/render/project-render.d.ts.map +1 -1
  239. package/vendor/directive-core/dist/render/project-render.js +1 -0
  240. package/vendor/directive-core/dist/render/project-render.js.map +1 -1
  241. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.d.ts +21 -0
  242. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.d.ts.map +1 -0
  243. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.js +95 -0
  244. package/vendor/directive-core/dist/scope/file-scope-coverage-warn.js.map +1 -0
  245. package/vendor/directive-core/dist/swarm/launch-cli.d.ts.map +1 -1
  246. package/vendor/directive-core/dist/swarm/launch-cli.js +12 -0
  247. package/vendor/directive-core/dist/swarm/launch-cli.js.map +1 -1
  248. package/vendor/directive-core/dist/swarm/launch.d.ts +6 -0
  249. package/vendor/directive-core/dist/swarm/launch.d.ts.map +1 -1
  250. package/vendor/directive-core/dist/swarm/launch.js +11 -0
  251. package/vendor/directive-core/dist/swarm/launch.js.map +1 -1
  252. package/vendor/directive-core/dist/swarm/leftover-before-activation.d.ts +27 -0
  253. package/vendor/directive-core/dist/swarm/leftover-before-activation.d.ts.map +1 -0
  254. package/vendor/directive-core/dist/swarm/leftover-before-activation.js +31 -0
  255. package/vendor/directive-core/dist/swarm/leftover-before-activation.js.map +1 -0
  256. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.d.ts +3 -3
  257. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.d.ts.map +1 -1
  258. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.js +7 -11
  259. package/vendor/directive-core/dist/verify-env/verify-hooks-installed.js.map +1 -1
  260. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.d.ts.map +1 -1
  261. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.js +1 -0
  262. package/vendor/directive-core/dist/verify-source/project-definition-mutation-boundary.js.map +1 -1
  263. package/.githooks/_deft-run.sh +0 -47
  264. package/vendor/directive-content/.githooks/_deft-run.sh +0 -47
package/tasks/docs.yml CHANGED
@@ -22,8 +22,6 @@ tasks:
22
22
  rule-map:
23
23
  desc: "Build the maintainer Rule Map (docs/RULE-MAP.md + gitignored docs/rule-map/index.html)"
24
24
  dir: '{{.USER_WORKING_DIR}}'
25
- deps:
26
- - task: :engine:_ts-build
27
25
  cmds:
28
26
  - task: :engine:invoke
29
27
  vars:
@@ -32,8 +30,6 @@ tasks:
32
30
  rule-map:check:
33
31
  desc: "Fail if committed docs/RULE-MAP.md is out of date (for CI / pre-commit gating)"
34
32
  dir: '{{.USER_WORKING_DIR}}'
35
- deps:
36
- - task: :engine:_ts-build
37
33
  cmds:
38
34
  - task: :engine:invoke
39
35
  vars:
@@ -42,15 +38,15 @@ tasks:
42
38
  capability-map:
43
39
  desc: "Generate content/docs/capabilities.md from the capability overlay (#4099)"
44
40
  dir: '{{.USER_WORKING_DIR}}'
45
- deps:
46
- - task: :engine:_ts-build
47
41
  cmds:
48
- - node "{{.DEFT_ROOT}}/packages/core/dist/docs/capability-map.js" --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}
42
+ - task: :engine:invoke
43
+ vars:
44
+ ENGINE_CMD: 'capability-map --project-root "{{.USER_WORKING_DIR}}" {{.CLI_ARGS}}'
49
45
 
50
46
  capability-map:check:
51
47
  desc: "Fail if committed content/docs/capabilities.md is stale or the overlay disagrees with registries (#4099)"
52
48
  dir: '{{.USER_WORKING_DIR}}'
53
- deps:
54
- - task: :engine:_ts-build
55
49
  cmds:
56
- - node "{{.DEFT_ROOT}}/packages/core/dist/docs/capability-map.js" --project-root "{{.USER_WORKING_DIR}}" --check
50
+ - task: :engine:invoke
51
+ vars:
52
+ ENGINE_CMD: 'capability-map --project-root "{{.USER_WORKING_DIR}}" --check'
@@ -23,6 +23,11 @@ const CONTENT_PACKAGE_NAME = "@deftai/directive-content";
23
23
  /** Single remediation when a deposit has no global CLI (#3324 / #3265). */
24
24
  const DEPOSIT_REMEDIATION = "npm i -g @deftai/directive";
25
25
  const SOURCE_BUILD_REMEDIATION = "task build";
26
+ /** Missing checkout pin remediation (#5805 Prefer-A Bound P1). */
27
+ const PIN_INSTALL_REMEDIATION =
28
+ "npm i -g @deftai/directive, then directive install --repair (or package-manager install of @deftai/directive-runtime)";
29
+ const PIN_MATERIALIZE_REMEDIATION = "task materialize:runtime";
30
+ const PIN_BIN_REL = path.join("node_modules", "@deftai", "directive-runtime", "dist", "bin.js");
26
31
 
27
32
  /**
28
33
  * cmd.exe command separators / metacharacters. Free-text DEFT_ENGINE_CMD_JSON
@@ -156,6 +161,63 @@ function hasConsumerDepositMarker(root, opts = {}) {
156
161
  * @param {string} root
157
162
  * @param {{ fs?: typeof fs, path?: typeof path }} [opts]
158
163
  */
164
+
165
+ /**
166
+ * Absolute path of the checkout-local pin binary (AC9.9 / #5805).
167
+ * @param {string} projectRoot
168
+ * @param {{ fs?: typeof fs, path?: typeof path }} [opts]
169
+ */
170
+ function resolveFrameworkPinBin(projectRoot, opts = {}) {
171
+ const pathMod = opts.path || path;
172
+ if (!projectRoot) return "";
173
+ return pathMod.join(projectRoot, "node_modules", "@deftai", "directive-runtime", "dist", "bin.js");
174
+ }
175
+
176
+ /**
177
+ * True when the checkout-local pin binary exists.
178
+ * @param {string} projectRoot
179
+ * @param {{ fs?: typeof fs, path?: typeof path }} [opts]
180
+ */
181
+ function hasFrameworkPinBin(projectRoot, opts = {}) {
182
+ const io = opts.fs || fs;
183
+ const pin = resolveFrameworkPinBin(projectRoot, opts);
184
+ if (!pin) return false;
185
+ try {
186
+ return io.existsSync(pin);
187
+ } catch {
188
+ return false;
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Framework-source ordinary invoke: pin exclusive, fail closed when missing (#5805).
194
+ * Deposit / non-buildable keep prior hasBin → vendored / global behavior.
195
+ * @param {{
196
+ * hasBin: boolean,
197
+ * isBuildableSource: boolean,
198
+ * hasPinBin: boolean,
199
+ * isRuntimeVerb?: boolean,
200
+ * hasGlobalCli?: boolean,
201
+ * }} input
202
+ */
203
+ function resolveFrameworkSourceInvoke(input) {
204
+ if (!input.isBuildableSource) {
205
+ return resolveInvokeDispatch({
206
+ hasBin: input.hasBin,
207
+ isBuildableSource: false,
208
+ isRuntimeVerb: Boolean(input.isRuntimeVerb),
209
+ hasGlobalCli: Boolean(input.hasGlobalCli),
210
+ });
211
+ }
212
+ if (input.hasPinBin) {
213
+ return { action: "vendored", binKind: "pin" };
214
+ }
215
+ return {
216
+ action: "fail-closed",
217
+ remediations: [PIN_INSTALL_REMEDIATION, PIN_MATERIALIZE_REMEDIATION],
218
+ exitCode: 2,
219
+ };
220
+ }
159
221
  function isBuildableSource(root, opts = {}) {
160
222
  if (hasConsumerDepositMarker(root, opts)) {
161
223
  return false;
@@ -337,6 +399,18 @@ if (require.main === module) {
337
399
  if (mode === "is-buildable-source") {
338
400
  process.exit(isBuildableSource(process.argv[3] || "") ? 0 : 1);
339
401
  }
402
+ if (mode === "pin-bin") {
403
+ const root = process.argv[3] || "";
404
+ const pin = resolveFrameworkPinBin(root);
405
+ if (hasFrameworkPinBin(root)) {
406
+ process.stdout.write(pin);
407
+ process.exit(0);
408
+ }
409
+ console.error("deft: missing checkout pin " + pin);
410
+ console.error(" Recovery: " + PIN_INSTALL_REMEDIATION);
411
+ console.error(" Or tip dogfood: " + PIN_MATERIALIZE_REMEDIATION);
412
+ process.exit(2);
413
+ }
340
414
  main();
341
415
  }
342
416
 
@@ -349,9 +423,14 @@ module.exports = {
349
423
  isVendoredCoreRoot,
350
424
  isBuildableSource,
351
425
  resolveInvokeDispatch,
426
+ resolveFrameworkPinBin,
427
+ hasFrameworkPinBin,
428
+ resolveFrameworkSourceInvoke,
352
429
  CONSUMER_DEPOSIT_FIELD,
353
430
  CONSUMER_DEPOSIT_MARKER_FILE,
354
431
  CONTENT_PACKAGE_NAME,
355
432
  DEPOSIT_REMEDIATION,
356
433
  SOURCE_BUILD_REMEDIATION,
434
+ PIN_INSTALL_REMEDIATION,
435
+ PIN_MATERIALIZE_REMEDIATION,
357
436
  };
@@ -533,3 +533,87 @@ describe("buildSpawnPlan — CodeQL absolute-path isolation (#3175 / alert #74)"
533
533
  assert.deepEqual(plan.args, [String.raw`C:\repo\packages\cli\dist\bin.js`, "session:start"]);
534
534
  });
535
535
  });
536
+
537
+ describe("framework pin exclusive invoke (#5805)", () => {
538
+ const {
539
+ resolveFrameworkPinBin,
540
+ hasFrameworkPinBin,
541
+ resolveFrameworkSourceInvoke,
542
+ PIN_INSTALL_REMEDIATION,
543
+ PIN_MATERIALIZE_REMEDIATION,
544
+ } = require("./engine-invoke.cjs");
545
+ const pinRoots = [];
546
+ function pinTempRoot() {
547
+ const root = mkdtempSync(join(tmpdir(), "pin-inv-"));
548
+ pinRoots.push(root);
549
+ return root;
550
+ }
551
+ after(() => {
552
+ for (const root of pinRoots) {
553
+ try {
554
+ rmSync(root, { recursive: true, force: true });
555
+ } catch {
556
+ /* ignore */
557
+ }
558
+ }
559
+ });
560
+
561
+ it("resolveFrameworkPinBin joins checkout pin path", () => {
562
+ const pin = resolveFrameworkPinBin(join("C:", "repo"));
563
+ assert.match(pin.replace(/\\/g, "/"), /node_modules\/@deftai\/directive-runtime\/dist\/bin\.js$/);
564
+ });
565
+
566
+ it("hasFrameworkPinBin is false when missing", () => {
567
+ const root = pinTempRoot();
568
+ assert.equal(hasFrameworkPinBin(root), false);
569
+ });
570
+
571
+ it("hasFrameworkPinBin is true when pin bin exists", () => {
572
+ const root = pinTempRoot();
573
+ const pin = resolveFrameworkPinBin(root);
574
+ mkdirSync(require("node:path").dirname(pin), { recursive: true });
575
+ writeFileSync(pin, "module.exports={}\n");
576
+ assert.equal(hasFrameworkPinBin(root), true);
577
+ });
578
+
579
+ it("framework-source with pin selects vendored pin (not tip dist)", () => {
580
+ const plan = resolveFrameworkSourceInvoke({
581
+ hasBin: true,
582
+ isBuildableSource: true,
583
+ hasPinBin: true,
584
+ });
585
+ assert.deepEqual(plan, { action: "vendored", binKind: "pin" });
586
+ });
587
+
588
+ it("framework-source missing pin fails closed even when tip dist / global exist", () => {
589
+ const plan = resolveFrameworkSourceInvoke({
590
+ hasBin: true,
591
+ isBuildableSource: true,
592
+ hasPinBin: false,
593
+ hasGlobalCli: true,
594
+ isRuntimeVerb: true,
595
+ });
596
+ assert.equal(plan.action, "fail-closed");
597
+ assert.equal(plan.exitCode, 2);
598
+ assert.deepEqual(plan.remediations, [PIN_INSTALL_REMEDIATION, PIN_MATERIALIZE_REMEDIATION]);
599
+ });
600
+
601
+ it("deposit path keeps prior resolveInvokeDispatch behavior", () => {
602
+ const plan = resolveFrameworkSourceInvoke({
603
+ hasBin: false,
604
+ isBuildableSource: false,
605
+ hasPinBin: false,
606
+ hasGlobalCli: true,
607
+ isRuntimeVerb: false,
608
+ });
609
+ assert.deepEqual(plan, { action: "global" });
610
+ });
611
+
612
+ it("pin-bin CLI exits 2 when missing", () => {
613
+ const root = pinTempRoot();
614
+ const script = join(__dirname, "engine-invoke.cjs");
615
+ const r = spawnSync(process.execPath, [script, "pin-bin", root], { encoding: "utf8" });
616
+ assert.equal(r.status, 2);
617
+ assert.match(r.stderr, /missing checkout pin/);
618
+ });
619
+ });
package/tasks/engine.yml CHANGED
@@ -2,11 +2,13 @@ version: '3'
2
2
 
3
3
  # Consumer engine resolution (#2022 Phase 3).
4
4
  #
5
- # Framework-source checkouts invoke the vendored `packages/runtime/dist/bin.js`.
5
+ # Framework-source checkouts invoke the checkout pin
6
+ # `node_modules/@deftai/directive-runtime/dist/bin.js` exclusively (#5805 / AC9.9).
7
+ # Tip dogfood without publish is `task materialize:runtime`, not packages/runtime/dist.
6
8
  # npm consumer deposits copy @deftai/directive-content only — no bundled CLI —
7
- # so tasks fall back to the globally installed `deft` / `directive` command.
9
+ # so tasks fall back to OVPR DEFT_ROOT/dist/bin.js or global `deft` / `directive`.
8
10
  # A deposit marker (package.json deftConsumerDeposit / .deft-consumer-deposit /
9
- # @deftai/directive-content name) forces that fallback for every verb (#3324).
11
+ # @deftai/directive-content name) forces that deposit path for every verb (#3324).
10
12
 
11
13
  vars:
12
14
  DEFT_ROOT: '{{joinPath .TASKFILE_DIR ".."}}'
@@ -59,7 +61,7 @@ tasks:
59
61
 
60
62
  invoke:
61
63
  internal: true
62
- desc: "Run a deft-ts verb from vendored bin.js (source checkout) or global deft (deposit / runtime fallback #2409 / #3324). Runtime/session verbs must not trigger engine:_ts-build / pnpm (#2181)."
64
+ desc: "Run a deft-ts verb from the checkout pin (framework-source #5805) or OVPR/global deposit path (#2409 / #3324). Ordinary framework-source verbs never fall through to packages/runtime/dist."
63
65
  # Run from the operator project root so deft verbs resolve USER_WORKING_DIR
64
66
  # correctly; without this, included engine.yml defaults cwd to tasks/ (#2022).
65
67
  dir: '{{.USER_WORKING_DIR}}'
@@ -71,23 +73,18 @@ tasks:
71
73
  cmds:
72
74
  - |
73
75
  set -eu
74
- # OVPR consumer: DEFT_ROOT is node_modules/@deftai/directive-runtime → dist/bin.js.
75
- # Framework source / legacy .deft/core: DEFT_ROOT/packages/runtime/dist/bin.js.
76
- bin=""
77
- if [ -f "{{.DEFT_ROOT}}/dist/bin.js" ]; then
78
- bin="{{.DEFT_ROOT}}/dist/bin.js"
79
- elif [ -f "{{.DEFT_ROOT}}/packages/runtime/dist/bin.js" ]; then
80
- bin="{{.DEFT_ROOT}}/packages/runtime/dist/bin.js"
81
- fi
82
- root_pkg="{{.DEFT_ROOT}}/package.json"
83
- # #3324: deposit marker (package.json field / file / content-package
84
- # name) forces is_buildable_source=0 so every verb uses global CLI.
76
+ # #3324: deposit marker forces is_buildable_source=0 (consumer / OVPR path).
85
77
  is_buildable_source=0
86
78
  if node "{{.TASKFILE_DIR}}/engine-invoke.cjs" is-buildable-source "{{.DEFT_ROOT}}"; then
87
79
  is_buildable_source=1
88
80
  fi
89
- if [ -n "$bin" ] && [ -f "$bin" ]; then
90
- if [ "$is_buildable_source" = 1 ] && [ -f "$root_pkg" ]; then
81
+ if [ "$is_buildable_source" = 1 ]; then
82
+ # #5805 Prefer-A Bound: framework-source ordinary invoke is pin-exclusive.
83
+ # No packages/runtime/dist fallthrough; missing pin fails closed.
84
+ # Resolve pin from DEFT_ROOT so subdirectory cwd still finds the checkout pin (#5805).
85
+ pin_bin=$(node "{{.TASKFILE_DIR}}/engine-invoke.cjs" pin-bin "{{.DEFT_ROOT}}" ) || exit $?
86
+ root_pkg="{{.DEFT_ROOT}}/package.json"
87
+ if [ -f "$root_pkg" ]; then
91
88
  node -e "
92
89
  const fs=require('fs');
93
90
  const pkg=JSON.parse(fs.readFileSync(process.argv[1],'utf8'));
@@ -101,80 +98,22 @@ tasks:
101
98
  }
102
99
  " "$root_pkg" || exit $?
103
100
  fi
104
- node "{{.TASKFILE_DIR}}/engine-invoke.cjs" vendored "$bin"
105
- elif [ "$is_buildable_source" = 1 ]; then
106
- first_token=$(node -e "process.stdout.write(JSON.parse(process.env.DEFT_ENGINE_CMD_JSON||'\"\"').split(/\\s+/)[0]||'')")
107
- is_runtime_verb=0
108
- case " ${first_token} " in
109
- " session:start "|" session-start "|\
110
- " session:ready "|" session-ready "|\
111
- " occupancy:steal "|" occupancy-steal "|\
112
- " occupancy:release "|" occupancy-release "|\
113
- " occupancy:heartbeat "|" occupancy-heartbeat "|\
114
- " occupancy:grant "|" occupancy-grant "|\
115
- " session:end "|" session-end "|\
116
- " lifecycle:event "|" lifecycle-event "|\
117
- " verify:session-ritual "|" verify-session-ritual "|\
118
- " verify:tools "|" verify-tools "|\
119
- " triage:summary "|" triage-summary "|\
120
- " triage:welcome "|" triage-welcome "|\
121
- " verify:cache-fresh "|" verify-cache-fresh "|\
122
- " preflight-cache "|\
123
- " ownership:doctor "|" ownership-doctor "|\
124
- " ownership:fix "|" ownership-fix "|\
125
- " verify:ownership "|" verify-ownership ")
126
- is_runtime_verb=1
127
- ;;
128
- esac
129
- if [ "${DEFT_USE_GLOBAL_CLI:-}" = "1" ]; then
130
- is_runtime_verb=1
101
+ node "{{.TASKFILE_DIR}}/engine-invoke.cjs" vendored "$pin_bin"
102
+ else
103
+ # OVPR consumer / deposit: DEFT_ROOT is often the runtime package itself.
104
+ bin=""
105
+ if [ -f "{{.DEFT_ROOT}}/dist/bin.js" ]; then
106
+ bin="{{.DEFT_ROOT}}/dist/bin.js"
131
107
  fi
132
- global_cli=""
133
- if command -v deft >/dev/null 2>&1; then
134
- global_cli=deft
108
+ if [ -n "$bin" ] && [ -f "$bin" ]; then
109
+ node "{{.TASKFILE_DIR}}/engine-invoke.cjs" vendored "$bin"
110
+ elif command -v deft >/dev/null 2>&1; then
111
+ node "{{.TASKFILE_DIR}}/engine-invoke.cjs" global deft
135
112
  elif command -v directive >/dev/null 2>&1; then
136
- global_cli=directive
137
- fi
138
- if [ "$is_runtime_verb" = 1 ] && [ -n "$global_cli" ]; then
139
- node -e "
140
- const {execFileSync}=require('child_process');
141
- const root=process.argv[1];
142
- const cli=process.argv[2];
143
- let srcVer='0.0.0-dev';
144
- try{
145
- if(process.env.DEFT_RELEASE_VERSION){
146
- srcVer=process.env.DEFT_RELEASE_VERSION;
147
- }else{
148
- srcVer=execFileSync('git',['describe','--tags','--abbrev=0'],{cwd:root,encoding:'utf8'}).trim().replace(/^v/,'');
149
- }
150
- }catch{}
151
- let globalVer='unknown';
152
- try{
153
- globalVer=execFileSync(cli,['--version'],{encoding:'utf8'}).trim();
154
- }catch{}
155
- const m=globalVer.match(/@([0-9]+\\.[0-9]+\\.[0-9]+)/)||globalVer.match(/([0-9]+\\.[0-9]+\\.[0-9]+)/);
156
- const gv=m?m[1]:globalVer;
157
- if(srcVer!=='0.0.0-dev'&&gv!=='unknown'&&gv!==srcVer){
158
- console.error('deft: using global '+cli+' ('+gv+'); source checkout is v'+srcVer+' — run task build for a local engine match.');
159
- }
160
- " "{{.DEFT_ROOT}}" "$global_cli" >&2 || true
161
- node "{{.TASKFILE_DIR}}/engine-invoke.cjs" global "$global_cli"
113
+ node "{{.TASKFILE_DIR}}/engine-invoke.cjs" global directive
162
114
  else
163
- echo "deft: CLI artifact missing under {{.DEFT_ROOT}} (tried dist/bin.js and packages/runtime/dist/bin.js)" >&2
164
- if [ "$is_runtime_verb" = 1 ]; then
165
- echo " Install global deft: npm i -g @deftai/directive" >&2
166
- echo " Or run \`task build\` first (framework source checkout)." >&2
167
- else
168
- echo " Run \`task build\` first (framework source checkout)." >&2
169
- fi
115
+ echo "deft: neither OVPR bin.js under {{.DEFT_ROOT}} nor a global deft command is available." >&2
116
+ echo " Install with: npm i -g @deftai/directive" >&2
170
117
  exit 2
171
118
  fi
172
- elif command -v deft >/dev/null 2>&1; then
173
- node "{{.TASKFILE_DIR}}/engine-invoke.cjs" global deft
174
- elif command -v directive >/dev/null 2>&1; then
175
- node "{{.TASKFILE_DIR}}/engine-invoke.cjs" global directive
176
- else
177
- echo "deft: neither OVPR/legacy bin.js under {{.DEFT_ROOT}} nor a global deft command is available." >&2
178
- echo " Install with: npm i -g @deftai/directive" >&2
179
- exit 2
180
119
  fi
package/tasks/eval.yml CHANGED
@@ -6,8 +6,6 @@ vars:
6
6
  tasks:
7
7
  health:
8
8
  desc: "Tier 0 static self-consistency aggregation -- versioned framework health score (#1703). -- task eval:health [-- --json] [--no-persist] [--project-root PATH]"
9
- deps:
10
- - task: :engine:_ts-build
11
9
  cmds:
12
10
  - task: :engine:invoke
13
11
  vars:
@@ -15,8 +13,6 @@ tasks:
15
13
 
16
14
  run:
17
15
  desc: "Tier 2 golden corpus champion-challenger eval (#1703). -- task eval:run -- --model MODEL [--seed N] [--directive-version V] [--harness NAME] [--json] [--no-persist] [--project-root PATH]"
18
- deps:
19
- - task: :engine:_ts-build
20
16
  cmds:
21
17
  - task: :engine:invoke
22
18
  vars:
@@ -24,8 +20,6 @@ tasks:
24
20
 
25
21
  report:
26
22
  desc: "Tier 2 version-diff report with significance (#1703). -- task eval:report -- --champion V --challenger V --model MODEL [--json] [--project-root PATH]"
27
- deps:
28
- - task: :engine:_ts-build
29
23
  cmds:
30
24
  - task: :engine:invoke
31
25
  vars:
@@ -33,8 +27,6 @@ tasks:
33
27
 
34
28
  triggers:
35
29
  desc: "Trigger routing coverage for AGENTS.md / Skills Index (#1586). Offline skill-pi-trigger-eval compatible eval over evals/trigger-cases.jsonl vs REFERENCES.md. -- task eval:triggers [-- --json] [--project-root PATH]"
36
- deps:
37
- - task: :engine:_ts-build
38
30
  cmds:
39
31
  - task: :engine:invoke
40
32
  vars:
@@ -6,8 +6,6 @@ vars:
6
6
  tasks:
7
7
  file:
8
8
  desc: "Draft or file a deduped framework-gap issue upstream (#1709 / #3713). -- task feedback:file -- [--summary TEXT | positional] [--context ...] [--blocker] [--confirm] [--dry-run] [--json]"
9
- deps:
10
- - task: :engine:_ts-build
11
9
  cmds:
12
10
  - task: :engine:invoke
13
11
  vars:
package/tasks/install.yml CHANGED
@@ -20,8 +20,6 @@ tasks:
20
20
  uninstall:
21
21
  desc: Remove deft entry from AGENTS.md
22
22
  dir: '{{.USER_WORKING_DIR}}'
23
- deps:
24
- - task: :engine:_ts-build
25
23
  cmds:
26
24
  - task: :engine:invoke
27
25
  vars:
@@ -62,8 +60,6 @@ tasks:
62
60
  # `task upgrade` failed on the primary npm consumer workflow. Framework-root is
63
61
  # intentionally omitted: install-upgrade auto-detects the consumer's
64
62
  # `.deft/core/VERSION` (#2053) when run from the global engine.
65
- deps:
66
- - task: :engine:_ts-build
67
63
  cmds:
68
64
  - task: :engine:invoke
69
65
  vars:
package/tasks/issue.yml CHANGED
@@ -22,8 +22,6 @@ tasks:
22
22
  ingest:
23
23
  desc: "Ingest GitHub issues as scope vBRIEFs (single <N> or --all [--label L] [--status S] [--dry-run])"
24
24
  dir: '{{.USER_WORKING_DIR}}'
25
- deps:
26
- - task: :engine:_ts-build
27
25
  cmds:
28
26
  - task: :engine:invoke
29
27
  vars:
@@ -39,7 +37,6 @@ tasks:
39
37
  emit:
40
38
  desc: "File GitHub issue(s) from scope vBRIEF(s) (<path> | --umbrella <glob> | --per-vbrief <glob> [--dry-run])"
41
39
  dir: '{{.USER_WORKING_DIR}}'
42
- deps: [":engine:_ts-build"]
43
40
  env:
44
41
  PYTHONUTF8: "1"
45
42
  cmds:
@@ -27,7 +27,6 @@ tasks:
27
27
  stats:
28
28
  desc: "Local xBRIEF lifecycle folder counts for process rollups (#2995). -- task lifecycle:stats -- --since=7d [--json] [--project-root <path>]"
29
29
  dir: '{{.USER_WORKING_DIR}}'
30
- deps: [':engine:_ts-build']
31
30
  env:
32
31
  PYTHONUTF8: "1"
33
32
  cmds: