@deftai/directive-runtime 0.129.3 → 0.129.5

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 (192) hide show
  1. package/Taskfile.yml +1 -1
  2. package/dist/hook-dispatch.js +8 -3
  3. package/dist/pre-pr-run.d.ts +7 -1
  4. package/dist/pre-pr-run.js +25 -1
  5. package/dist/verify-ac.d.ts +7 -2
  6. package/dist/verify-ac.js +13 -5
  7. package/docs/scope-provenance.md +4 -0
  8. package/package.json +1 -1
  9. package/packs/skills/skills-pack-0.1.json +3 -3
  10. package/skills/deft-directive-pre-pr/SKILL.md +27 -33
  11. package/skills/deft-directive-release/SKILL.md +23 -0
  12. package/tasks/materialize.cjs +106 -5
  13. package/tasks/materialize.test.cjs +108 -0
  14. package/tasks/materialize.yml +14 -2
  15. package/templates/agents-entry.md +1 -1
  16. package/vendor/directive-content/Taskfile.yml +1 -1
  17. package/vendor/directive-content/docs/scope-provenance.md +4 -0
  18. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +3 -3
  19. package/vendor/directive-content/skills/deft-directive-pre-pr/SKILL.md +27 -33
  20. package/vendor/directive-content/skills/deft-directive-release/SKILL.md +23 -0
  21. package/vendor/directive-content/tasks/materialize.cjs +106 -5
  22. package/vendor/directive-content/tasks/materialize.test.cjs +108 -0
  23. package/vendor/directive-content/tasks/materialize.yml +14 -2
  24. package/vendor/directive-content/templates/agents-entry.md +1 -1
  25. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  26. package/vendor/directive-core/dist/authz/classify.d.ts +6 -0
  27. package/vendor/directive-core/dist/authz/classify.d.ts.map +1 -1
  28. package/vendor/directive-core/dist/authz/classify.js +156 -2
  29. package/vendor/directive-core/dist/authz/classify.js.map +1 -1
  30. package/vendor/directive-core/dist/authz/evaluate.d.ts +5 -0
  31. package/vendor/directive-core/dist/authz/evaluate.d.ts.map +1 -1
  32. package/vendor/directive-core/dist/authz/evaluate.js +15 -5
  33. package/vendor/directive-core/dist/authz/evaluate.js.map +1 -1
  34. package/vendor/directive-core/dist/check/cached-orchestrator.d.ts.map +1 -1
  35. package/vendor/directive-core/dist/check/cached-orchestrator.js +101 -2
  36. package/vendor/directive-core/dist/check/cached-orchestrator.js.map +1 -1
  37. package/vendor/directive-core/dist/check/context.d.ts +199 -0
  38. package/vendor/directive-core/dist/check/context.d.ts.map +1 -1
  39. package/vendor/directive-core/dist/check/context.js +417 -2
  40. package/vendor/directive-core/dist/check/context.js.map +1 -1
  41. package/vendor/directive-core/dist/check/gate-lists.d.ts +42 -0
  42. package/vendor/directive-core/dist/check/gate-lists.d.ts.map +1 -1
  43. package/vendor/directive-core/dist/check/gate-lists.js +226 -0
  44. package/vendor/directive-core/dist/check/gate-lists.js.map +1 -1
  45. package/vendor/directive-core/dist/check/index.d.ts +1 -0
  46. package/vendor/directive-core/dist/check/index.d.ts.map +1 -1
  47. package/vendor/directive-core/dist/check/index.js +1 -0
  48. package/vendor/directive-core/dist/check/index.js.map +1 -1
  49. package/vendor/directive-core/dist/check/named-cause.d.ts.map +1 -1
  50. package/vendor/directive-core/dist/check/named-cause.js +1 -0
  51. package/vendor/directive-core/dist/check/named-cause.js.map +1 -1
  52. package/vendor/directive-core/dist/check/orchestrator.d.ts +1 -0
  53. package/vendor/directive-core/dist/check/orchestrator.d.ts.map +1 -1
  54. package/vendor/directive-core/dist/check/orchestrator.js +69 -4
  55. package/vendor/directive-core/dist/check/orchestrator.js.map +1 -1
  56. package/vendor/directive-core/dist/eval/health.d.ts.map +1 -1
  57. package/vendor/directive-core/dist/eval/health.js +75 -6
  58. package/vendor/directive-core/dist/eval/health.js.map +1 -1
  59. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.d.ts +7 -0
  60. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.d.ts.map +1 -1
  61. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.js +42 -0
  62. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.js.map +1 -1
  63. package/vendor/directive-core/dist/forward-coverage/diff-coverage.d.ts +2 -1
  64. package/vendor/directive-core/dist/forward-coverage/diff-coverage.d.ts.map +1 -1
  65. package/vendor/directive-core/dist/forward-coverage/diff-coverage.js +2 -1
  66. package/vendor/directive-core/dist/forward-coverage/diff-coverage.js.map +1 -1
  67. package/vendor/directive-core/dist/forward-coverage/evaluate.d.ts +4 -2
  68. package/vendor/directive-core/dist/forward-coverage/evaluate.d.ts.map +1 -1
  69. package/vendor/directive-core/dist/forward-coverage/evaluate.js +11 -4
  70. package/vendor/directive-core/dist/forward-coverage/evaluate.js.map +1 -1
  71. package/vendor/directive-core/dist/hooks/classify/host-session-identity.d.ts +15 -2
  72. package/vendor/directive-core/dist/hooks/classify/host-session-identity.d.ts.map +1 -1
  73. package/vendor/directive-core/dist/hooks/classify/host-session-identity.js +46 -5
  74. package/vendor/directive-core/dist/hooks/classify/host-session-identity.js.map +1 -1
  75. package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
  76. package/vendor/directive-core/dist/hooks/dispatcher.js +61 -10
  77. package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
  78. package/vendor/directive-core/dist/hooks/scope.d.ts +38 -9
  79. package/vendor/directive-core/dist/hooks/scope.d.ts.map +1 -1
  80. package/vendor/directive-core/dist/hooks/scope.js +102 -16
  81. package/vendor/directive-core/dist/hooks/scope.js.map +1 -1
  82. package/vendor/directive-core/dist/install-health/cheap.d.ts +11 -0
  83. package/vendor/directive-core/dist/install-health/cheap.d.ts.map +1 -1
  84. package/vendor/directive-core/dist/install-health/cheap.js +36 -2
  85. package/vendor/directive-core/dist/install-health/cheap.js.map +1 -1
  86. package/vendor/directive-core/dist/install-health/index.d.ts +1 -1
  87. package/vendor/directive-core/dist/install-health/index.d.ts.map +1 -1
  88. package/vendor/directive-core/dist/install-health/index.js +1 -1
  89. package/vendor/directive-core/dist/install-health/index.js.map +1 -1
  90. package/vendor/directive-core/dist/policy/write-fence.d.ts +7 -0
  91. package/vendor/directive-core/dist/policy/write-fence.d.ts.map +1 -1
  92. package/vendor/directive-core/dist/policy/write-fence.js +81 -14
  93. package/vendor/directive-core/dist/policy/write-fence.js.map +1 -1
  94. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts +19 -0
  95. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts.map +1 -1
  96. package/vendor/directive-core/dist/pr-closing-keywords/main.js +31 -16
  97. package/vendor/directive-core/dist/pr-closing-keywords/main.js.map +1 -1
  98. package/vendor/directive-core/dist/pr-merge-readiness/compute.d.ts +8 -0
  99. package/vendor/directive-core/dist/pr-merge-readiness/compute.d.ts.map +1 -1
  100. package/vendor/directive-core/dist/pr-merge-readiness/compute.js +54 -2
  101. package/vendor/directive-core/dist/pr-merge-readiness/compute.js.map +1 -1
  102. package/vendor/directive-core/dist/pr-merge-readiness/gh.d.ts +7 -0
  103. package/vendor/directive-core/dist/pr-merge-readiness/gh.d.ts.map +1 -1
  104. package/vendor/directive-core/dist/pr-merge-readiness/gh.js +180 -49
  105. package/vendor/directive-core/dist/pr-merge-readiness/gh.js.map +1 -1
  106. package/vendor/directive-core/dist/pr-merge-readiness/main.d.ts +2 -0
  107. package/vendor/directive-core/dist/pr-merge-readiness/main.d.ts.map +1 -1
  108. package/vendor/directive-core/dist/pr-merge-readiness/main.js +1 -0
  109. package/vendor/directive-core/dist/pr-merge-readiness/main.js.map +1 -1
  110. package/vendor/directive-core/dist/pr-monitor/monitor.d.ts.map +1 -1
  111. package/vendor/directive-core/dist/pr-monitor/monitor.js +1 -0
  112. package/vendor/directive-core/dist/pr-monitor/monitor.js.map +1 -1
  113. package/vendor/directive-core/dist/pr-monitor/readiness.d.ts.map +1 -1
  114. package/vendor/directive-core/dist/pr-monitor/readiness.js +1 -0
  115. package/vendor/directive-core/dist/pr-monitor/readiness.js.map +1 -1
  116. package/vendor/directive-core/dist/pr-monitor/types.d.ts +2 -0
  117. package/vendor/directive-core/dist/pr-monitor/types.d.ts.map +1 -1
  118. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.d.ts +6 -0
  119. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.d.ts.map +1 -1
  120. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.js +27 -0
  121. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.js.map +1 -1
  122. package/vendor/directive-core/dist/pr-wait-mergeable/constants.d.ts +15 -0
  123. package/vendor/directive-core/dist/pr-wait-mergeable/constants.d.ts.map +1 -1
  124. package/vendor/directive-core/dist/pr-wait-mergeable/constants.js +18 -0
  125. package/vendor/directive-core/dist/pr-wait-mergeable/constants.js.map +1 -1
  126. package/vendor/directive-core/dist/pr-wait-mergeable/index.d.ts +2 -1
  127. package/vendor/directive-core/dist/pr-wait-mergeable/index.d.ts.map +1 -1
  128. package/vendor/directive-core/dist/pr-wait-mergeable/index.js +2 -1
  129. package/vendor/directive-core/dist/pr-wait-mergeable/index.js.map +1 -1
  130. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.d.ts +81 -0
  131. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.d.ts.map +1 -1
  132. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.js +687 -3
  133. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.js.map +1 -1
  134. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts +59 -1
  135. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts.map +1 -1
  136. package/vendor/directive-core/dist/pre-pr-controller/controller.js +168 -5
  137. package/vendor/directive-core/dist/pre-pr-controller/controller.js.map +1 -1
  138. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts +1 -1
  139. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts.map +1 -1
  140. package/vendor/directive-core/dist/pre-pr-controller/index.js +1 -1
  141. package/vendor/directive-core/dist/pre-pr-controller/index.js.map +1 -1
  142. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts +7 -0
  143. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts.map +1 -1
  144. package/vendor/directive-core/dist/pre-pr-controller/phases.js +14 -3
  145. package/vendor/directive-core/dist/pre-pr-controller/phases.js.map +1 -1
  146. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts +1 -1
  147. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts.map +1 -1
  148. package/vendor/directive-core/dist/pre-pr-controller/types.js.map +1 -1
  149. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts.map +1 -1
  150. package/vendor/directive-core/dist/preflight-gh/pre-push.js +58 -2
  151. package/vendor/directive-core/dist/preflight-gh/pre-push.js.map +1 -1
  152. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts +1 -1
  153. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts.map +1 -1
  154. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js +1 -1
  155. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js.map +1 -1
  156. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts +1 -1
  157. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts.map +1 -1
  158. package/vendor/directive-core/dist/product-first-done-gate/index.js +1 -1
  159. package/vendor/directive-core/dist/product-first-done-gate/index.js.map +1 -1
  160. package/vendor/directive-core/dist/release/pipeline.d.ts.map +1 -1
  161. package/vendor/directive-core/dist/release/pipeline.js +22 -23
  162. package/vendor/directive-core/dist/release/pipeline.js.map +1 -1
  163. package/vendor/directive-core/dist/release/preflight.d.ts +11 -0
  164. package/vendor/directive-core/dist/release/preflight.d.ts.map +1 -1
  165. package/vendor/directive-core/dist/release/preflight.js +68 -11
  166. package/vendor/directive-core/dist/release/preflight.js.map +1 -1
  167. package/vendor/directive-core/dist/release/suite-stamp.d.ts +5 -2
  168. package/vendor/directive-core/dist/release/suite-stamp.d.ts.map +1 -1
  169. package/vendor/directive-core/dist/release/suite-stamp.js +12 -1
  170. package/vendor/directive-core/dist/release/suite-stamp.js.map +1 -1
  171. package/vendor/directive-core/dist/release/types.d.ts +10 -6
  172. package/vendor/directive-core/dist/release/types.d.ts.map +1 -1
  173. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +37 -0
  174. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
  175. package/vendor/directive-core/dist/scope/delivery-evidence.js +106 -6
  176. package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
  177. package/vendor/directive-core/dist/scope/transition.d.ts +3 -1
  178. package/vendor/directive-core/dist/scope/transition.d.ts.map +1 -1
  179. package/vendor/directive-core/dist/scope/transition.js +4 -0
  180. package/vendor/directive-core/dist/scope/transition.js.map +1 -1
  181. package/vendor/directive-core/dist/ts-check-lane/run-lane.d.ts +6 -4
  182. package/vendor/directive-core/dist/ts-check-lane/run-lane.d.ts.map +1 -1
  183. package/vendor/directive-core/dist/ts-check-lane/run-lane.js +10 -6
  184. package/vendor/directive-core/dist/ts-check-lane/run-lane.js.map +1 -1
  185. package/vendor/directive-core/dist/verify-ac/evaluate.d.ts +52 -0
  186. package/vendor/directive-core/dist/verify-ac/evaluate.d.ts.map +1 -1
  187. package/vendor/directive-core/dist/verify-ac/evaluate.js +361 -1
  188. package/vendor/directive-core/dist/verify-ac/evaluate.js.map +1 -1
  189. package/vendor/directive-core/dist/verify-ac/index.d.ts +1 -1
  190. package/vendor/directive-core/dist/verify-ac/index.d.ts.map +1 -1
  191. package/vendor/directive-core/dist/verify-ac/index.js +1 -1
  192. package/vendor/directive-core/dist/verify-ac/index.js.map +1 -1
@@ -16,12 +16,70 @@ const path = require("node:path");
16
16
  const PIN_PKG = path.join("node_modules", "@deftai", "directive-runtime");
17
17
  const LOCK_REL = path.join(".deft-scratch", "materialize-runtime.lock");
18
18
  const OVERLAY_REL = path.join(".deft-scratch", "materialize-runtime-overlay.json");
19
+ /** Release cut-context marker (#5910). Active from release entry through bump/tag. */
20
+ const CUT_CONTEXT_REL = path.join(".deft-scratch", "release-cut-context.json");
21
+ const CUT_CONTEXT_SCHEMA = "deft.release.cut-context.v1";
19
22
 
20
23
  function fail(msg, code = 2) {
21
24
  console.error(`materialize:runtime: ${msg}`);
22
25
  process.exit(code);
23
26
  }
24
27
 
28
+ function isCutContextActive(projectRoot) {
29
+ return fs.existsSync(path.join(projectRoot, CUT_CONTEXT_REL));
30
+ }
31
+
32
+ /**
33
+ * Named cut-context producer for the release cut worktree (#5910 P1).
34
+ * Write at release entry; clear after version bump/tag. While active,
35
+ * materialize:runtime refuses before it moves or replaces the pin.
36
+ * Shares the materialize lock so cut entry cannot race an in-flight replace.
37
+ */
38
+ function writeReleaseCutContext(projectRoot, meta = {}) {
39
+ const root = path.resolve(projectRoot);
40
+ const dest = path.join(root, CUT_CONTEXT_REL);
41
+ const lockPath = acquireLock(root);
42
+ try {
43
+ fs.mkdirSync(path.dirname(dest), { recursive: true });
44
+ const body = {
45
+ schema: CUT_CONTEXT_SCHEMA,
46
+ writtenAt: new Date().toISOString(),
47
+ projectRoot: root,
48
+ phase: meta.phase || "release-entry",
49
+ note:
50
+ meta.note ||
51
+ "Release cut-context active through version bump/tag; task materialize:runtime refuses pin replace (#5910).",
52
+ };
53
+ fs.writeFileSync(dest, `${JSON.stringify(body, null, 2)}\n`);
54
+ return body;
55
+ } finally {
56
+ releaseLock(lockPath);
57
+ }
58
+ }
59
+
60
+ function clearReleaseCutContext(projectRoot) {
61
+ const dest = path.join(path.resolve(projectRoot), CUT_CONTEXT_REL);
62
+ try {
63
+ fs.unlinkSync(dest);
64
+ return true;
65
+ } catch (err) {
66
+ if (err && err.code === "ENOENT") return false;
67
+ throw err;
68
+ }
69
+ }
70
+
71
+ /** Retire the materialize overlay after exact restore (#5910 P2/P4). */
72
+ function retireMaterializeOverlay(projectRoot) {
73
+ const dest = path.join(path.resolve(projectRoot), OVERLAY_REL);
74
+ try {
75
+ fs.unlinkSync(dest);
76
+ return true;
77
+ } catch (err) {
78
+ if (err && err.code === "ENOENT") return false;
79
+ throw err;
80
+ }
81
+ }
82
+
25
83
  function runNode(script, args, opts = {}) {
26
84
  const r = spawnSync(process.execPath, [script, ...args], {
27
85
  cwd: opts.cwd,
@@ -121,15 +179,14 @@ function materialize(projectRoot, opts = {}) {
121
179
  const root = path.resolve(projectRoot);
122
180
  const stageScript = path.join(root, "packages", "runtime", "scripts", "stage-bundle.mjs");
123
181
  const packScript = path.join(root, "packages", "runtime", "scripts", "pack-staged-runtime.mjs");
124
- if (!fs.existsSync(stageScript) || !fs.existsSync(packScript)) {
125
- throw new Error("stage-bundle/pack-staged-runtime scripts missing; run from framework-source checkout");
126
- }
127
182
 
128
183
  const pinDir = path.join(root, PIN_PKG);
129
184
  if (fs.existsSync(pinDir) && !isCheckoutOwnedDir(pinDir, root)) {
130
185
  throw new Error(`refusing to mutate linked/shared pin at ${pinDir}`);
131
186
  }
132
187
 
188
+ // Hold the same lock as cut entry; check cut-context under the lock so a
189
+ // mid-flight cut cannot outlive an unlocked pre-check (#5910 Greptile P1).
133
190
  const lockPath = acquireLock(root);
134
191
  const priorPinUsable = fs.existsSync(path.join(pinDir, "dist", "bin.js"));
135
192
  let priorBackup = null;
@@ -137,6 +194,14 @@ function materialize(projectRoot, opts = {}) {
137
194
  let packDir;
138
195
  let extractDir;
139
196
  try {
197
+ if (isCutContextActive(root)) {
198
+ throw new Error(
199
+ `refusing materialize:runtime while release cut-context is active (${CUT_CONTEXT_REL}); keep the published pin through version bump/tag (#5910)`,
200
+ );
201
+ }
202
+ if (!fs.existsSync(stageScript) || !fs.existsSync(packScript)) {
203
+ throw new Error("stage-bundle/pack-staged-runtime scripts missing; run from framework-source checkout");
204
+ }
140
205
  stageDir = fs.mkdtempSync(path.join(os.tmpdir(), "deft-materialize-stage-"));
141
206
  packDir = fs.mkdtempSync(path.join(os.tmpdir(), "deft-materialize-pack-"));
142
207
  runNode(stageScript, [stageDir], { cwd: root });
@@ -156,6 +221,13 @@ function materialize(projectRoot, opts = {}) {
156
221
  if (entries.length !== 1) throw new Error(`expected one package folder in tgz, got ${entries.join(",")}`);
157
222
  const extracted = path.join(extractDir, entries[0]);
158
223
 
224
+ // Final cut-context check under lock immediately before pin move/replace.
225
+ if (isCutContextActive(root)) {
226
+ throw new Error(
227
+ `refusing materialize:runtime while release cut-context is active (${CUT_CONTEXT_REL}); keep the published pin through version bump/tag (#5910)`,
228
+ );
229
+ }
230
+
159
231
  const parent = path.dirname(pinDir);
160
232
  fs.mkdirSync(parent, { recursive: true });
161
233
  const stagingPin = path.join(parent, `.directive-runtime-next-${process.pid}`);
@@ -226,9 +298,33 @@ function materialize(projectRoot, opts = {}) {
226
298
  }
227
299
 
228
300
  if (require.main === module) {
229
- const root = process.argv[2] || process.cwd();
301
+ const argv = process.argv.slice(2);
302
+ const flag = argv[0];
230
303
  try {
231
- materialize(root);
304
+ if (flag === "--write-cut-context") {
305
+ const target = argv[1] || process.cwd();
306
+ const body = writeReleaseCutContext(target);
307
+ process.stdout.write(
308
+ `materialize:runtime: cut-context written ${path.join(path.resolve(target), CUT_CONTEXT_REL)}\n`,
309
+ );
310
+ process.stdout.write(`${JSON.stringify(body)}\n`);
311
+ } else if (flag === "--clear-cut-context") {
312
+ const cleared = clearReleaseCutContext(argv[1] || process.cwd());
313
+ process.stdout.write(
314
+ cleared
315
+ ? `materialize:runtime: cut-context cleared\n`
316
+ : `materialize:runtime: cut-context absent\n`,
317
+ );
318
+ } else if (flag === "--retire-overlay") {
319
+ const retired = retireMaterializeOverlay(argv[1] || process.cwd());
320
+ process.stdout.write(
321
+ retired
322
+ ? `materialize:runtime: overlay retired\n`
323
+ : `materialize:runtime: overlay absent\n`,
324
+ );
325
+ } else {
326
+ materialize(flag || process.cwd());
327
+ }
232
328
  } catch (err) {
233
329
  fail(err && err.message ? err.message : String(err), err && err.code ? Number(err.code) || 2 : 2);
234
330
  }
@@ -240,7 +336,12 @@ module.exports = {
240
336
  releaseLock,
241
337
  isCheckoutOwnedDir,
242
338
  movePath,
339
+ isCutContextActive,
340
+ writeReleaseCutContext,
341
+ clearReleaseCutContext,
342
+ retireMaterializeOverlay,
243
343
  PIN_PKG,
244
344
  LOCK_REL,
245
345
  OVERLAY_REL,
346
+ CUT_CONTEXT_REL,
246
347
  };
@@ -20,7 +20,14 @@ const {
20
20
  isCheckoutOwnedDir,
21
21
  movePath,
22
22
  materialize,
23
+ writeReleaseCutContext,
24
+ clearReleaseCutContext,
25
+ isCutContextActive,
26
+ retireMaterializeOverlay,
23
27
  LOCK_REL,
28
+ OVERLAY_REL,
29
+ CUT_CONTEXT_REL,
30
+ PIN_PKG,
24
31
  } = require("./materialize.cjs");
25
32
 
26
33
  const roots = [];
@@ -101,3 +108,104 @@ describe("materialize isolation (#5805 P4)", () => {
101
108
  releaseLock(lock);
102
109
  });
103
110
  });
111
+
112
+ describe("release cut-context refuse (#5910 P1/P4)", () => {
113
+ function seedPublishedPin(root, version = "0.129.0") {
114
+ const pinDir = join(root, PIN_PKG);
115
+ mkdirSync(join(pinDir, "dist"), { recursive: true });
116
+ writeFileSync(
117
+ join(pinDir, "package.json"),
118
+ `${JSON.stringify({ name: "@deftai/directive-runtime", version }, null, 2)}\n`,
119
+ );
120
+ writeFileSync(join(pinDir, "dist", "bin.js"), "console.log('pin');\n");
121
+ writeFileSync(
122
+ join(root, "package.json"),
123
+ `${JSON.stringify(
124
+ { private: true, devDependencies: { "@deftai/directive-runtime": version } },
125
+ null,
126
+ 2,
127
+ )}\n`,
128
+ );
129
+ return pinDir;
130
+ }
131
+
132
+ it("cut-context producer writes marker; materialize refuses before replace with prior pin intact", () => {
133
+ const root = tempRoot();
134
+ const pinDir = seedPublishedPin(root);
135
+ const priorPkg = readFileSync(join(pinDir, "package.json"), "utf8");
136
+ const body = writeReleaseCutContext(root, { phase: "release-entry" });
137
+ assert.equal(body.schema, "deft.release.cut-context.v1");
138
+ assert.equal(isCutContextActive(root), true);
139
+ assert.ok(existsSync(join(root, CUT_CONTEXT_REL)));
140
+
141
+ assert.throws(
142
+ () => materialize(root),
143
+ /refusing materialize:runtime while release cut-context is active|cut-context/i,
144
+ );
145
+ // Prior pin untouched — refuse happened before move/replace.
146
+ assert.equal(readFileSync(join(pinDir, "package.json"), "utf8"), priorPkg);
147
+ assert.equal(JSON.parse(priorPkg).version, "0.129.0");
148
+ assert.equal(existsSync(join(root, LOCK_REL)), false);
149
+ assert.equal(existsSync(join(root, OVERLAY_REL)), false);
150
+ });
151
+
152
+ it("cut entry shares the materialize lock (refuses while materialize holds it)", () => {
153
+ const root = tempRoot();
154
+ seedPublishedPin(root);
155
+ const lock = acquireLock(root);
156
+ assert.throws(
157
+ () => writeReleaseCutContext(root, { phase: "release-entry" }),
158
+ /another materialize|second writer|EEXIST|in progress/i,
159
+ );
160
+ assert.equal(isCutContextActive(root), false);
161
+ releaseLock(lock);
162
+ const body = writeReleaseCutContext(root, { phase: "release-entry" });
163
+ assert.equal(body.schema, "deft.release.cut-context.v1");
164
+ assert.equal(existsSync(join(root, LOCK_REL)), false);
165
+ });
166
+
167
+ it("without cut-context, missing stage scripts still fail after the cut guard", () => {
168
+ const root = tempRoot();
169
+ seedPublishedPin(root);
170
+ assert.equal(isCutContextActive(root), false);
171
+ assert.throws(() => materialize(root), /stage-bundle|pack-staged|missing/i);
172
+ });
173
+
174
+ it("clearReleaseCutContext retires the marker so materialize can proceed past the cut guard", () => {
175
+ const root = tempRoot();
176
+ seedPublishedPin(root);
177
+ writeReleaseCutContext(root);
178
+ assert.equal(clearReleaseCutContext(root), true);
179
+ assert.equal(isCutContextActive(root), false);
180
+ assert.throws(() => materialize(root), /stage-bundle|pack-staged|missing/i);
181
+ });
182
+
183
+ it("retireMaterializeOverlay removes the overlay marker after restore", () => {
184
+ const root = tempRoot();
185
+ mkdirSync(join(root, ".deft-scratch"), { recursive: true });
186
+ writeFileSync(join(root, OVERLAY_REL), `${JSON.stringify({ schema: "overlay" })}\n`);
187
+ assert.equal(retireMaterializeOverlay(root), true);
188
+ assert.equal(existsSync(join(root, OVERLAY_REL)), false);
189
+ assert.equal(retireMaterializeOverlay(root), false);
190
+ });
191
+
192
+ it("cut-context keeps published pin intact (bump-gate preconditions; not a full release run)", () => {
193
+ // Narrow pin-preservation proof (#5910 P4 / Greptile P2): cut-context at entry,
194
+ // materialize refuses, published pin + pin declaration stay aligned, no overlay.
195
+ // Full release-to-bump coverage stays on task release:e2e / release skill path.
196
+ const root = tempRoot();
197
+ const pinDir = seedPublishedPin(root, "0.129.0");
198
+ writeReleaseCutContext(root, { phase: "release-entry" });
199
+
200
+ assert.throws(() => materialize(root), /cut-context/i);
201
+ const installed = JSON.parse(readFileSync(join(pinDir, "package.json"), "utf8"));
202
+ assert.equal(installed.version, "0.129.0");
203
+ assert.equal(existsSync(join(root, OVERLAY_REL)), false);
204
+
205
+ // Version-bump gate preconditions only (not an executed bump).
206
+ const rootPkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
207
+ assert.equal(rootPkg.devDependencies["@deftai/directive-runtime"], "0.129.0");
208
+ assert.equal(installed.version, rootPkg.devDependencies["@deftai/directive-runtime"]);
209
+ assert.equal(isCutContextActive(root), true);
210
+ });
211
+ });
@@ -5,9 +5,21 @@ vars:
5
5
 
6
6
  tasks:
7
7
  runtime:
8
- desc: "Build tip staged-runtime and replace this checkout node_modules/@deftai/directive-runtime only (#5805). No lockfile/location-spec mutation."
8
+ desc: "Build tip staged-runtime and replace this checkout node_modules/@deftai/directive-runtime only (#5805). No lockfile/location-spec mutation. Refuses while release cut-context is active (#5910)."
9
9
  dir: "{{.USER_WORKING_DIR}}"
10
10
  deps:
11
11
  - task: :engine:_ts-build
12
12
  cmds:
13
- - node "{{.TASKFILE_DIR}}/materialize.cjs" "{{.USER_WORKING_DIR}}"
13
+ - node "{{.TASKFILE_DIR}}/materialize.cjs" "{{.USER_WORKING_DIR}}"
14
+
15
+ cut-context:
16
+ desc: "Write release cut-context marker (#5910). materialize:runtime refuses pin replace while active (entry through version bump/tag)."
17
+ dir: "{{.USER_WORKING_DIR}}"
18
+ cmds:
19
+ - node "{{.TASKFILE_DIR}}/materialize.cjs" --write-cut-context "{{.USER_WORKING_DIR}}"
20
+
21
+ clear-cut-context:
22
+ desc: "Clear release cut-context marker after version bump/tag (#5910)."
23
+ dir: "{{.USER_WORKING_DIR}}"
24
+ cmds:
25
+ - node "{{.TASKFILE_DIR}}/materialize.cjs" --clear-cut-context "{{.USER_WORKING_DIR}}"
@@ -88,7 +88,7 @@ Deft runtime is pinned as `@deftai/directive-runtime`. Full guidelines: node_mod
88
88
  ! **Dual stop (#2442):** multi-iteration work MUST have success + failure/budget stop (max iters / no-progress / budget); single-turn exempt; halt with operator-visible report; ⊗ thrash. Defaults: build, swarm, review-cycle skills. See main.md Dual Stop Rule. Ledger #3143.
89
89
  ## Rule Authority [AXIOM]
90
90
  ! Prefer `task deft:*` over AGENTS.md prose. See main.md.
91
- ! Merge chokepoint (#4379 / #2893): prefer `deft check`; else `task deft:check` on include-only consumers. One gate, not two runs.
91
+ ! Merge chokepoint (#4379 / #2893 / #6040): when the full gate runs (conflict-resolve / behind-rebase locally, or CI merge-gate (`check:merge`)), prefer `deft check`; else `task deft:check` on include-only consumers. Ordinary pre-PR is RWDL + `verify:ac` and does not require that full gate. One gate, not two runs.
92
92
  ## Thin Fail-Closed Design (#3265)
93
93
  ! One fail-closed `task deft:*` check + one remediation. See main.md.
94
94
  ## Writing bar (#3368)
@@ -419,7 +419,7 @@ tasks:
419
419
  ENGINE_CMD: 'check --framework-root "{{.TASKFILE_DIR}}" --project-root "{{.USER_WORKING_DIR}}"'
420
420
 
421
421
  test:coverage:
422
- desc: "Run tests with coverage (alias for ts:test; canonical coverage path used by task check, #2528)"
422
+ desc: "On-demand tests with coverage (alias for ts:test). Merge path is coverage-free (#6041); release Step 5 and this task are the host coverage runs."
423
423
  cmds:
424
424
  - task: ts:test
425
425
 
@@ -73,6 +73,10 @@ When an active implementation brief is **outside** the change set, membership is
73
73
 
74
74
  Membership-land (Path B activation) PRs that only touch nonterminal `xbrief|vbrief` under `proposed|pending|active` plus optional root `CHANGELOG.md` leave `metadata.productPullRequest` **unset**. Closing-keywords admits that brief-land shape when body has `deft-story: N` covering each changed nonterminal (`isBriefLandShapedDiff` + early return in `evaluateFullStoryMarkAdmission`). Optional `metadata.activationPullRequest` is provenance only — delivery readers ignore it. The stacked product PR stamps virgin `productPullRequest` on the existing null path; leftover keeps the original product stamp. ⊗ Write the activation PR number into `productPullRequest`. Legacy stamped activations unstamp once, then product stamps. Depth: `packages/core/src/pr-closing-keywords/main.ts`.
75
75
 
76
+ ### Path B activation vs product `verify:ac` (#5792)
77
+
78
+ Scope-only Path B activation must be able to clear `deft check` before merge-base write authority exists. Check inventories the complete local change set (merge-base..HEAD ∪ dirty ∪ cached ∪ untracked, with rename origins) into `PrDiffPath`, then reuses the Path B witness (`evaluatePathBActivationAdmit`). Inventory base prefers typed `plan.policy.deliveryBranch` / remote default before `master`|`main`, and git-toplevel paths are remapped to `projectRoot` so nested consumers keep brief-land shape. When the inventory is brief-land shaped and the witness admits, check records one named disposition `path_b_activation_deferred` and **defers** product acceptance commands and artifact-clause execution — it does not selectively forgive opaque npm failures and does not bank as a later product verified-pass. Local check without a PR body uses inventory brief issue-ref identity instead of `deft-story` marks; when a PR body is present, mark coverage still applies. Any product path in the inventory, or `productPullRequest` set, restores full `verify:ac`. Write authority stays merge-base-only (`loadStoryWriteFenceFromMergeBase` unchanged). Depth: `packages/core/src/verify-ac/evaluate.ts`, `packages/core/src/check/cached-orchestrator.ts`.
79
+
76
80
 
77
81
  ## Historical ship-closeout for stale merged actives (#5403)
78
82