@deftai/directive-runtime 0.129.4 → 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 (167) hide show
  1. package/dist/hook-dispatch.js +8 -3
  2. package/dist/pre-pr-run.d.ts +7 -1
  3. package/dist/pre-pr-run.js +25 -1
  4. package/dist/verify-ac.d.ts +7 -2
  5. package/dist/verify-ac.js +13 -5
  6. package/docs/scope-provenance.md +4 -0
  7. package/package.json +1 -1
  8. package/packs/skills/skills-pack-0.1.json +1 -1
  9. package/skills/deft-directive-release/SKILL.md +23 -0
  10. package/tasks/materialize.cjs +106 -5
  11. package/tasks/materialize.test.cjs +108 -0
  12. package/tasks/materialize.yml +14 -2
  13. package/vendor/directive-content/docs/scope-provenance.md +4 -0
  14. package/vendor/directive-content/packs/skills/skills-pack-0.1.json +1 -1
  15. package/vendor/directive-content/skills/deft-directive-release/SKILL.md +23 -0
  16. package/vendor/directive-content/tasks/materialize.cjs +106 -5
  17. package/vendor/directive-content/tasks/materialize.test.cjs +108 -0
  18. package/vendor/directive-content/tasks/materialize.yml +14 -2
  19. package/vendor/directive-core/dist/.tsbuildinfo +1 -1
  20. package/vendor/directive-core/dist/authz/classify.d.ts +6 -0
  21. package/vendor/directive-core/dist/authz/classify.d.ts.map +1 -1
  22. package/vendor/directive-core/dist/authz/classify.js +156 -2
  23. package/vendor/directive-core/dist/authz/classify.js.map +1 -1
  24. package/vendor/directive-core/dist/authz/evaluate.d.ts +5 -0
  25. package/vendor/directive-core/dist/authz/evaluate.d.ts.map +1 -1
  26. package/vendor/directive-core/dist/authz/evaluate.js +15 -5
  27. package/vendor/directive-core/dist/authz/evaluate.js.map +1 -1
  28. package/vendor/directive-core/dist/check/cached-orchestrator.d.ts.map +1 -1
  29. package/vendor/directive-core/dist/check/cached-orchestrator.js +101 -2
  30. package/vendor/directive-core/dist/check/cached-orchestrator.js.map +1 -1
  31. package/vendor/directive-core/dist/check/context.d.ts +199 -0
  32. package/vendor/directive-core/dist/check/context.d.ts.map +1 -1
  33. package/vendor/directive-core/dist/check/context.js +417 -2
  34. package/vendor/directive-core/dist/check/context.js.map +1 -1
  35. package/vendor/directive-core/dist/check/gate-lists.d.ts +42 -0
  36. package/vendor/directive-core/dist/check/gate-lists.d.ts.map +1 -1
  37. package/vendor/directive-core/dist/check/gate-lists.js +226 -0
  38. package/vendor/directive-core/dist/check/gate-lists.js.map +1 -1
  39. package/vendor/directive-core/dist/check/index.d.ts +1 -0
  40. package/vendor/directive-core/dist/check/index.d.ts.map +1 -1
  41. package/vendor/directive-core/dist/check/index.js +1 -0
  42. package/vendor/directive-core/dist/check/index.js.map +1 -1
  43. package/vendor/directive-core/dist/check/named-cause.d.ts.map +1 -1
  44. package/vendor/directive-core/dist/check/named-cause.js +1 -0
  45. package/vendor/directive-core/dist/check/named-cause.js.map +1 -1
  46. package/vendor/directive-core/dist/check/orchestrator.d.ts +1 -0
  47. package/vendor/directive-core/dist/check/orchestrator.d.ts.map +1 -1
  48. package/vendor/directive-core/dist/check/orchestrator.js +69 -4
  49. package/vendor/directive-core/dist/check/orchestrator.js.map +1 -1
  50. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.d.ts +7 -0
  51. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.d.ts.map +1 -1
  52. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.js +42 -0
  53. package/vendor/directive-core/dist/finish-loop/pr-finish-loop.js.map +1 -1
  54. package/vendor/directive-core/dist/hooks/classify/host-session-identity.d.ts +15 -2
  55. package/vendor/directive-core/dist/hooks/classify/host-session-identity.d.ts.map +1 -1
  56. package/vendor/directive-core/dist/hooks/classify/host-session-identity.js +46 -5
  57. package/vendor/directive-core/dist/hooks/classify/host-session-identity.js.map +1 -1
  58. package/vendor/directive-core/dist/hooks/dispatcher.d.ts.map +1 -1
  59. package/vendor/directive-core/dist/hooks/dispatcher.js +61 -10
  60. package/vendor/directive-core/dist/hooks/dispatcher.js.map +1 -1
  61. package/vendor/directive-core/dist/hooks/scope.d.ts +38 -9
  62. package/vendor/directive-core/dist/hooks/scope.d.ts.map +1 -1
  63. package/vendor/directive-core/dist/hooks/scope.js +102 -16
  64. package/vendor/directive-core/dist/hooks/scope.js.map +1 -1
  65. package/vendor/directive-core/dist/install-health/cheap.d.ts +11 -0
  66. package/vendor/directive-core/dist/install-health/cheap.d.ts.map +1 -1
  67. package/vendor/directive-core/dist/install-health/cheap.js +36 -2
  68. package/vendor/directive-core/dist/install-health/cheap.js.map +1 -1
  69. package/vendor/directive-core/dist/install-health/index.d.ts +1 -1
  70. package/vendor/directive-core/dist/install-health/index.d.ts.map +1 -1
  71. package/vendor/directive-core/dist/install-health/index.js +1 -1
  72. package/vendor/directive-core/dist/install-health/index.js.map +1 -1
  73. package/vendor/directive-core/dist/policy/write-fence.d.ts +7 -0
  74. package/vendor/directive-core/dist/policy/write-fence.d.ts.map +1 -1
  75. package/vendor/directive-core/dist/policy/write-fence.js +81 -14
  76. package/vendor/directive-core/dist/policy/write-fence.js.map +1 -1
  77. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts +19 -0
  78. package/vendor/directive-core/dist/pr-closing-keywords/main.d.ts.map +1 -1
  79. package/vendor/directive-core/dist/pr-closing-keywords/main.js +31 -16
  80. package/vendor/directive-core/dist/pr-closing-keywords/main.js.map +1 -1
  81. package/vendor/directive-core/dist/pr-merge-readiness/compute.d.ts +8 -0
  82. package/vendor/directive-core/dist/pr-merge-readiness/compute.d.ts.map +1 -1
  83. package/vendor/directive-core/dist/pr-merge-readiness/compute.js +54 -2
  84. package/vendor/directive-core/dist/pr-merge-readiness/compute.js.map +1 -1
  85. package/vendor/directive-core/dist/pr-merge-readiness/gh.d.ts +7 -0
  86. package/vendor/directive-core/dist/pr-merge-readiness/gh.d.ts.map +1 -1
  87. package/vendor/directive-core/dist/pr-merge-readiness/gh.js +180 -49
  88. package/vendor/directive-core/dist/pr-merge-readiness/gh.js.map +1 -1
  89. package/vendor/directive-core/dist/pr-merge-readiness/main.d.ts +2 -0
  90. package/vendor/directive-core/dist/pr-merge-readiness/main.d.ts.map +1 -1
  91. package/vendor/directive-core/dist/pr-merge-readiness/main.js +1 -0
  92. package/vendor/directive-core/dist/pr-merge-readiness/main.js.map +1 -1
  93. package/vendor/directive-core/dist/pr-monitor/monitor.d.ts.map +1 -1
  94. package/vendor/directive-core/dist/pr-monitor/monitor.js +1 -0
  95. package/vendor/directive-core/dist/pr-monitor/monitor.js.map +1 -1
  96. package/vendor/directive-core/dist/pr-monitor/readiness.d.ts.map +1 -1
  97. package/vendor/directive-core/dist/pr-monitor/readiness.js +1 -0
  98. package/vendor/directive-core/dist/pr-monitor/readiness.js.map +1 -1
  99. package/vendor/directive-core/dist/pr-monitor/types.d.ts +2 -0
  100. package/vendor/directive-core/dist/pr-monitor/types.d.ts.map +1 -1
  101. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.d.ts +6 -0
  102. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.d.ts.map +1 -1
  103. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.js +27 -0
  104. package/vendor/directive-core/dist/pr-wait-mergeable/cascade.js.map +1 -1
  105. package/vendor/directive-core/dist/pr-wait-mergeable/constants.d.ts +15 -0
  106. package/vendor/directive-core/dist/pr-wait-mergeable/constants.d.ts.map +1 -1
  107. package/vendor/directive-core/dist/pr-wait-mergeable/constants.js +18 -0
  108. package/vendor/directive-core/dist/pr-wait-mergeable/constants.js.map +1 -1
  109. package/vendor/directive-core/dist/pr-wait-mergeable/index.d.ts +2 -1
  110. package/vendor/directive-core/dist/pr-wait-mergeable/index.d.ts.map +1 -1
  111. package/vendor/directive-core/dist/pr-wait-mergeable/index.js +2 -1
  112. package/vendor/directive-core/dist/pr-wait-mergeable/index.js.map +1 -1
  113. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.d.ts +81 -0
  114. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.d.ts.map +1 -1
  115. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.js +687 -3
  116. package/vendor/directive-core/dist/pr-wait-mergeable/semantic-green.js.map +1 -1
  117. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts +59 -1
  118. package/vendor/directive-core/dist/pre-pr-controller/controller.d.ts.map +1 -1
  119. package/vendor/directive-core/dist/pre-pr-controller/controller.js +155 -2
  120. package/vendor/directive-core/dist/pre-pr-controller/controller.js.map +1 -1
  121. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts +1 -1
  122. package/vendor/directive-core/dist/pre-pr-controller/index.d.ts.map +1 -1
  123. package/vendor/directive-core/dist/pre-pr-controller/index.js +1 -1
  124. package/vendor/directive-core/dist/pre-pr-controller/index.js.map +1 -1
  125. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts +7 -0
  126. package/vendor/directive-core/dist/pre-pr-controller/phases.d.ts.map +1 -1
  127. package/vendor/directive-core/dist/pre-pr-controller/phases.js +11 -0
  128. package/vendor/directive-core/dist/pre-pr-controller/phases.js.map +1 -1
  129. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts +1 -1
  130. package/vendor/directive-core/dist/pre-pr-controller/types.d.ts.map +1 -1
  131. package/vendor/directive-core/dist/pre-pr-controller/types.js.map +1 -1
  132. package/vendor/directive-core/dist/preflight-gh/pre-push.d.ts.map +1 -1
  133. package/vendor/directive-core/dist/preflight-gh/pre-push.js +58 -2
  134. package/vendor/directive-core/dist/preflight-gh/pre-push.js.map +1 -1
  135. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts +1 -1
  136. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.d.ts.map +1 -1
  137. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js +1 -1
  138. package/vendor/directive-core/dist/product-first-done-gate/acceptance-resolver.js.map +1 -1
  139. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts +1 -1
  140. package/vendor/directive-core/dist/product-first-done-gate/index.d.ts.map +1 -1
  141. package/vendor/directive-core/dist/product-first-done-gate/index.js +1 -1
  142. package/vendor/directive-core/dist/product-first-done-gate/index.js.map +1 -1
  143. package/vendor/directive-core/dist/release/pipeline.d.ts.map +1 -1
  144. package/vendor/directive-core/dist/release/pipeline.js +13 -1
  145. package/vendor/directive-core/dist/release/pipeline.js.map +1 -1
  146. package/vendor/directive-core/dist/release/preflight.d.ts +11 -0
  147. package/vendor/directive-core/dist/release/preflight.d.ts.map +1 -1
  148. package/vendor/directive-core/dist/release/preflight.js +65 -0
  149. package/vendor/directive-core/dist/release/preflight.js.map +1 -1
  150. package/vendor/directive-core/dist/release/types.d.ts +4 -0
  151. package/vendor/directive-core/dist/release/types.d.ts.map +1 -1
  152. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts +37 -0
  153. package/vendor/directive-core/dist/scope/delivery-evidence.d.ts.map +1 -1
  154. package/vendor/directive-core/dist/scope/delivery-evidence.js +106 -6
  155. package/vendor/directive-core/dist/scope/delivery-evidence.js.map +1 -1
  156. package/vendor/directive-core/dist/scope/transition.d.ts +3 -1
  157. package/vendor/directive-core/dist/scope/transition.d.ts.map +1 -1
  158. package/vendor/directive-core/dist/scope/transition.js +4 -0
  159. package/vendor/directive-core/dist/scope/transition.js.map +1 -1
  160. package/vendor/directive-core/dist/verify-ac/evaluate.d.ts +52 -0
  161. package/vendor/directive-core/dist/verify-ac/evaluate.d.ts.map +1 -1
  162. package/vendor/directive-core/dist/verify-ac/evaluate.js +361 -1
  163. package/vendor/directive-core/dist/verify-ac/evaluate.js.map +1 -1
  164. package/vendor/directive-core/dist/verify-ac/index.d.ts +1 -1
  165. package/vendor/directive-core/dist/verify-ac/index.d.ts.map +1 -1
  166. package/vendor/directive-core/dist/verify-ac/index.js +1 -1
  167. 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}}"