@deftai/directive-core 0.104.0 → 0.106.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 (287) hide show
  1. package/dist/authz/classify.js +1108 -67
  2. package/dist/check/cached-orchestrator.d.ts +1 -1
  3. package/dist/check/cached-orchestrator.js +2 -2
  4. package/dist/check/named-cause.d.ts +1 -1
  5. package/dist/check/named-cause.js +34 -4
  6. package/dist/codebase/default-extractor.d.ts +5 -0
  7. package/dist/codebase/default-extractor.js +7 -15
  8. package/dist/deposit/copy-tree.js +60 -0
  9. package/dist/deposit/python-free.js +26 -18
  10. package/dist/doctor/checks.d.ts +8 -0
  11. package/dist/doctor/checks.js +37 -25
  12. package/dist/doctor/doctor-state.d.ts +4 -0
  13. package/dist/doctor/doctor-state.js +7 -1
  14. package/dist/doctor/main.js +9 -19
  15. package/dist/doctor/types.d.ts +9 -0
  16. package/dist/forward-coverage/diff-coverage.d.ts +39 -0
  17. package/dist/forward-coverage/diff-coverage.js +112 -0
  18. package/dist/forward-coverage/diff-lines.d.ts +19 -0
  19. package/dist/forward-coverage/diff-lines.js +173 -0
  20. package/dist/forward-coverage/evaluate.d.ts +24 -9
  21. package/dist/forward-coverage/evaluate.js +125 -19
  22. package/dist/fs/contained-write.d.ts +115 -1
  23. package/dist/fs/contained-write.js +241 -5
  24. package/dist/fs/mutation-ledger.d.ts +54 -0
  25. package/dist/fs/mutation-ledger.js +133 -0
  26. package/dist/fs/non-product-dirs.d.ts +79 -0
  27. package/dist/fs/non-product-dirs.js +96 -0
  28. package/dist/hooks/dispatcher.d.ts +3 -1
  29. package/dist/hooks/dispatcher.js +14 -0
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/init-deposit/agent-hooks.d.ts +1 -1
  33. package/dist/init-deposit/agent-hooks.js +18 -16
  34. package/dist/init-deposit/core-guard-pin-content.d.ts +7 -0
  35. package/dist/init-deposit/core-guard-pin-content.js +393 -0
  36. package/dist/init-deposit/gitignore.js +9 -0
  37. package/dist/init-deposit/hygiene.d.ts +47 -11
  38. package/dist/init-deposit/hygiene.js +172 -37
  39. package/dist/init-deposit/legacy-detect.js +6 -2
  40. package/dist/init-deposit/refresh.d.ts +21 -1
  41. package/dist/init-deposit/refresh.js +106 -9
  42. package/dist/init-deposit/scaffold.js +28 -279
  43. package/dist/init-deposit/slash-deposit.js +13 -7
  44. package/dist/init-deposit/xbrief-projections.d.ts +8 -1
  45. package/dist/init-deposit/xbrief-projections.js +24 -11
  46. package/dist/intake/clause-derivation.d.ts +47 -1
  47. package/dist/intake/clause-derivation.js +238 -9
  48. package/dist/intake/issue-ingest.d.ts +3 -1
  49. package/dist/intake/issue-ingest.js +35 -6
  50. package/dist/lifecycle/completed-tracked-on-delivery.d.ts +5 -0
  51. package/dist/lifecycle/completed-tracked-on-delivery.js +85 -18
  52. package/dist/lifecycle-visible/evaluate.d.ts +98 -0
  53. package/dist/lifecycle-visible/evaluate.js +710 -0
  54. package/dist/lifecycle-visible/index.d.ts +2 -0
  55. package/dist/lifecycle-visible/index.js +2 -0
  56. package/dist/literal-acceptance/capture.d.ts +10 -0
  57. package/dist/literal-acceptance/capture.js +226 -77
  58. package/dist/literal-acceptance/evaluate.d.ts +29 -4
  59. package/dist/literal-acceptance/evaluate.js +70 -2
  60. package/dist/literal-acceptance/index.d.ts +3 -3
  61. package/dist/literal-acceptance/index.js +3 -3
  62. package/dist/literal-acceptance/safety.d.ts +41 -0
  63. package/dist/literal-acceptance/safety.js +126 -2
  64. package/dist/literal-acceptance/types.d.ts +8 -0
  65. package/dist/orchestration/judgment-policy.d.ts +13 -0
  66. package/dist/orchestration/judgment-policy.js +15 -0
  67. package/dist/orchestration/probe-session.js +13 -8
  68. package/dist/orchestration/verify-judgment-gates.d.ts +4 -0
  69. package/dist/orchestration/verify-judgment-gates.js +43 -11
  70. package/dist/orphan-active/evaluate.d.ts +7 -1
  71. package/dist/orphan-active/evaluate.js +102 -23
  72. package/dist/platform/platform-capabilities.js +2 -3
  73. package/dist/policy/base-branch.d.ts +37 -0
  74. package/dist/policy/base-branch.js +114 -0
  75. package/dist/policy/branch-sync.d.ts +80 -0
  76. package/dist/policy/branch-sync.js +211 -0
  77. package/dist/policy/ceremony-dial-escalation.js +1 -0
  78. package/dist/policy/ceremony-dial.js +11 -21
  79. package/dist/policy/delivery-branch.d.ts +5 -3
  80. package/dist/policy/delivery-branch.js +7 -3
  81. package/dist/policy/file-size-thresholds.d.ts +24 -0
  82. package/dist/policy/file-size-thresholds.js +23 -0
  83. package/dist/policy/forge-outage-retry.d.ts +47 -0
  84. package/dist/policy/forge-outage-retry.js +157 -0
  85. package/dist/policy/host-hooks.d.ts +20 -0
  86. package/dist/policy/host-hooks.js +121 -2
  87. package/dist/policy/index.d.ts +7 -0
  88. package/dist/policy/index.js +66 -7
  89. package/dist/policy/org-force-on-migration.js +2 -1
  90. package/dist/policy/plan-extensions.d.ts +1 -1
  91. package/dist/policy/plan-extensions.js +2 -0
  92. package/dist/policy/product-signal.js +6 -7
  93. package/dist/policy/project-invariants.d.ts +50 -0
  94. package/dist/policy/project-invariants.js +205 -0
  95. package/dist/policy/require-human-merge.js +8 -6
  96. package/dist/policy/resolve.d.ts +7 -2
  97. package/dist/policy/resolve.js +25 -8
  98. package/dist/policy/sync-default.d.ts +129 -0
  99. package/dist/policy/sync-default.js +452 -0
  100. package/dist/policy/sync-max-files.d.ts +93 -0
  101. package/dist/policy/sync-max-files.js +192 -0
  102. package/dist/policy/value-feedback.js +7 -8
  103. package/dist/pr-monitor/absent-required.d.ts +11 -0
  104. package/dist/pr-monitor/absent-required.js +61 -0
  105. package/dist/pr-monitor/constants.d.ts +7 -0
  106. package/dist/pr-monitor/constants.js +7 -0
  107. package/dist/pr-monitor/index.d.ts +2 -1
  108. package/dist/pr-monitor/index.js +2 -1
  109. package/dist/pr-monitor/main.js +4 -0
  110. package/dist/pr-monitor/monitor.js +24 -1
  111. package/dist/pr-wait-mergeable/classify.js +6 -0
  112. package/dist/preflight/evaluate.d.ts +4 -0
  113. package/dist/preflight/evaluate.js +35 -1
  114. package/dist/preflight/index.d.ts +4 -0
  115. package/dist/preflight/index.js +2 -0
  116. package/dist/preflight/intended-placement.d.ts +62 -0
  117. package/dist/preflight/intended-placement.js +275 -0
  118. package/dist/preflight/project-invariants-gate.d.ts +29 -0
  119. package/dist/preflight/project-invariants-gate.js +82 -0
  120. package/dist/preflight-cache/evaluate.d.ts +12 -0
  121. package/dist/preflight-cache/evaluate.js +15 -1
  122. package/dist/preflight-cache/index.d.ts +1 -1
  123. package/dist/preflight-cache/index.js +1 -1
  124. package/dist/product-first-done-gate/acceptance-resolver.d.ts +128 -0
  125. package/dist/product-first-done-gate/acceptance-resolver.js +144 -0
  126. package/dist/product-first-done-gate/acceptance.d.ts +7 -4
  127. package/dist/product-first-done-gate/acceptance.js +79 -8
  128. package/dist/product-first-done-gate/empty-resolution.d.ts +4 -1
  129. package/dist/product-first-done-gate/empty-resolution.js +12 -1
  130. package/dist/product-first-done-gate/evaluate.d.ts +16 -0
  131. package/dist/product-first-done-gate/evaluate.js +298 -34
  132. package/dist/product-first-done-gate/index.d.ts +2 -0
  133. package/dist/product-first-done-gate/index.js +1 -0
  134. package/dist/release/build-dist.d.ts +101 -0
  135. package/dist/release/build-dist.js +428 -46
  136. package/dist/release/closed-verb-gate.d.ts +12 -0
  137. package/dist/release/closed-verb-gate.js +51 -0
  138. package/dist/release/index.d.ts +1 -0
  139. package/dist/release/index.js +1 -0
  140. package/dist/release/pipeline.js +7 -0
  141. package/dist/release/types.d.ts +12 -0
  142. package/dist/render/constants.d.ts +2 -1
  143. package/dist/render/constants.js +2 -1
  144. package/dist/render/framework-commands.js +4 -0
  145. package/dist/render/spec-validate.js +23 -12
  146. package/dist/run-summary/emit.d.ts +16 -10
  147. package/dist/run-summary/emit.js +26 -15
  148. package/dist/run-summary/index.d.ts +3 -2
  149. package/dist/run-summary/index.js +2 -1
  150. package/dist/run-summary/session-id.d.ts +21 -0
  151. package/dist/run-summary/session-id.js +92 -0
  152. package/dist/run-summary/types.d.ts +33 -4
  153. package/dist/run-summary/types.js +1 -0
  154. package/dist/scope/acceptance-evidence.d.ts +19 -7
  155. package/dist/scope/acceptance-evidence.js +38 -11
  156. package/dist/scope/delivery-evidence.d.ts +3 -3
  157. package/dist/scope/delivery-evidence.js +22 -27
  158. package/dist/scope/index.d.ts +1 -0
  159. package/dist/scope/index.js +1 -0
  160. package/dist/scope/main.js +15 -5
  161. package/dist/scope/parent-lineage.js +7 -6
  162. package/dist/scope/project-invariant-coverage.d.ts +54 -0
  163. package/dist/scope/project-invariant-coverage.js +322 -0
  164. package/dist/scope/promote-from-issue.js +5 -5
  165. package/dist/scope/transition.js +1 -1
  166. package/dist/scope-provenance/compare-intent.d.ts +27 -0
  167. package/dist/scope-provenance/compare-intent.js +233 -0
  168. package/dist/scope-provenance/digest.d.ts +18 -1
  169. package/dist/scope-provenance/digest.js +16 -11
  170. package/dist/scope-provenance/evaluate.d.ts +5 -1
  171. package/dist/scope-provenance/evaluate.js +67 -7
  172. package/dist/scope-provenance/extract-intent.d.ts +43 -0
  173. package/dist/scope-provenance/extract-intent.js +262 -0
  174. package/dist/scope-provenance/index.d.ts +7 -1
  175. package/dist/scope-provenance/index.js +7 -1
  176. package/dist/scope-provenance/intent-digest.d.ts +12 -0
  177. package/dist/scope-provenance/intent-digest.js +33 -0
  178. package/dist/scope-provenance/intent-evaluate.d.ts +43 -0
  179. package/dist/scope-provenance/intent-evaluate.js +149 -0
  180. package/dist/scope-provenance/json-tokenizer.d.ts +19 -0
  181. package/dist/scope-provenance/json-tokenizer.js +225 -0
  182. package/dist/scope-provenance/known-machine.d.ts +38 -0
  183. package/dist/scope-provenance/known-machine.js +157 -0
  184. package/dist/scope-provenance/mint-artifacts.d.ts +102 -0
  185. package/dist/scope-provenance/mint-artifacts.js +425 -0
  186. package/dist/session/ac-pass-banking.d.ts +9 -36
  187. package/dist/session/ac-pass-banking.js +33 -79
  188. package/dist/session/ac-pass-reuse.d.ts +53 -0
  189. package/dist/session/ac-pass-reuse.js +95 -0
  190. package/dist/session/git.js +19 -4
  191. package/dist/session/index.d.ts +4 -0
  192. package/dist/session/index.js +4 -0
  193. package/dist/session/occupancy-stress-worker.d.ts +7 -0
  194. package/dist/session/occupancy-stress-worker.js +36 -0
  195. package/dist/session/occupancy.d.ts +97 -0
  196. package/dist/session/occupancy.js +422 -0
  197. package/dist/session/openclaw-soft-rebind-deposit.js +6 -6
  198. package/dist/session/process-cost.d.ts +32 -10
  199. package/dist/session/process-cost.js +189 -1
  200. package/dist/session/product-state-hash.d.ts +26 -0
  201. package/dist/session/product-state-hash.js +700 -0
  202. package/dist/session/ritual-entrypoint.js +16 -1
  203. package/dist/session/session-ready.d.ts +2 -0
  204. package/dist/session/session-ready.js +52 -30
  205. package/dist/session/session-start.d.ts +13 -0
  206. package/dist/session/session-start.js +103 -9
  207. package/dist/session/verify-ac-session-cache.d.ts +42 -0
  208. package/dist/session/verify-ac-session-cache.js +126 -0
  209. package/dist/session/verify-session-ritual.d.ts +28 -0
  210. package/dist/session/verify-session-ritual.js +97 -5
  211. package/dist/slash/openclaw-deposit.js +13 -9
  212. package/dist/slice/constants.d.ts +2 -2
  213. package/dist/slice/constants.js +2 -2
  214. package/dist/slice/existing.js +9 -3
  215. package/dist/slice/lock.d.ts +16 -1
  216. package/dist/slice/lock.js +137 -11
  217. package/dist/story-ready/evaluate.d.ts +2 -0
  218. package/dist/story-ready/evaluate.js +13 -0
  219. package/dist/swarm/complete-cohort.d.ts +3 -0
  220. package/dist/swarm/complete-cohort.js +59 -11
  221. package/dist/swarm/finalize-cohort-cli.d.ts +7 -2
  222. package/dist/swarm/finalize-cohort-cli.js +165 -35
  223. package/dist/swarm/finalize-cohort.d.ts +1 -0
  224. package/dist/swarm/finalize-cohort.js +47 -4
  225. package/dist/swarm/launch.d.ts +22 -0
  226. package/dist/swarm/launch.js +155 -0
  227. package/dist/swarm/routing-set-cli.d.ts +11 -1
  228. package/dist/swarm/routing-set-cli.js +15 -3
  229. package/dist/swarm/routing-verify.d.ts +13 -1
  230. package/dist/swarm/routing-verify.js +60 -21
  231. package/dist/swarm/routing.d.ts +14 -0
  232. package/dist/swarm/routing.js +53 -3
  233. package/dist/telemetry-coverage/fake-trial.js +10 -0
  234. package/dist/telemetry-coverage/kinds.js +2 -0
  235. package/dist/triage/actions/index.js +4 -1
  236. package/dist/triage/bootstrap/index.js +6 -6
  237. package/dist/triage/help/registry-data.d.ts +1 -1
  238. package/dist/triage/help/registry-data.js +1 -1
  239. package/dist/triage/welcome/writers.d.ts +1 -1
  240. package/dist/triage/welcome/writers.js +10 -5
  241. package/dist/ts-check-lane/index.d.ts +3 -0
  242. package/dist/ts-check-lane/index.js +2 -0
  243. package/dist/ts-check-lane/progress-reporter.d.ts +17 -0
  244. package/dist/ts-check-lane/progress-reporter.js +38 -0
  245. package/dist/ts-check-lane/progress.d.ts +32 -0
  246. package/dist/ts-check-lane/progress.js +57 -0
  247. package/dist/ts-check-lane/run-lane.d.ts +3 -1
  248. package/dist/ts-check-lane/run-lane.js +8 -6
  249. package/dist/validate-content/validate-links.d.ts +8 -0
  250. package/dist/validate-content/validate-links.js +9 -15
  251. package/dist/value/feedback-file.js +12 -2
  252. package/dist/value/readback.d.ts +4 -1
  253. package/dist/value/readback.js +51 -12
  254. package/dist/vbrief-build/index.d.ts +1 -0
  255. package/dist/vbrief-build/index.js +1 -0
  256. package/dist/vbrief-build/project-invariants-io.d.ts +16 -0
  257. package/dist/vbrief-build/project-invariants-io.js +41 -0
  258. package/dist/vbrief-reconcile/graph.js +18 -1
  259. package/dist/vbrief-reconcile/index.d.ts +1 -1
  260. package/dist/vbrief-reconcile/index.js +1 -1
  261. package/dist/vbrief-reconcile/types.d.ts +13 -0
  262. package/dist/vbrief-reconcile/umbrellas.d.ts +14 -0
  263. package/dist/vbrief-reconcile/umbrellas.js +261 -26
  264. package/dist/vbrief-validate/index.d.ts +1 -1
  265. package/dist/vbrief-validate/index.js +1 -1
  266. package/dist/vbrief-validate/plan-hooks.d.ts +4 -0
  267. package/dist/vbrief-validate/plan-hooks.js +68 -0
  268. package/dist/vbrief-validate/schema.d.ts +4 -0
  269. package/dist/vbrief-validate/schema.js +1 -1
  270. package/dist/verify-ac/evaluate.d.ts +7 -1
  271. package/dist/verify-ac/evaluate.js +34 -26
  272. package/dist/verify-ac/flag.d.ts +4 -0
  273. package/dist/verify-ac/flag.js +16 -0
  274. package/dist/verify-ac/index.d.ts +2 -2
  275. package/dist/verify-ac/index.js +2 -2
  276. package/dist/verify-env/agent-hook-readiness.d.ts +2 -2
  277. package/dist/verify-env/agent-hook-readiness.js +12 -8
  278. package/dist/verify-env/agent-hooks-live-probe.d.ts +5 -1
  279. package/dist/verify-env/agent-hooks-live-probe.js +26 -5
  280. package/dist/verify-env/agent-hooks.js +3 -4
  281. package/dist/verify-source/contained-writes.js +2 -0
  282. package/dist/verify-source/verify-stubs.d.ts +15 -1
  283. package/dist/verify-source/verify-stubs.js +20 -16
  284. package/dist/vitest-runner/win32-coverage-tmp-setup.d.ts +5 -6
  285. package/dist/vitest-runner/win32-coverage-tmp-setup.js +5 -6
  286. package/dist/xbrief-migrate/migrate-project.js +2 -5
  287. package/package.json +7 -3
@@ -1,11 +1,13 @@
1
1
  import { existsSync, readdirSync, readFileSync } from "node:fs";
2
2
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
3
- import { hasArtifactSuffix, resolveLifecycleRoot } from "../layout/resolve.js";
3
+ import { hasArtifactSuffix, resolveLifecycleRoot, stripArtifactSuffix } from "../layout/resolve.js";
4
4
  import { detectLifecycleFolder } from "../scope/decomposed-refs.js";
5
5
  import { classifyStoredDeliveryDisposition, } from "../scope/delivery-evidence.js";
6
6
  import { runTransition } from "../scope/transition.js";
7
7
  import { collectChildUris, collectPlanRefs, resolveVbriefRef } from "../scope/vbrief-ref.js";
8
+ import { readOccupancy, releaseSwarmOccupancy } from "../session/occupancy.js";
8
9
  import { MAX_FIXPOINT_PASSES, TERMINAL_FOLDERS } from "./constants.js";
10
+ import { resolveLaunchOccupancySessionId } from "./launch.js";
9
11
  function loadPlan(path) {
10
12
  try {
11
13
  const data = JSON.parse(readFileSync(path, "utf8"));
@@ -21,6 +23,14 @@ function loadPlan(path) {
21
23
  return null;
22
24
  }
23
25
  }
26
+ function storyIdFromPath(path) {
27
+ const plan = loadPlan(path);
28
+ const id = plan !== null && typeof plan.id === "string" ? plan.id.trim() : "";
29
+ if (id.length > 0)
30
+ return id;
31
+ const name = basename(path);
32
+ return hasArtifactSuffix(name) ? stripArtifactSuffix(name) : name.replace(/\.[^.]+$/, "");
33
+ }
24
34
  function rel(path, projectRoot) {
25
35
  try {
26
36
  return resolve(path)
@@ -226,6 +236,7 @@ function completeParent(args) {
226
236
  }
227
237
  let current = parentPath;
228
238
  let action = "complete";
239
+ let activateNotice = "";
229
240
  if (folder === "pending") {
230
241
  action = "activate+complete";
231
242
  const activateResult = runTransition("activate", current);
@@ -238,18 +249,22 @@ function completeParent(args) {
238
249
  detail: `activate failed: ${activateResult.message}`,
239
250
  };
240
251
  }
252
+ activateNotice = activateResult.message.trim();
241
253
  current = join(vbriefDir, "active", parentPath.split(/[/\\]/).pop() ?? "");
242
254
  }
243
255
  const completeResult = runTransition("complete", current, new Date(), transitionOptionsFor(current, delivery));
244
256
  if (completeResult.ok) {
245
257
  settled.add(resolve(join(vbriefDir, "completed", parentPath.split(/[/\\]/).pop() ?? "")));
246
258
  }
259
+ const detail = activateNotice.length > 0
260
+ ? `${activateNotice}\n${completeResult.message}`
261
+ : completeResult.message;
247
262
  return {
248
263
  kind: "epic",
249
264
  path: relpath,
250
265
  action: completeResult.ok ? action : "failed",
251
266
  ok: completeResult.ok,
252
- detail: completeResult.message,
267
+ detail,
253
268
  };
254
269
  }
255
270
  export function sweepCohort(storyPaths, projectRoot, dryRun, delivery) {
@@ -412,6 +427,7 @@ export function completeCohort(args) {
412
427
  exitCode: 2,
413
428
  stdout: "",
414
429
  stderr: `Error: project root does not exist: ${projectRoot}\n`,
430
+ sweep: null,
415
431
  };
416
432
  }
417
433
  if (!existsSync(resolveLifecycleRoot(projectRoot))) {
@@ -419,31 +435,33 @@ export function completeCohort(args) {
419
435
  exitCode: 2,
420
436
  stdout: "",
421
437
  stderr: `Error: no vbrief/ directory under project root: ${projectRoot}\n`,
438
+ sweep: null,
422
439
  };
423
440
  }
424
441
  const { paths, errors } = resolveCohortPaths(args.stories ?? [], args.cohortGlobs ?? [], projectRoot);
425
442
  if (paths.length === 0) {
426
443
  const msg = "Error: empty cohort. Pass one or more story vBRIEF paths as positional arguments and/or --cohort <glob>.";
444
+ const empty = {
445
+ project_root: projectRoot,
446
+ dry_run: args.dryRun ?? false,
447
+ stories: [],
448
+ parents: [],
449
+ errors: errors.length > 0 ? errors : [msg],
450
+ ok: false,
451
+ };
427
452
  if (args.emitJson) {
428
- const empty = {
429
- project_root: projectRoot,
430
- dry_run: args.dryRun ?? false,
431
- stories: [],
432
- parents: [],
433
- errors: errors.length > 0 ? errors : [msg],
434
- ok: false,
435
- };
436
453
  return {
437
454
  exitCode: 2,
438
455
  stdout: `${JSON.stringify(sweepResultToDict(empty), null, 2)}\n`,
439
456
  stderr: "",
457
+ sweep: empty,
440
458
  };
441
459
  }
442
460
  let stderr = `${msg}\n`;
443
461
  for (const err of errors) {
444
462
  stderr += ` - ${err}\n`;
445
463
  }
446
- return { exitCode: 2, stdout: "", stderr };
464
+ return { exitCode: 2, stdout: "", stderr, sweep: empty };
447
465
  }
448
466
  const result = sweepCohortWithArgs({
449
467
  storyPaths: paths,
@@ -452,17 +470,47 @@ export function completeCohort(args) {
452
470
  delivery: args.delivery ?? null,
453
471
  });
454
472
  result.errors.push(...errors);
473
+ if (result.ok && args.dryRun !== true) {
474
+ const envSession = process.env.DEFT_SESSION_ID?.trim() ?? "";
475
+ let sessionId = envSession;
476
+ if (sessionId.length === 0) {
477
+ const resolved = resolveLaunchOccupancySessionId(projectRoot, {
478
+ allocationPlanId: args.allocationPlanId ?? null,
479
+ storyIds: paths.map(storyIdFromPath),
480
+ });
481
+ if (resolved.reason === "ok" && resolved.sessionId.length > 0) {
482
+ sessionId = resolved.sessionId;
483
+ }
484
+ else if (readOccupancy(projectRoot) !== null) {
485
+ result.ok = false;
486
+ result.errors.push("swarm close-out occupancy record is missing or belongs to a different cohort. " +
487
+ "Steal with occupancy:steal --confirm --occupant <id>.");
488
+ }
489
+ }
490
+ if (result.ok && sessionId.length > 0) {
491
+ const released = releaseSwarmOccupancy(projectRoot, {
492
+ env: process.env,
493
+ sessionId,
494
+ });
495
+ if (released.code !== 0) {
496
+ result.ok = false;
497
+ result.errors.push(released.message);
498
+ }
499
+ }
500
+ }
455
501
  if (args.emitJson) {
456
502
  return {
457
503
  exitCode: result.ok ? 0 : 1,
458
504
  stdout: `${JSON.stringify(sweepResultToDict(result), null, 2)}\n`,
459
505
  stderr: "",
506
+ sweep: result,
460
507
  };
461
508
  }
462
509
  return {
463
510
  exitCode: result.ok ? 0 : 1,
464
511
  stdout: `${renderSweepText(result)}\n`,
465
512
  stderr: "",
513
+ sweep: result,
466
514
  };
467
515
  }
468
516
  //# sourceMappingURL=complete-cohort.js.map
@@ -1,5 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { finalizeCohort } from "./finalize-cohort.js";
3
- export declare function parseFinalizeCohortArgv(argv: readonly string[]): Parameters<typeof finalizeCohort>[0];
2
+ import { type FinalizeCohortArgs } from "./finalize-cohort.js";
3
+ export interface ParsedFinalizeCohortArgv extends FinalizeCohortArgs {
4
+ readonly help: boolean;
5
+ readonly error: string | null;
6
+ }
7
+ export declare const FINALIZE_COHORT_USAGE = "Usage: task swarm:finalize-cohort -- [--pr <n>[,<n>...]] [--stories <ids|paths>] [options]\n\nAfter cohort PRs merge, sweep story briefs active/ -> completed/ and open the lifecycle PR.\n\nOptions:\n --pr <n>[,<n>...] Merged PR numbers (closing issues map to active stories)\n --stories <ids|paths> Explicit story tokens (repeatable)\n --repo OWNER/REPO GitHub repo (or $GH_REPO)\n --project-root <path> Project root (default: cwd)\n --base-branch <name> Sweep/PR base (default: resolved delivery branch)\n --delivery-branch <name> Delivery-branch override when policy is untyped\n --label <name> Feature-branch label\n --dry-run Print plan; no git mutation\n --no-commit Sweep without committing / opening a PR\n --no-open-pr Commit without opening a PR\n --json Machine-readable result\n -h, --help Show this help\n";
8
+ export declare function parseFinalizeCohortArgv(argv: readonly string[]): ParsedFinalizeCohortArgv;
4
9
  export declare function finalizeCohortMain(argv?: string[]): number;
5
10
  //# sourceMappingURL=finalize-cohort-cli.d.ts.map
@@ -1,67 +1,181 @@
1
1
  #!/usr/bin/env node
2
2
  import { fileURLToPath } from "node:url";
3
+ import { EXIT_CONFIG_ERROR, EXIT_OK } from "./constants.js";
3
4
  import { finalizeCohort } from "./finalize-cohort.js";
5
+ export const FINALIZE_COHORT_USAGE = `Usage: task swarm:finalize-cohort -- [--pr <n>[,<n>...]] [--stories <ids|paths>] [options]
6
+
7
+ After cohort PRs merge, sweep story briefs active/ -> completed/ and open the lifecycle PR.
8
+
9
+ Options:
10
+ --pr <n>[,<n>...] Merged PR numbers (closing issues map to active stories)
11
+ --stories <ids|paths> Explicit story tokens (repeatable)
12
+ --repo OWNER/REPO GitHub repo (or $GH_REPO)
13
+ --project-root <path> Project root (default: cwd)
14
+ --base-branch <name> Sweep/PR base (default: resolved delivery branch)
15
+ --delivery-branch <name> Delivery-branch override when policy is untyped
16
+ --label <name> Feature-branch label
17
+ --dry-run Print plan; no git mutation
18
+ --no-commit Sweep without committing / opening a PR
19
+ --no-open-pr Commit without opening a PR
20
+ --json Machine-readable result
21
+ -h, --help Show this help
22
+ `;
23
+ function equalsValue(arg, flag) {
24
+ return arg.slice(flag.length + 1);
25
+ }
26
+ function parsePrList(raw, flag, prNumbers, reject) {
27
+ if (raw.trim().length === 0) {
28
+ reject(flag);
29
+ return;
30
+ }
31
+ for (const piece of raw.split(",")) {
32
+ const trimmed = piece.trim();
33
+ if (trimmed.length === 0) {
34
+ reject(flag);
35
+ return;
36
+ }
37
+ if (!/^\d+$/.test(trimmed)) {
38
+ reject(flag);
39
+ return;
40
+ }
41
+ prNumbers.push(Number.parseInt(trimmed, 10));
42
+ }
43
+ }
4
44
  export function parseFinalizeCohortArgv(argv) {
5
45
  const prNumbers = [];
6
46
  const storyTokens = [];
7
47
  let repo = null;
8
48
  let projectRoot = ".";
9
- let baseBranch = "master";
49
+ let baseBranch;
10
50
  let deliveryBranch = null;
11
51
  let label = null;
12
52
  let dryRun = false;
13
53
  let noCommit = false;
14
54
  let noOpenPr = false;
15
55
  let emitJson = false;
56
+ let help = false;
57
+ let error = null;
58
+ const reject = (arg) => {
59
+ error ??= `unrecognized argument: ${arg}`;
60
+ };
61
+ const takeValue = (flag, nextValue) => {
62
+ if (nextValue === undefined || nextValue.startsWith("-")) {
63
+ reject(flag);
64
+ return null;
65
+ }
66
+ return nextValue;
67
+ };
16
68
  for (let i = 0; i < argv.length; i += 1) {
17
69
  const arg = argv[i];
18
70
  const next = argv[i + 1];
19
- if (arg === "--pr" && next !== undefined) {
20
- for (const piece of next.split(",")) {
21
- const trimmed = piece.trim();
22
- if (/^\d+$/.test(trimmed)) {
23
- prNumbers.push(Number.parseInt(trimmed, 10));
24
- }
71
+ if (arg === "--help" || arg === "-h") {
72
+ help = true;
73
+ }
74
+ else if (arg === "--pr") {
75
+ const value = takeValue(arg, next);
76
+ if (value !== null) {
77
+ parsePrList(value, arg, prNumbers, reject);
78
+ i += 1;
25
79
  }
26
- i += 1;
27
80
  }
28
81
  else if (arg?.startsWith("--pr=")) {
29
- for (const piece of arg.slice("--pr=".length).split(",")) {
30
- const trimmed = piece.trim();
31
- if (/^\d+$/.test(trimmed)) {
32
- prNumbers.push(Number.parseInt(trimmed, 10));
33
- }
82
+ parsePrList(equalsValue(arg, "--pr"), arg, prNumbers, reject);
83
+ }
84
+ else if (arg === "--stories") {
85
+ const value = takeValue(arg, next);
86
+ if (value !== null) {
87
+ storyTokens.push(value);
88
+ i += 1;
34
89
  }
35
90
  }
36
- else if (arg === "--stories" && next !== undefined) {
37
- storyTokens.push(next);
38
- i += 1;
91
+ else if (arg?.startsWith("--stories=")) {
92
+ const value = equalsValue(arg, "--stories");
93
+ if (value.length === 0) {
94
+ reject(arg);
95
+ }
96
+ else {
97
+ storyTokens.push(value);
98
+ }
39
99
  }
40
- else if (arg === "--repo" && next !== undefined) {
41
- repo = next;
42
- i += 1;
100
+ else if (arg === "--repo") {
101
+ const value = takeValue(arg, next);
102
+ if (value !== null) {
103
+ repo = value;
104
+ i += 1;
105
+ }
43
106
  }
44
107
  else if (arg?.startsWith("--repo=")) {
45
- repo = arg.slice("--repo=".length);
108
+ const value = equalsValue(arg, "--repo");
109
+ if (value.length === 0) {
110
+ reject(arg);
111
+ }
112
+ else {
113
+ repo = value;
114
+ }
115
+ }
116
+ else if (arg === "--project-root") {
117
+ const value = takeValue(arg, next);
118
+ if (value !== null) {
119
+ projectRoot = value;
120
+ i += 1;
121
+ }
46
122
  }
47
- else if (arg === "--project-root" && next !== undefined) {
48
- projectRoot = next;
49
- i += 1;
123
+ else if (arg?.startsWith("--project-root=")) {
124
+ const value = equalsValue(arg, "--project-root");
125
+ if (value.length === 0) {
126
+ reject(arg);
127
+ }
128
+ else {
129
+ projectRoot = value;
130
+ }
50
131
  }
51
- else if (arg === "--base-branch" && next !== undefined) {
52
- baseBranch = next;
53
- i += 1;
132
+ else if (arg === "--base-branch") {
133
+ const value = takeValue(arg, next);
134
+ if (value !== null) {
135
+ baseBranch = value;
136
+ i += 1;
137
+ }
54
138
  }
55
- else if (arg === "--delivery-branch" && next !== undefined) {
56
- deliveryBranch = next;
57
- i += 1;
139
+ else if (arg?.startsWith("--base-branch=")) {
140
+ const value = equalsValue(arg, "--base-branch");
141
+ if (value.length === 0) {
142
+ reject(arg);
143
+ }
144
+ else {
145
+ baseBranch = value;
146
+ }
147
+ }
148
+ else if (arg === "--delivery-branch") {
149
+ const value = takeValue(arg, next);
150
+ if (value !== null) {
151
+ deliveryBranch = value;
152
+ i += 1;
153
+ }
58
154
  }
59
155
  else if (arg?.startsWith("--delivery-branch=")) {
60
- deliveryBranch = arg.slice("--delivery-branch=".length);
156
+ const value = equalsValue(arg, "--delivery-branch");
157
+ if (value.length === 0) {
158
+ reject(arg);
159
+ }
160
+ else {
161
+ deliveryBranch = value;
162
+ }
163
+ }
164
+ else if (arg === "--label") {
165
+ const value = takeValue(arg, next);
166
+ if (value !== null) {
167
+ label = value;
168
+ i += 1;
169
+ }
61
170
  }
62
- else if (arg === "--label" && next !== undefined) {
63
- label = next;
64
- i += 1;
171
+ else if (arg?.startsWith("--label=")) {
172
+ const value = equalsValue(arg, "--label");
173
+ if (value.length === 0) {
174
+ reject(arg);
175
+ }
176
+ else {
177
+ label = value;
178
+ }
65
179
  }
66
180
  else if (arg === "--dry-run") {
67
181
  dryRun = true;
@@ -78,23 +192,37 @@ export function parseFinalizeCohortArgv(argv) {
78
192
  else if (arg !== undefined && !arg.startsWith("-")) {
79
193
  storyTokens.push(arg);
80
194
  }
195
+ else if (arg !== undefined) {
196
+ reject(arg);
197
+ }
81
198
  }
82
199
  return {
83
200
  prNumbers,
84
201
  storyTokens,
85
202
  repo,
86
203
  projectRoot,
87
- baseBranch,
204
+ ...(baseBranch !== undefined ? { baseBranch } : {}),
88
205
  deliveryBranch,
89
206
  label,
90
207
  dryRun,
91
208
  noCommit,
92
209
  noOpenPr,
93
210
  emitJson,
211
+ help,
212
+ error,
94
213
  };
95
214
  }
96
215
  export function finalizeCohortMain(argv = process.argv.slice(2)) {
97
- const result = finalizeCohort(parseFinalizeCohortArgv(argv));
216
+ const parsed = parseFinalizeCohortArgv(argv);
217
+ if (parsed.help) {
218
+ process.stdout.write(FINALIZE_COHORT_USAGE);
219
+ return EXIT_OK;
220
+ }
221
+ if (parsed.error !== null) {
222
+ process.stderr.write(`${parsed.error}\n`);
223
+ return EXIT_CONFIG_ERROR;
224
+ }
225
+ const result = finalizeCohort(parsed);
98
226
  if (result.stdout.length > 0) {
99
227
  process.stdout.write(result.stdout);
100
228
  }
@@ -103,7 +231,9 @@ export function finalizeCohortMain(argv = process.argv.slice(2)) {
103
231
  }
104
232
  return result.exitCode;
105
233
  }
234
+ /* v8 ignore start -- entry guard */
106
235
  if (process.argv[1] !== undefined && fileURLToPath(import.meta.url) === process.argv[1]) {
107
236
  process.exit(finalizeCohortMain());
108
237
  }
238
+ /* v8 ignore stop */
109
239
  //# sourceMappingURL=finalize-cohort-cli.js.map
@@ -13,6 +13,7 @@ export interface FinalizeCohortResult {
13
13
  readonly branch: string | null;
14
14
  readonly pr_url: string | null;
15
15
  readonly delivery_branch: string | null;
16
+ readonly sweep_base: string;
16
17
  readonly delivery_errors: readonly string[];
17
18
  readonly errors: readonly string[];
18
19
  readonly warnings: readonly string[];
@@ -51,6 +51,18 @@ function safeSegment(text) {
51
51
  function oneLine(text) {
52
52
  return text.replace(/\r?\n/g, " ");
53
53
  }
54
+ /** Existing sweep records already carry refused-stamp remediations (#3398). */
55
+ function sweepDetailLines(sweep) {
56
+ const lines = [];
57
+ for (const rec of [...sweep.stories, ...sweep.parents]) {
58
+ const detail = rec.detail.trim();
59
+ if (detail.length > 0) {
60
+ lines.push(`${rec.path}: ${detail}`);
61
+ }
62
+ }
63
+ lines.push(...sweep.errors);
64
+ return lines;
65
+ }
54
66
  function parseRepo(repo) {
55
67
  const slash = repo.indexOf("/");
56
68
  if (slash <= 0 || slash >= repo.length - 1) {
@@ -315,8 +327,6 @@ export function finalizeCohort(args) {
315
327
  const prNumbers = [...(args.prNumbers ?? [])].sort((a, b) => a - b);
316
328
  const storyTokens = splitCsv(args.storyTokens ?? []);
317
329
  const repo = args.repo ?? process.env.GH_REPO ?? null;
318
- // baseBranch is for the lifecycle sweep PR only — not delivery proof (#3041).
319
- const baseBranch = args.baseBranch ?? "master";
320
330
  const dryRun = args.dryRun ?? false;
321
331
  const noCommit = args.noCommit ?? false;
322
332
  const noOpenPr = args.noOpenPr ?? false;
@@ -339,6 +349,12 @@ export function finalizeCohort(args) {
339
349
  const deliveryBranch = policyDelivery.source === "typed"
340
350
  ? policyDelivery.branch
341
351
  : (cliDelivery ?? policyDelivery.branch);
352
+ // Sweep/PR base is distinct from delivery proof (#3041). Default via the resolved
353
+ // delivery branch — never a hardcoded "master". --base-branch remains the override.
354
+ const explicitSweepBase = args.baseBranch !== undefined && args.baseBranch !== null && args.baseBranch.trim().length > 0
355
+ ? args.baseBranch.trim()
356
+ : null;
357
+ const baseBranch = explicitSweepBase ?? deliveryBranch;
342
358
  if (!existsSync(projectRoot)) {
343
359
  return buildResponse({
344
360
  projectRoot,
@@ -352,6 +368,7 @@ export function finalizeCohort(args) {
352
368
  branch: null,
353
369
  prUrl: null,
354
370
  deliveryBranch,
371
+ sweepBase: baseBranch,
355
372
  deliveryErrors: [],
356
373
  errors: [`project root does not exist: ${projectRoot}`],
357
374
  warnings: [],
@@ -373,6 +390,7 @@ export function finalizeCohort(args) {
373
390
  branch: null,
374
391
  prUrl: null,
375
392
  deliveryBranch,
393
+ sweepBase: baseBranch,
376
394
  deliveryErrors: [],
377
395
  errors: [`no xbrief/ directory under project root: ${projectRoot}`],
378
396
  warnings: [],
@@ -534,6 +552,7 @@ export function finalizeCohort(args) {
534
552
  branch: null,
535
553
  prUrl: null,
536
554
  deliveryBranch,
555
+ sweepBase: baseBranch,
537
556
  deliveryErrors,
538
557
  errors,
539
558
  warnings,
@@ -560,6 +579,7 @@ export function finalizeCohort(args) {
560
579
  branch: null,
561
580
  prUrl: null,
562
581
  deliveryBranch,
582
+ sweepBase: baseBranch,
563
583
  deliveryErrors,
564
584
  errors,
565
585
  warnings,
@@ -640,8 +660,15 @@ export function finalizeCohort(args) {
640
660
  }
641
661
  : null,
642
662
  });
663
+ const sweep = sweepResult.sweep;
643
664
  if (sweepResult.exitCode !== 0) {
644
665
  errors.push("cohort completion sweep failed.");
666
+ if (sweep !== null) {
667
+ errors.push(...sweepDetailLines(sweep));
668
+ }
669
+ else if (sweepResult.stdout.trim().length > 0) {
670
+ errors.push(sweepResult.stdout.trim());
671
+ }
645
672
  return buildResponse({
646
673
  projectRoot,
647
674
  dryRun,
@@ -649,11 +676,12 @@ export function finalizeCohort(args) {
649
676
  prNumbers,
650
677
  storyPaths,
651
678
  closingIssues: [...closingIssues],
652
- sweep: null,
679
+ sweep,
653
680
  commitSha: null,
654
681
  branch: null,
655
682
  prUrl: null,
656
683
  deliveryBranch,
684
+ sweepBase: baseBranch,
657
685
  deliveryErrors,
658
686
  errors,
659
687
  warnings,
@@ -688,11 +716,12 @@ export function finalizeCohort(args) {
688
716
  prNumbers,
689
717
  storyPaths,
690
718
  closingIssues: [...closingIssues],
691
- sweep: null,
719
+ sweep,
692
720
  commitSha,
693
721
  branch,
694
722
  prUrl,
695
723
  deliveryBranch,
724
+ sweepBase: baseBranch,
696
725
  deliveryErrors,
697
726
  errors,
698
727
  warnings,
@@ -714,6 +743,7 @@ function buildResponse(input) {
714
743
  branch: input.branch,
715
744
  pr_url: input.prUrl,
716
745
  delivery_branch: input.deliveryBranch,
746
+ sweep_base: input.sweepBase,
717
747
  delivery_errors: input.deliveryErrors,
718
748
  errors: input.errors,
719
749
  warnings: input.warnings,
@@ -735,6 +765,7 @@ function buildResponse(input) {
735
765
  if (input.deliveryBranch !== null) {
736
766
  lines.push(` Delivery branch: ${input.deliveryBranch}`);
737
767
  }
768
+ lines.push(` Sweep base: ${input.sweepBase}`);
738
769
  if (input.prNumbers.length > 0) {
739
770
  lines.push(` PRs: ${input.prNumbers.map((n) => `#${n}`).join(", ")}`);
740
771
  }
@@ -747,6 +778,18 @@ function buildResponse(input) {
747
778
  lines.push(` - ${oneLine(path)}`);
748
779
  }
749
780
  }
781
+ if (input.sweep !== null) {
782
+ const records = [...input.sweep.stories, ...input.sweep.parents];
783
+ if (records.length > 0 || input.sweep.errors.length > 0) {
784
+ lines.push(" Sweep:");
785
+ for (const rec of records) {
786
+ lines.push(` [${rec.ok ? "ok" : "FAILED"}] ${rec.action} ${rec.path} -- ${oneLine(rec.detail)}`);
787
+ }
788
+ for (const err of input.sweep.errors) {
789
+ lines.push(` - ${oneLine(err)}`);
790
+ }
791
+ }
792
+ }
750
793
  if (input.branch !== null) {
751
794
  lines.push(` Branch: ${input.branch}`);
752
795
  }
@@ -37,6 +37,27 @@ export declare function enforceGates(resolved: readonly ResolvedStory[], project
37
37
  story: ResolvedStory;
38
38
  reason: string;
39
39
  } | null;
40
+ export declare const SWARM_LAUNCH_MANIFEST_RELPATH: readonly [".deft", "swarm-launch-manifest.json"];
41
+ export declare const SWARM_LAUNCH_OCCUPANCY_DIR: readonly [".deft", "swarm-launch-occupancy"];
42
+ export declare function swarmLaunchManifestPath(projectRoot: string): string;
43
+ export interface LaunchOccupancyRecord {
44
+ readonly allocation_plan_id: string | null;
45
+ readonly occupancy_session_id: string;
46
+ readonly story_ids: readonly string[];
47
+ readonly cohort_key: string;
48
+ }
49
+ export interface LaunchOccupancyQuery {
50
+ readonly allocationPlanId?: string | null;
51
+ readonly storyIds?: readonly string[];
52
+ }
53
+ export type LaunchOccupancyLookupReason = "ok" | "missing" | "wrong-cohort";
54
+ export declare function occupancyCohortKey(allocationPlanId: string | null | undefined, storyIds?: readonly string[]): string;
55
+ export declare function launchOccupancyRecordRelpath(cohortKey: string): string[];
56
+ export declare function persistLaunchOccupancyRecord(projectRoot: string, record: LaunchOccupancyRecord): void;
57
+ export declare function resolveLaunchOccupancySessionId(projectRoot: string, query?: LaunchOccupancyQuery): {
58
+ sessionId: string;
59
+ reason: LaunchOccupancyLookupReason;
60
+ };
40
61
  export declare function buildManifest(resolved: readonly ResolvedStory[], options: {
41
62
  projectRoot: string;
42
63
  group?: string | null;
@@ -53,6 +74,7 @@ export declare function buildManifest(resolved: readonly ResolvedStory[], option
53
74
  modelSource?: string | null;
54
75
  runtimeMode?: string | null;
55
76
  githubAuthMode?: string | null;
77
+ occupancySessionId?: string | null;
56
78
  }): Record<string, unknown>[];
57
79
  export declare function orderCohort(resolved: readonly ResolvedStory[], _projectRoot: string): ResolvedStory[];
58
80
  export interface LaunchArgs {