mandrel 1.94.0 → 2.1.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 (560) hide show
  1. package/.agents/README.md +116 -99
  2. package/.agents/agents/acceptance-critic.md +9 -7
  3. package/.agents/agents/story-worker.md +45 -51
  4. package/.agents/audit-checklists/performance.md +1 -1
  5. package/.agents/docs/SDLC.md +498 -1287
  6. package/.agents/docs/agentrc-reference.json +185 -80
  7. package/.agents/docs/configuration.md +132 -190
  8. package/.agents/docs/execution-reference.md +51 -25
  9. package/.agents/docs/quality-gates.md +25 -33
  10. package/.agents/docs/workflows.md +8 -8
  11. package/.agents/instructions.md +113 -139
  12. package/.agents/rules/ci-remediation.md +11 -15
  13. package/.agents/rules/git-conventions-reference.md +48 -58
  14. package/.agents/rules/git-conventions.md +16 -22
  15. package/.agents/schemas/acceptance-eval-verdict.schema.json +1 -1
  16. package/.agents/schemas/agentrc.schema.json +83 -254
  17. package/.agents/schemas/audit-rules.json +59 -1
  18. package/.agents/schemas/audit-rules.schema.json +33 -1
  19. package/.agents/schemas/lifecycle/README.md +1 -2
  20. package/.agents/schemas/lifecycle/ledger-record.schema.json +1 -1
  21. package/.agents/schemas/lifecycle/merge.flip-failed.schema.json +33 -0
  22. package/.agents/schemas/lifecycle/merge.unlanded.schema.json +1 -0
  23. package/.agents/schemas/lifecycle/retro.end.schema.json +1 -1
  24. package/.agents/schemas/lifecycle/story.merged.schema.json +1 -1
  25. package/.agents/schemas/signal-event.schema.json +3 -3
  26. package/.agents/schemas/story-deliver-terminal.schema.json +152 -0
  27. package/.agents/schemas/validation-evidence.schema.json +1 -1
  28. package/.agents/scripts/acceptance-eval.js +22 -66
  29. package/.agents/scripts/agents-bootstrap-github.js +1 -1
  30. package/.agents/scripts/audit-to-stories.js +7 -7
  31. package/.agents/scripts/boot-sweep.js +1 -1
  32. package/.agents/scripts/bootstrap.js +3 -3
  33. package/.agents/scripts/check-dead-exports.js +43 -104
  34. package/.agents/scripts/check-doc-links.js +2 -2
  35. package/.agents/scripts/check-lifecycle-lint.js +7 -10
  36. package/.agents/scripts/check-workflow-cli-lint.js +91 -0
  37. package/.agents/scripts/cleanup-repo-test-temp.js +6 -1
  38. package/.agents/scripts/deliver-recover.js +122 -0
  39. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  40. package/.agents/scripts/evidence-gate.js +20 -50
  41. package/.agents/scripts/generate-skills-index.js +17 -1
  42. package/.agents/scripts/generate-workflows-doc.js +4 -4
  43. package/.agents/scripts/lib/ITicketingProvider.js +1 -19
  44. package/.agents/scripts/lib/Logger.js +6 -10
  45. package/.agents/scripts/lib/audit-suite/runner.js +2 -2
  46. package/.agents/scripts/lib/audit-suite/selector.js +328 -28
  47. package/.agents/scripts/lib/audit-to-stories/{seed-epic-from-findings.js → seed-from-findings.js} +9 -9
  48. package/.agents/scripts/lib/baselines/kernel.js +206 -18
  49. package/.agents/scripts/lib/baselines/kinds/maintainability.js +0 -15
  50. package/.agents/scripts/lib/baselines/reader.js +1 -6
  51. package/.agents/scripts/lib/bdd-runner-detect.js +5 -9
  52. package/.agents/scripts/lib/bootstrap/ci-workflow-template.js +28 -33
  53. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +32 -33
  54. package/.agents/scripts/lib/bootstrap/manifest.js +8 -11
  55. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +30 -53
  56. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +0 -2
  57. package/.agents/scripts/lib/checks/core-bare-clean.js +6 -3
  58. package/.agents/scripts/lib/checks/index.js +3 -2
  59. package/.agents/scripts/lib/checks/loop-health.js +12 -11
  60. package/.agents/scripts/lib/checks/state.js +17 -248
  61. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +26 -24
  62. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +3 -4
  63. package/.agents/scripts/lib/checks/worktree-bootstrap-env.js +2 -2
  64. package/.agents/scripts/lib/checks/worktree-residue-biome.js +3 -3
  65. package/.agents/scripts/lib/cli/standard-args.js +13 -22
  66. package/.agents/scripts/lib/cli-args.js +39 -9
  67. package/.agents/scripts/lib/close-validation/gates.js +15 -15
  68. package/.agents/scripts/lib/close-validation/projections/inputs.js +7 -7
  69. package/.agents/scripts/lib/close-validation/projections/maintainability.js +12 -12
  70. package/.agents/scripts/lib/close-validation/runner.js +13 -21
  71. package/.agents/scripts/lib/close-validation/telemetry.js +17 -8
  72. package/.agents/scripts/lib/config/ci.js +6 -31
  73. package/.agents/scripts/lib/config/delivery-routing.js +52 -35
  74. package/.agents/scripts/lib/config/explain.js +61 -48
  75. package/.agents/scripts/lib/config/github.js +7 -5
  76. package/.agents/scripts/lib/config/limits.js +29 -80
  77. package/.agents/scripts/lib/config/paths.js +0 -2
  78. package/.agents/scripts/lib/config/quality.js +12 -15
  79. package/.agents/scripts/lib/config/runners.js +20 -66
  80. package/.agents/scripts/lib/config/temp-paths.js +30 -63
  81. package/.agents/scripts/lib/config/worktree-isolation.js +0 -5
  82. package/.agents/scripts/lib/config-resolver.js +2 -7
  83. package/.agents/scripts/lib/config-settings-schema-delivery.js +55 -161
  84. package/.agents/scripts/lib/config-settings-schema-quality.js +17 -16
  85. package/.agents/scripts/lib/config-settings-schema.js +100 -60
  86. package/.agents/scripts/lib/dead-exports-knip.js +105 -0
  87. package/.agents/scripts/lib/dead-exports-mode.js +51 -0
  88. package/.agents/scripts/lib/dependency-parser.js +3 -2
  89. package/.agents/scripts/lib/doc-tiers.js +2 -2
  90. package/.agents/scripts/lib/duplicate-search.js +242 -41
  91. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +1 -1
  92. package/.agents/scripts/lib/findings/promote-finding.js +23 -14
  93. package/.agents/scripts/lib/format-generated-json.js +97 -0
  94. package/.agents/scripts/lib/framework-version.js +19 -190
  95. package/.agents/scripts/lib/gh-exec.js +8 -0
  96. package/.agents/scripts/lib/git-branch-cleanup.js +1 -10
  97. package/.agents/scripts/lib/git-branch-lifecycle.js +17 -180
  98. package/.agents/scripts/lib/git-utils.js +32 -20
  99. package/.agents/scripts/lib/github/framework-repo.js +6 -0
  100. package/.agents/scripts/lib/json-utils.js +1 -2
  101. package/.agents/scripts/lib/label-constants.js +10 -38
  102. package/.agents/scripts/lib/label-taxonomy.js +10 -55
  103. package/.agents/scripts/lib/observability/active-story-env.js +44 -165
  104. package/.agents/scripts/lib/observability/runtime-friction.js +243 -0
  105. package/.agents/scripts/lib/observability/signal-validator.js +4 -4
  106. package/.agents/scripts/lib/observability/signals-writer.js +6 -82
  107. package/.agents/scripts/lib/observability/source-classifier.js +5 -5
  108. package/.agents/scripts/lib/observability/tool-trace-hook.js +2 -12
  109. package/.agents/scripts/lib/onboard/init-tail.js +1 -3
  110. package/.agents/scripts/lib/orchestration/acceptance-clusters.js +1 -1
  111. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +2 -2
  112. package/.agents/scripts/lib/orchestration/ceremony-routing.js +105 -44
  113. package/.agents/scripts/lib/orchestration/code-review.js +78 -436
  114. package/.agents/scripts/lib/orchestration/column-sync.js +1 -1
  115. package/.agents/scripts/lib/orchestration/consolidation-precondition.js +4 -4
  116. package/.agents/scripts/lib/orchestration/context-envelope.js +2 -5
  117. package/.agents/scripts/lib/orchestration/deliver-recover.js +328 -0
  118. package/.agents/scripts/lib/orchestration/detectors-phase.js +12 -6
  119. package/.agents/scripts/lib/orchestration/docs-digest.js +8 -8
  120. package/.agents/scripts/lib/orchestration/file-assumptions.js +7 -13
  121. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +1 -1
  122. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +34 -0
  123. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +3 -2
  124. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +142 -0
  125. package/.agents/scripts/lib/orchestration/lifecycle/emit-loop-tick.js +17 -19
  126. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +86 -0
  127. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +37 -103
  128. package/.agents/scripts/lib/orchestration/lifecycle/ledger-writer.js +6 -3
  129. package/.agents/scripts/lib/orchestration/lifecycle/listeners/README.md +21 -43
  130. package/.agents/scripts/lib/orchestration/lifecycle/listeners/watcher.js +50 -85
  131. package/.agents/scripts/lib/orchestration/lifecycle/trace-logger.js +3 -14
  132. package/.agents/scripts/lib/orchestration/lint-baseline-service.js +4 -4
  133. package/.agents/scripts/lib/orchestration/merge-block-class.js +77 -21
  134. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -0
  135. package/.agents/scripts/lib/orchestration/phase-runner.js +3 -2
  136. package/.agents/scripts/lib/orchestration/plan-context.js +354 -282
  137. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +11 -22
  138. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +4 -8
  139. package/.agents/scripts/lib/orchestration/plan-metrics.js +38 -6
  140. package/.agents/scripts/lib/orchestration/plan-navigation.js +92 -0
  141. package/.agents/scripts/lib/orchestration/plan-persist/fan-out-gate.js +71 -0
  142. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +245 -0
  143. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +116 -0
  144. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +432 -858
  145. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +778 -0
  146. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +47 -115
  147. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +509 -0
  148. package/.agents/scripts/lib/orchestration/plan-reachability.js +9 -14
  149. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +1 -1
  150. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/authoring-context.js +52 -51
  151. package/.agents/scripts/lib/orchestration/planning/decomposer-context.js +27 -0
  152. package/.agents/scripts/lib/orchestration/{epic-plan-spec/phases → planning}/spec-authoring-grounding.js +1 -1
  153. package/.agents/scripts/lib/orchestration/pr-base-guard.js +18 -28
  154. package/.agents/scripts/lib/orchestration/remote-verifier.js +1 -1
  155. package/.agents/scripts/lib/orchestration/resolve-stories.js +344 -0
  156. package/.agents/scripts/lib/orchestration/resolves-token.js +1 -1
  157. package/.agents/scripts/lib/orchestration/retro-proposals.js +140 -79
  158. package/.agents/scripts/lib/orchestration/review-depth.js +126 -47
  159. package/.agents/scripts/lib/orchestration/review-providers/codex.js +2 -2
  160. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +3 -13
  161. package/.agents/scripts/lib/orchestration/review-providers/native.js +1 -154
  162. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +3 -2
  163. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +21 -56
  164. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +1 -1
  165. package/.agents/scripts/lib/orchestration/review-providers/types.js +5 -4
  166. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +1 -1
  167. package/.agents/scripts/lib/orchestration/run-epilogue.js +784 -0
  168. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +25 -1
  169. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +11 -9
  170. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +4 -4
  171. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +86 -41
  172. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +608 -152
  173. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +77 -32
  174. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +305 -0
  175. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +1 -1
  176. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +44 -0
  177. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +37 -4
  178. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +2 -2
  179. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +275 -46
  180. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +1 -1
  181. package/.agents/scripts/lib/orchestration/spec-freshness.js +14 -205
  182. package/.agents/scripts/lib/orchestration/spec-section-validator.js +4 -5
  183. package/.agents/scripts/lib/orchestration/spec-spill.js +60 -0
  184. package/.agents/scripts/lib/orchestration/split-policy-validator.js +188 -0
  185. package/.agents/scripts/lib/orchestration/story-close/emit-blocked.js +49 -0
  186. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +10 -10
  187. package/.agents/scripts/lib/orchestration/story-close/phases/code-review.js +28 -42
  188. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +360 -0
  189. package/.agents/scripts/lib/orchestration/story-follow-ups.js +298 -0
  190. package/.agents/scripts/lib/orchestration/story-init-remote.js +51 -0
  191. package/.agents/scripts/lib/orchestration/story-plan-state.js +33 -0
  192. package/.agents/scripts/lib/orchestration/structured-comment-parser.js +1 -1
  193. package/.agents/scripts/lib/orchestration/task-body-validator.js +60 -25
  194. package/.agents/scripts/lib/orchestration/ticket-lease.js +27 -74
  195. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +130 -75
  196. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +192 -377
  197. package/.agents/scripts/lib/orchestration/ticket-validator.js +123 -25
  198. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +14 -72
  199. package/.agents/scripts/lib/orchestration/ticketing/reads.js +45 -55
  200. package/.agents/scripts/lib/orchestration/ticketing/transition.js +66 -6
  201. package/.agents/scripts/lib/orchestration/ticketing.js +0 -1
  202. package/.agents/scripts/lib/plan-phase-cleanup.js +12 -14
  203. package/.agents/scripts/lib/planning-corpus.js +12 -281
  204. package/.agents/scripts/lib/preflight-runner.js +4 -4
  205. package/.agents/scripts/lib/qa/coverage-verdict.js +5 -5
  206. package/.agents/scripts/lib/qa/qa-context-hydrator.js +5 -5
  207. package/.agents/scripts/lib/signals/index.js +4 -17
  208. package/.agents/scripts/lib/signals/read.js +35 -35
  209. package/.agents/scripts/lib/signals/schema.js +8 -11
  210. package/.agents/scripts/lib/signals/span-tree.js +7 -7
  211. package/.agents/scripts/lib/signals/write.js +0 -1
  212. package/.agents/scripts/lib/single-story/story-merged-notify.js +13 -2
  213. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +1 -1
  214. package/.agents/scripts/lib/skills/parse-skill.js +16 -3
  215. package/.agents/scripts/lib/story-adjacency.js +17 -19
  216. package/.agents/scripts/lib/story-body/story-body.js +130 -75
  217. package/.agents/scripts/lib/story-plan.js +2 -4
  218. package/.agents/scripts/lib/templates/decomposer-prompts.js +51 -46
  219. package/.agents/scripts/lib/templates/spec-author-prompts.js +47 -45
  220. package/.agents/scripts/lib/test-env.js +14 -1
  221. package/.agents/scripts/lib/test-tiers.js +0 -3
  222. package/.agents/scripts/lib/{epic-body-sections.js → ticket-body-sections.js} +25 -39
  223. package/.agents/scripts/lib/validation-evidence.js +32 -60
  224. package/.agents/scripts/lib/wave-runner/ready-set.js +38 -12
  225. package/.agents/scripts/lib/workspace-provisioner.js +1 -1
  226. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +1 -1
  227. package/.agents/scripts/lib/worktree/lifecycle/reap.js +72 -25
  228. package/.agents/scripts/lib/worktree/lifecycle-manager.js +1 -2
  229. package/.agents/scripts/lint-issue-body.js +71 -40
  230. package/.agents/scripts/mandrel-update-preflight.js +1 -1
  231. package/.agents/scripts/notify.js +4 -3
  232. package/.agents/scripts/plan-context.js +102 -80
  233. package/.agents/scripts/plan-persist.js +230 -279
  234. package/.agents/scripts/plan-run-epilogue.js +142 -0
  235. package/.agents/scripts/post-structured-comment.js +0 -38
  236. package/.agents/scripts/pr-watch-with-update.js +43 -22
  237. package/.agents/scripts/providers/github/compose.js +0 -1
  238. package/.agents/scripts/providers/github/errors.js +0 -19
  239. package/.agents/scripts/providers/github/issues.js +13 -39
  240. package/.agents/scripts/providers/github/mappers.js +5 -12
  241. package/.agents/scripts/providers/github/sub-issues.js +0 -47
  242. package/.agents/scripts/providers/github/tickets.js +33 -156
  243. package/.agents/scripts/providers/github.js +17 -6
  244. package/.agents/scripts/resolve-stories.js +236 -0
  245. package/.agents/scripts/run-coverage.js +4 -1
  246. package/.agents/scripts/run-lint.js +2 -2
  247. package/.agents/scripts/run-verify.js +31 -2
  248. package/.agents/scripts/signals-view.js +25 -21
  249. package/.agents/scripts/single-story-close.js +178 -26
  250. package/.agents/scripts/single-story-confirm-merge.js +313 -24
  251. package/.agents/scripts/single-story-init.js +35 -30
  252. package/.agents/scripts/stories-wave-tick.js +85 -10
  253. package/.agents/scripts/story-plan.js +28 -49
  254. package/.agents/scripts/update-ticket-state.js +14 -65
  255. package/.agents/skills/core/code-review-and-quality/SKILL.md +28 -450
  256. package/.agents/skills/core/code-review-and-quality/reference.md +458 -0
  257. package/.agents/skills/core/debugging-and-error-recovery/SKILL.md +22 -315
  258. package/.agents/skills/core/debugging-and-error-recovery/reference.md +323 -0
  259. package/.agents/skills/core/diagnose-friction/SKILL.md +14 -18
  260. package/.agents/skills/core/documentation-and-adrs/SKILL.md +25 -397
  261. package/.agents/skills/core/documentation-and-adrs/reference.md +403 -0
  262. package/.agents/skills/core/gates-and-baselines/SKILL.md +12 -12
  263. package/.agents/skills/core/idea-refinement/SKILL.md +9 -9
  264. package/.agents/skills/core/scope-triage/SKILL.md +31 -172
  265. package/.agents/skills/core/security-and-hardening/SKILL.md +22 -367
  266. package/.agents/skills/core/security-and-hardening/reference.md +375 -0
  267. package/.agents/skills/skills.index.json +3 -53
  268. package/.agents/skills/stack/qa/playwright-bdd/SKILL.md +2 -4
  269. package/.agents/skills/stack/qa/qa-explore-driving/SKILL.md +1 -1
  270. package/.agents/skills/stack/qa/qa-harness/SKILL.md +1 -3
  271. package/.agents/starter-agentrc.json +0 -5
  272. package/.agents/templates/agent-protocol.md +9 -10
  273. package/.agents/workflows/audit-architecture.md +6 -7
  274. package/.agents/workflows/audit-clean-code.md +7 -7
  275. package/.agents/workflows/audit-dependencies.md +3 -3
  276. package/.agents/workflows/audit-devops.md +3 -3
  277. package/.agents/workflows/audit-documentation.md +9 -10
  278. package/.agents/workflows/audit-lighthouse.md +11 -3
  279. package/.agents/workflows/audit-navigability.md +13 -2
  280. package/.agents/workflows/audit-performance.md +5 -6
  281. package/.agents/workflows/audit-privacy.md +3 -3
  282. package/.agents/workflows/audit-quality.md +11 -12
  283. package/.agents/workflows/audit-security.md +4 -5
  284. package/.agents/workflows/audit-seo.md +13 -3
  285. package/.agents/workflows/audit-sre.md +3 -3
  286. package/.agents/workflows/audit-to-stories.md +20 -20
  287. package/.agents/workflows/audit-ux-ui.md +10 -3
  288. package/.agents/workflows/deliver.md +177 -176
  289. package/.agents/workflows/git-cleanup.md +5 -6
  290. package/.agents/workflows/git-deliver.md +1 -1
  291. package/.agents/workflows/helpers/_merge-conflict-template.md +1 -1
  292. package/.agents/workflows/helpers/acceptance-self-eval.md +35 -40
  293. package/.agents/workflows/helpers/code-quality-guardrails.md +7 -7
  294. package/.agents/workflows/helpers/code-review.md +75 -196
  295. package/.agents/workflows/helpers/{single-story-deliver-reference.md → deliver-story-reference.md} +83 -44
  296. package/.agents/workflows/helpers/deliver-story.md +606 -0
  297. package/.agents/workflows/helpers/diagnose.md +10 -10
  298. package/.agents/workflows/helpers/parallel-tooling.md +3 -3
  299. package/.agents/workflows/helpers/signals.md +16 -16
  300. package/.agents/workflows/helpers/worktree-lifecycle.md +66 -86
  301. package/.agents/workflows/mandrel-update.md +2 -1
  302. package/.agents/workflows/plan.md +277 -145
  303. package/.agents/workflows/qa-assist.md +27 -33
  304. package/.agents/workflows/qa-explore.md +29 -38
  305. package/.agents/workflows/qa-run.md +2 -6
  306. package/README.md +9 -8
  307. package/bin/mandrel.js +12 -1
  308. package/docs/CHANGELOG.md +70 -0
  309. package/lib/cli/registry.js +262 -19
  310. package/lib/cli/sync-agents.js +157 -0
  311. package/lib/cli/sync-commands.js +115 -6
  312. package/lib/cli/sync.js +168 -6
  313. package/lib/cli/update.js +105 -8
  314. package/lib/cli/version-helpers.js +131 -0
  315. package/lib/migrations/README.md +7 -5
  316. package/lib/migrations/index.js +12 -8
  317. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +100 -0
  318. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +101 -0
  319. package/package.json +2 -2
  320. package/.agents/agents/retro.md +0 -42
  321. package/.agents/personas/architect.md +0 -113
  322. package/.agents/personas/devops-engineer.md +0 -38
  323. package/.agents/personas/engineer.md +0 -33
  324. package/.agents/personas/project-manager.md +0 -114
  325. package/.agents/personas/qa-engineer.md +0 -95
  326. package/.agents/personas/security-engineer.md +0 -111
  327. package/.agents/personas/technical-writer.md +0 -101
  328. package/.agents/schemas/dispatch-manifest.json +0 -232
  329. package/.agents/schemas/epic-perf-report.schema.json +0 -89
  330. package/.agents/schemas/epic-spec.schema.json +0 -153
  331. package/.agents/schemas/lifecycle/acceptance.reconcile.failed.schema.json +0 -13
  332. package/.agents/schemas/lifecycle/acceptance.reconcile.ok.schema.json +0 -13
  333. package/.agents/schemas/lifecycle/acceptance.reconcile.skipped.schema.json +0 -13
  334. package/.agents/schemas/lifecycle/acceptance.reconcile.start.schema.json +0 -12
  335. package/.agents/schemas/lifecycle/acceptance.reconcile.waived.schema.json +0 -13
  336. package/.agents/schemas/lifecycle/epic.automerge.end.schema.json +0 -15
  337. package/.agents/schemas/lifecycle/epic.automerge.start.schema.json +0 -13
  338. package/.agents/schemas/lifecycle/epic.blocked.schema.json +0 -13
  339. package/.agents/schemas/lifecycle/epic.cleanup.end.schema.json +0 -12
  340. package/.agents/schemas/lifecycle/epic.cleanup.start.schema.json +0 -12
  341. package/.agents/schemas/lifecycle/epic.close.end.schema.json +0 -12
  342. package/.agents/schemas/lifecycle/epic.complete.schema.json +0 -13
  343. package/.agents/schemas/lifecycle/epic.finalize.end.schema.json +0 -13
  344. package/.agents/schemas/lifecycle/epic.finalize.start.schema.json +0 -12
  345. package/.agents/schemas/lifecycle/epic.merge.armed.schema.json +0 -13
  346. package/.agents/schemas/lifecycle/epic.merge.blocked.schema.json +0 -14
  347. package/.agents/schemas/lifecycle/epic.merge.confirmed.schema.json +0 -17
  348. package/.agents/schemas/lifecycle/epic.merge.ready.schema.json +0 -15
  349. package/.agents/schemas/lifecycle/epic.plan.end.schema.json +0 -18
  350. package/.agents/schemas/lifecycle/epic.plan.start.schema.json +0 -12
  351. package/.agents/schemas/lifecycle/epic.snapshot.end.schema.json +0 -16
  352. package/.agents/schemas/lifecycle/epic.snapshot.start.schema.json +0 -12
  353. package/.agents/schemas/lifecycle/epic.watch.end.schema.json +0 -29
  354. package/.agents/schemas/lifecycle/epic.watch.start.schema.json +0 -16
  355. package/.agents/schemas/lifecycle/slice.end.schema.json +0 -21
  356. package/.agents/schemas/lifecycle/slice.heartbeat.schema.json +0 -20
  357. package/.agents/schemas/lifecycle/slice.start.schema.json +0 -17
  358. package/.agents/schemas/lifecycle/story.heartbeat.schema.json +0 -20
  359. package/.agents/schemas/risk-verdict.schema.json +0 -66
  360. package/.agents/schemas/story-perf-summary.schema.json +0 -73
  361. package/.agents/scripts/acceptance-spec-reconciler.js +0 -642
  362. package/.agents/scripts/analyze-execution.js +0 -444
  363. package/.agents/scripts/bookkeeping-reconcile.js +0 -117
  364. package/.agents/scripts/check-prepush-recovery.js +0 -90
  365. package/.agents/scripts/dispatcher.js +0 -295
  366. package/.agents/scripts/epic-audit-prepare.js +0 -497
  367. package/.agents/scripts/epic-audit-recheck.js +0 -274
  368. package/.agents/scripts/epic-deliver-note-intervention.js +0 -192
  369. package/.agents/scripts/epic-deliver-preflight.js +0 -462
  370. package/.agents/scripts/epic-deliver-prepare.js +0 -852
  371. package/.agents/scripts/epic-execute-record-wave.js +0 -449
  372. package/.agents/scripts/epic-plan-clarity.js +0 -211
  373. package/.agents/scripts/epic-plan-healthcheck.js +0 -581
  374. package/.agents/scripts/epic-reconcile.js +0 -625
  375. package/.agents/scripts/lib/baseline-snapshot.js +0 -979
  376. package/.agents/scripts/lib/checks/epic-merge-lock-stale.js +0 -54
  377. package/.agents/scripts/lib/checks/stale-origin-epic.js +0 -49
  378. package/.agents/scripts/lib/config/lifecycle.js +0 -40
  379. package/.agents/scripts/lib/config/preflight.js +0 -58
  380. package/.agents/scripts/lib/config/retro.js +0 -77
  381. package/.agents/scripts/lib/epic-merge-lock.js +0 -322
  382. package/.agents/scripts/lib/epic-plan-clarity.js +0 -181
  383. package/.agents/scripts/lib/epic-plan-ideation.js +0 -261
  384. package/.agents/scripts/lib/git-merge-orchestrator.js +0 -261
  385. package/.agents/scripts/lib/observability/baseline-refresh-rate.js +0 -221
  386. package/.agents/scripts/lib/observability/hook-heartbeat.js +0 -219
  387. package/.agents/scripts/lib/observability/perf-aggregator.js +0 -813
  388. package/.agents/scripts/lib/observability/perf-report-readers.js +0 -328
  389. package/.agents/scripts/lib/observability/perf-report-render.js +0 -182
  390. package/.agents/scripts/lib/orchestration/bookkeeping-outbox.js +0 -270
  391. package/.agents/scripts/lib/orchestration/context-hydration-engine.js +0 -539
  392. package/.agents/scripts/lib/orchestration/deliver-route.js +0 -173
  393. package/.agents/scripts/lib/orchestration/dispatch-engine.js +0 -134
  394. package/.agents/scripts/lib/orchestration/dispatch-pipeline.js +0 -183
  395. package/.agents/scripts/lib/orchestration/epic-cleanup.js +0 -801
  396. package/.agents/scripts/lib/orchestration/epic-deliver-lease-guard.js +0 -310
  397. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/context.js +0 -163
  398. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/creation.js +0 -140
  399. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/dag.js +0 -64
  400. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/diagnostics.js +0 -72
  401. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist-helpers.js +0 -156
  402. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/persist.js +0 -345
  403. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/planning-artifacts.js +0 -41
  404. package/.agents/scripts/lib/orchestration/epic-plan-decompose/phases/reconcile-spawn.js +0 -86
  405. package/.agents/scripts/lib/orchestration/epic-plan-lease-guard.js +0 -391
  406. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/drain.js +0 -94
  407. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/plan-epic.js +0 -236
  408. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/risk-verdict.js +0 -105
  409. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/run-spec-phase.js +0 -307
  410. package/.agents/scripts/lib/orchestration/epic-plan-spec/phases/spec-freshness.js +0 -117
  411. package/.agents/scripts/lib/orchestration/epic-plan-state-store.js +0 -117
  412. package/.agents/scripts/lib/orchestration/epic-run-state-store.js +0 -621
  413. package/.agents/scripts/lib/orchestration/epic-runner/concurrency-gate.js +0 -186
  414. package/.agents/scripts/lib/orchestration/epic-runner/deliver-phases.js +0 -50
  415. package/.agents/scripts/lib/orchestration/epic-runner/phases/build-wave-dag.js +0 -129
  416. package/.agents/scripts/lib/orchestration/epic-runner/phases/snapshot.js +0 -103
  417. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/composition.js +0 -267
  418. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/signals.js +0 -210
  419. package/.agents/scripts/lib/orchestration/epic-runner/progress-reporter/transport.js +0 -238
  420. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/_bullet-format.js +0 -32
  421. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/component-drift.js +0 -203
  422. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/crap-drift.js +0 -227
  423. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/maintainability-drift.js +0 -117
  424. package/.agents/scripts/lib/orchestration/epic-runner/progress-signals/stalled-worktree.js +0 -37
  425. package/.agents/scripts/lib/orchestration/epic-runner/story-launcher.js +0 -127
  426. package/.agents/scripts/lib/orchestration/epic-runner/story-run-progress-writer.js +0 -400
  427. package/.agents/scripts/lib/orchestration/epic-runner/sub-agent-return.js +0 -276
  428. package/.agents/scripts/lib/orchestration/epic-runner/wave-scheduler.js +0 -66
  429. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-apply.js +0 -789
  430. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-diff.js +0 -676
  431. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-discriminator.js +0 -389
  432. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-format.js +0 -230
  433. package/.agents/scripts/lib/orchestration/epic-spec-reconciler-ops.js +0 -361
  434. package/.agents/scripts/lib/orchestration/error-journal.js +0 -139
  435. package/.agents/scripts/lib/orchestration/finalize/open-or-locate-pr.js +0 -306
  436. package/.agents/scripts/lib/orchestration/finalize/post-handoff-comment.js +0 -489
  437. package/.agents/scripts/lib/orchestration/finalize/sanitize-skip-ci.js +0 -88
  438. package/.agents/scripts/lib/orchestration/lifecycle/emit-slice-lifecycle.js +0 -270
  439. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-dispatch-end.js +0 -147
  440. package/.agents/scripts/lib/orchestration/lifecycle/emit-story-heartbeat.js +0 -155
  441. package/.agents/scripts/lib/orchestration/lifecycle/ledger-diff.js +0 -140
  442. package/.agents/scripts/lib/orchestration/lifecycle/listeners/acceptance-reconciler.js +0 -465
  443. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-armer.js +0 -501
  444. package/.agents/scripts/lib/orchestration/lifecycle/listeners/automerge-predicate.js +0 -984
  445. package/.agents/scripts/lib/orchestration/lifecycle/listeners/branch-cleaner.js +0 -264
  446. package/.agents/scripts/lib/orchestration/lifecycle/listeners/checkpoint-pointer-writer.js +0 -284
  447. package/.agents/scripts/lib/orchestration/lifecycle/listeners/cleaner.js +0 -355
  448. package/.agents/scripts/lib/orchestration/lifecycle/listeners/finalizer.js +0 -673
  449. package/.agents/scripts/lib/orchestration/lifecycle/listeners/index.js +0 -378
  450. package/.agents/scripts/lib/orchestration/lifecycle/listeners/intervention-recorder.js +0 -140
  451. package/.agents/scripts/lib/orchestration/lifecycle/listeners/label-transitioner.js +0 -144
  452. package/.agents/scripts/lib/orchestration/lifecycle/listeners/merge-watcher.js +0 -665
  453. package/.agents/scripts/lib/orchestration/lifecycle/listeners/notify-dispatcher.js +0 -174
  454. package/.agents/scripts/lib/orchestration/manifest-builder.js +0 -222
  455. package/.agents/scripts/lib/orchestration/plan-persist/amend.js +0 -359
  456. package/.agents/scripts/lib/orchestration/plan-persist/delivery-mode.js +0 -127
  457. package/.agents/scripts/lib/orchestration/plan-review-routing.js +0 -63
  458. package/.agents/scripts/lib/orchestration/planning-context-budget.js +0 -213
  459. package/.agents/scripts/lib/orchestration/planning-risk.js +0 -194
  460. package/.agents/scripts/lib/orchestration/post-merge/phases/branch-cleanup.js +0 -56
  461. package/.agents/scripts/lib/orchestration/post-merge/phases/dashboard-refresh.js +0 -33
  462. package/.agents/scripts/lib/orchestration/post-merge/phases/notification.js +0 -78
  463. package/.agents/scripts/lib/orchestration/post-merge/phases/temp-cleanup.js +0 -68
  464. package/.agents/scripts/lib/orchestration/post-merge/phases/ticket-closure.js +0 -118
  465. package/.agents/scripts/lib/orchestration/post-merge/phases/worktree-reap.js +0 -396
  466. package/.agents/scripts/lib/orchestration/post-merge-pipeline.js +0 -205
  467. package/.agents/scripts/lib/orchestration/preflight-cache.js +0 -187
  468. package/.agents/scripts/lib/orchestration/recurring-failure-detector.js +0 -152
  469. package/.agents/scripts/lib/orchestration/retro/phases/checks.js +0 -94
  470. package/.agents/scripts/lib/orchestration/retro/phases/compose-body.js +0 -571
  471. package/.agents/scripts/lib/orchestration/retro/phases/gather-signals.js +0 -450
  472. package/.agents/scripts/lib/orchestration/retro/phases/post-and-mirror.js +0 -191
  473. package/.agents/scripts/lib/orchestration/retro-heuristics.js +0 -57
  474. package/.agents/scripts/lib/orchestration/retro-perf-heuristics.js +0 -275
  475. package/.agents/scripts/lib/orchestration/retro-runner.js +0 -197
  476. package/.agents/scripts/lib/orchestration/spec-renderer.js +0 -447
  477. package/.agents/scripts/lib/orchestration/story-close/auto-refresh-runner.js +0 -747
  478. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/gate-failure.js +0 -211
  479. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/pre-merge-attribution.js +0 -158
  480. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/refresh-commit.js +0 -446
  481. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/regression-projection.js +0 -297
  482. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution/phases/scope-discovery.js +0 -48
  483. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution-wiring.js +0 -67
  484. package/.agents/scripts/lib/orchestration/story-close/baseline-attribution.js +0 -161
  485. package/.agents/scripts/lib/orchestration/story-close/baseline-friction-body.js +0 -117
  486. package/.agents/scripts/lib/orchestration/story-close/cd-out-guard.js +0 -86
  487. package/.agents/scripts/lib/orchestration/story-close/cleanup-reconciler.js +0 -147
  488. package/.agents/scripts/lib/orchestration/story-close/close-inputs.js +0 -142
  489. package/.agents/scripts/lib/orchestration/story-close/comment-bodies.js +0 -62
  490. package/.agents/scripts/lib/orchestration/story-close/merge-runner.js +0 -658
  491. package/.agents/scripts/lib/orchestration/story-close/merge-subject.js +0 -198
  492. package/.agents/scripts/lib/orchestration/story-close/phases/branch-restore.js +0 -105
  493. package/.agents/scripts/lib/orchestration/story-close/phases/close.js +0 -222
  494. package/.agents/scripts/lib/orchestration/story-close/phases/gates.js +0 -292
  495. package/.agents/scripts/lib/orchestration/story-close/phases/locked-pipeline.js +0 -270
  496. package/.agents/scripts/lib/orchestration/story-close/phases/preflight.js +0 -110
  497. package/.agents/scripts/lib/orchestration/story-close/phases/refresh.js +0 -86
  498. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked-emitter.js +0 -112
  499. package/.agents/scripts/lib/orchestration/story-close/phases/timeout-blocked.js +0 -157
  500. package/.agents/scripts/lib/orchestration/story-close/post-merge-close.js +0 -421
  501. package/.agents/scripts/lib/orchestration/story-close/pre-merge-validation.js +0 -302
  502. package/.agents/scripts/lib/orchestration/story-close/shared-checkout-guard.js +0 -163
  503. package/.agents/scripts/lib/orchestration/story-close-recovery.js +0 -690
  504. package/.agents/scripts/lib/orchestration/wave-marker.js +0 -28
  505. package/.agents/scripts/lib/orchestration/wave-record-io.js +0 -218
  506. package/.agents/scripts/lib/orchestration/wave-record-notifications.js +0 -145
  507. package/.agents/scripts/lib/orchestration/wave-record-projection.js +0 -212
  508. package/.agents/scripts/lib/presentation/dispatch-manifest-render.js +0 -111
  509. package/.agents/scripts/lib/presentation/manifest-builder.js +0 -239
  510. package/.agents/scripts/lib/presentation/manifest-formatter.js +0 -242
  511. package/.agents/scripts/lib/presentation/manifest-helpers.js +0 -213
  512. package/.agents/scripts/lib/presentation/manifest-persistence.js +0 -261
  513. package/.agents/scripts/lib/presentation/manifest-procedures.js +0 -55
  514. package/.agents/scripts/lib/presentation/manifest-render-waves.js +0 -306
  515. package/.agents/scripts/lib/presentation/manifest-renderer.js +0 -188
  516. package/.agents/scripts/lib/presentation/manifest-story-views.js +0 -110
  517. package/.agents/scripts/lib/push-epic-retry.js +0 -209
  518. package/.agents/scripts/lib/spec/index.js +0 -36
  519. package/.agents/scripts/lib/spec/loader.js +0 -425
  520. package/.agents/scripts/lib/spec/state.js +0 -208
  521. package/.agents/scripts/lib/story-init/blocker-validator.js +0 -68
  522. package/.agents/scripts/lib/story-init/branch-initializer.js +0 -408
  523. package/.agents/scripts/lib/story-init/context-resolver.js +0 -92
  524. package/.agents/scripts/lib/story-init/donor-precheck.js +0 -207
  525. package/.agents/scripts/lib/story-init/state-transitioner.js +0 -80
  526. package/.agents/scripts/lib/story-init/task-graph-builder.js +0 -124
  527. package/.agents/scripts/lib/story-init/transition-summary.js +0 -34
  528. package/.agents/scripts/lib/test-reserved-epic-temp-ids.js +0 -35
  529. package/.agents/scripts/lib/wave-runner/tick.js +0 -754
  530. package/.agents/scripts/lib/wave-runner/wave-runner-error.js +0 -20
  531. package/.agents/scripts/lifecycle-emit-story-dispatch.js +0 -194
  532. package/.agents/scripts/lifecycle-emit.js +0 -510
  533. package/.agents/scripts/retro-run.js +0 -218
  534. package/.agents/scripts/slice-phase.js +0 -361
  535. package/.agents/scripts/standalone-feedback-rollup.js +0 -188
  536. package/.agents/scripts/story-close.js +0 -294
  537. package/.agents/scripts/story-init.js +0 -599
  538. package/.agents/scripts/story-phase.js +0 -369
  539. package/.agents/scripts/wave-tick.js +0 -464
  540. package/.agents/skills/core/analyze-execution/SKILL.md +0 -98
  541. package/.agents/skills/core/epic-plan-consolidate/SKILL.md +0 -172
  542. package/.agents/skills/core/epic-plan-consolidate/examples.md +0 -51
  543. package/.agents/skills/core/epic-plan-decompose-author/SKILL.md +0 -441
  544. package/.agents/skills/core/epic-plan-decompose-author/examples.md +0 -47
  545. package/.agents/skills/core/epic-plan-premortem/SKILL.md +0 -146
  546. package/.agents/skills/core/epic-plan-premortem/examples.md +0 -53
  547. package/.agents/skills/core/epic-plan-spec-author/SKILL.md +0 -383
  548. package/.agents/skills/core/epic-plan-spec-author/examples.md +0 -91
  549. package/.agents/workflows/helpers/deliver-epic-reference.md +0 -547
  550. package/.agents/workflows/helpers/deliver-epic-single.md +0 -331
  551. package/.agents/workflows/helpers/deliver-epic.md +0 -998
  552. package/.agents/workflows/helpers/deliver-stories.md +0 -450
  553. package/.agents/workflows/helpers/epic-audit.md +0 -189
  554. package/.agents/workflows/helpers/epic-deliver-story.md +0 -436
  555. package/.agents/workflows/helpers/epic-testing.md +0 -125
  556. package/.agents/workflows/helpers/plan-epic-reference.md +0 -160
  557. package/.agents/workflows/helpers/plan-epic.md +0 -353
  558. package/.agents/workflows/helpers/plan-story.md +0 -251
  559. package/.agents/workflows/helpers/scope-triage-gate.md +0 -108
  560. package/.agents/workflows/helpers/single-story-deliver.md +0 -557
@@ -43,6 +43,18 @@ import { execFileSync, spawnSync } from 'node:child_process';
43
43
  let _execFileSync = execFileSync;
44
44
  let _spawnSync = spawnSync;
45
45
 
46
+ /**
47
+ * Memoized cleaned env shared by every `gitSync` / `gitSpawn` /
48
+ * `createGitInterface` invocation in this process. Built lazily on first
49
+ * use so cold imports pay nothing. Call sites pass the object through to
50
+ * `child_process` only — none mutate `GIT_*` (or any other key) between
51
+ * git calls, so reuse is safe. Tests that mutate `process.env` and need
52
+ * a fresh snapshot must call {@link __resetCleanGitEnv}.
53
+ *
54
+ * @type {NodeJS.ProcessEnv | null}
55
+ */
56
+ let _cleanGitEnv = null;
57
+
46
58
  /**
47
59
  * Build a child-process env that drops every `GIT_*` variable inherited from
48
60
  * the parent. When this module's helpers run inside a git hook (e.g. husky
@@ -53,13 +65,28 @@ let _spawnSync = spawnSync;
53
65
  * that spin up real git fixtures break reproducibly under that shape.
54
66
  *
55
67
  * Stripping every `GIT_*` is broader than strictly necessary but cheap and
56
- * impossible to drift out of sync with future git releases. Author/committer
57
- * identity is restored via per-call `env:` overrides where required.
68
+ * impossible to drift out of sync with future git releases. The result is
69
+ * memoized per process (see `_cleanGitEnv`); author/committer identity is
70
+ * restored via per-call `env:` overrides where required.
71
+ *
72
+ * @returns {NodeJS.ProcessEnv}
58
73
  */
59
74
  function cleanGitEnv() {
60
- return Object.fromEntries(
61
- Object.entries(process.env).filter(([k]) => !k.startsWith('GIT_')),
75
+ if (_cleanGitEnv) return _cleanGitEnv;
76
+ _cleanGitEnv = Object.freeze(
77
+ Object.fromEntries(
78
+ Object.entries(process.env).filter(([k]) => !k.startsWith('GIT_')),
79
+ ),
62
80
  );
81
+ return _cleanGitEnv;
82
+ }
83
+
84
+ /**
85
+ * Drop the memoized cleaned env so the next git call rebuilds from
86
+ * `process.env`. Testing-only seam — not part of the stable API.
87
+ */
88
+ export function __resetCleanGitEnv() {
89
+ _cleanGitEnv = null;
63
90
  }
64
91
 
65
92
  /**
@@ -288,20 +315,6 @@ export function gitPullWithRetry(cwd, ...args) {
288
315
  return gitWithContentionRetry(cwd, ['pull', '--rebase'], args);
289
316
  }
290
317
 
291
- /**
292
- * Resolves the canonical branch name for an Epic.
293
- * v5 Standard: epic/[EPIC_ID]
294
- * @param {string|number} epicId
295
- * @returns {string}
296
- */
297
- export function getEpicBranch(epicId) {
298
- const id = typeof epicId === 'number' ? epicId : Number.parseInt(epicId, 10);
299
- if (!Number.isFinite(id) || id <= 0) {
300
- throw new Error(`getEpicBranch: invalid epicId: ${epicId}`);
301
- }
302
- return `epic/${id}`;
303
- }
304
-
305
318
  /**
306
319
  * Sanitize a string into a URL/branch-safe slug.
307
320
  * Lowercases, replaces non-alphanumeric characters with hyphens,
@@ -321,11 +334,10 @@ export function slugify(text) {
321
334
  /**
322
335
  * Resolves the canonical branch name for a Story.
323
336
  * v5 Standard: story-[STORY_ID]
324
- * @param {string|number} _epicId - Unused; retained for back-compat call sites.
325
337
  * @param {string|number} storyId
326
338
  * @returns {string}
327
339
  */
328
- export function getStoryBranch(_epicId, storyId) {
340
+ export function getStoryBranch(storyId) {
329
341
  const id =
330
342
  typeof storyId === 'number' ? storyId : Number.parseInt(storyId, 10);
331
343
  if (!Number.isFinite(id) || id <= 0) {
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Canonical framework repository slug used by follow-up / graduator
3
+ * paths when the consumer config does not supply owner/repo.
4
+ */
5
+
6
+ export const DEFAULT_FRAMEWORK_REPO = 'dsj1984/mandrel';
@@ -2,8 +2,7 @@
2
2
  * json-utils.js — shared JSON-shape helpers.
3
3
  *
4
4
  * Hoisted out of five callers (`lib/baselines/writer.js`,
5
- * `lib/config/defaults.js`, `lib/observability/baseline-refresh-rate.js`,
6
- * `lib/observability/perf-aggregator.js`, `lib/signals/schema.js`) which
5
+ * `lib/config/defaults.js`, `lib/signals/schema.js`) which
7
6
  * shipped functionally-equivalent copies of these predicates. See Story
8
7
  * #2464.
9
8
  *
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Central source of truth for all GitHub label names used by the orchestrator.
3
3
  *
4
- * Every other module (label-taxonomy, dispatch-engine, story-close,
5
- * etc.) should import from here rather than using string literals. Renames
4
+ * Every other module (label-taxonomy, single-story-close.js,
5
+ * stories-wave-tick.js, etc.) should import from here rather than using string literals. Renames
6
6
  * land in one place.
7
7
  */
8
8
 
@@ -10,12 +10,12 @@ export const AGENT_LABELS = {
10
10
  REVIEW_SPEC: 'agent::review-spec',
11
11
  READY: 'agent::ready',
12
12
  EXECUTING: 'agent::executing',
13
- // Story #2144 — intermediate state owned by `story-close.js`. A Story
13
+ // Story #2144 — intermediate state owned by `single-story-close.js`. A Story
14
14
  // flips to `agent::closing` after preflight validation succeeds and
15
- // before the merge into `epic/<id>` is attempted. It flips to
16
- // `agent::done` only after the post-merge pipeline confirms the merge
15
+ // the Story PR is opened against `main`. It flips to
16
+ // `agent::done` only after the close pipeline confirms the PR merge
17
17
  // landed; if the close is killed mid-flight, the Story remains at
18
- // `agent::closing` so a `/story-execute --resume` can pick up at the
18
+ // `agent::closing` so `/deliver` can pick up at the
19
19
  // post-merge phase rather than re-running preflight. The label is the
20
20
  // distinguishing signal between "hung close" and "finished work".
21
21
  CLOSING: 'agent::closing',
@@ -75,7 +75,6 @@ export function isValidTransition(fromState, toState) {
75
75
  }
76
76
 
77
77
  export const TYPE_LABELS = {
78
- EPIC: 'type::epic',
79
78
  STORY: 'type::story',
80
79
  };
81
80
 
@@ -83,14 +82,6 @@ export const STATUS_LABELS = {
83
82
  BLOCKED: 'status::blocked',
84
83
  };
85
84
 
86
- /**
87
- * Persona labels are derived at bootstrap time from `.agents/personas/*.md`
88
- * (see `label-taxonomy.js`), not hard-coded here — the persona file is the
89
- * source of truth, and ticket hydration resolves the label value to the
90
- * matching filename.
91
- */
92
- export const PERSONA_LABEL_PREFIX = 'persona::';
93
-
94
85
  /**
95
86
  * Acceptance-axis labels for opt-out signalling on Epics that
96
87
  * intentionally have no acceptance-table coverage. (Story #4324 retired
@@ -122,13 +113,10 @@ export const META_LABELS = {
122
113
 
123
114
  /**
124
115
  * Planning-axis labels (Epic #2880 F7). Currently scoped to the
125
- * `planning::healthcheck-waived` operator-applied waiver, which is the
126
- * documented escape hatch for the inline post-plan readiness
127
- * healthcheck (`runPlanHealthcheck`). The persist surface
128
- * (`plan-persist.js`) refuses to flip an Epic to `agent::ready`
129
- * when the healthcheck returned `ok: false` unless this label is
130
- * present — see `.agents/docs/SDLC.md` § "`agent::ready` exit conditions"
131
- * for the full handoff contract.
116
+ * `planning::healthcheck-waived` operator-applied waiver a historical
117
+ * escape hatch for the retired post-plan readiness healthcheck. The
118
+ * label remains in the taxonomy for tickets that still carry it; the
119
+ * healthcheck CLI itself was deleted in the v2 epic-scripts sweep.
132
120
  *
133
121
  * Future planning-axis waivers (one per failing exit condition) extend
134
122
  * this enum so consumers can reference them by symbol.
@@ -147,27 +135,11 @@ export const PLANNING_LABELS = {
147
135
  */
148
136
  export const PLANNING_HEALTHCHECK_WAIVED = 'planning::healthcheck-waived';
149
137
 
150
- /**
151
- * Delivery-routing labels (Epic #4474 PR4 — design §2 mode matrix).
152
- * `delivery::single` marks an Epic whose plan was persisted in the
153
- * spec-only single-delivery mode: no Story tree exists and the Delivery
154
- * Slicing table of the Epic body's Tech Spec is the audit trail.
155
- * `plan-persist.js` applies it when the risk verdict declares
156
- * `deliveryShape: "single"`; a fan-out re-persist over the same Epic
157
- * removes it. The marker is **inert until #4475** lands the deliver-side
158
- * reader — nothing in the deliver path consumes it yet.
159
- */
160
- export const DELIVERY_LABELS = {
161
- SINGLE: 'delivery::single',
162
- };
163
-
164
138
  /** Palette for the taxonomy; consumed by label-taxonomy.js. */
165
139
  export const LABEL_COLORS = {
166
140
  TYPE: '#7057FF',
167
141
  AGENT: '#0E8A16',
168
142
  STATUS_BLOCKED: '#D93F0B',
169
- PERSONA: '#C5DEF5',
170
143
  ACCEPTANCE: '#FBCA04',
171
144
  PLANNING: '#FEF2C0',
172
- DELIVERY: '#BFD4F2',
173
145
  };
@@ -4,59 +4,29 @@
4
4
  *
5
5
  * All label names are sourced from `label-constants.js` so renames only need
6
6
  * to happen in one place. Colors come from `LABEL_COLORS` in the same module.
7
+ *
8
+ * v2 deleted the behavioral persona concept (`.agents/personas/` +
9
+ * `persona::*` labels). Role framing for spawns lives in `.agents/agents/`
10
+ * via `delivery.routing.roleScopedAgents`; QA auth identities live in
11
+ * `qa.personas` — neither is a GitHub label axis.
7
12
  */
8
13
 
9
- import fs from 'node:fs';
10
- import path from 'node:path';
11
- import { fileURLToPath } from 'node:url';
12
14
  import {
13
15
  ACCEPTANCE_LABELS,
14
16
  AGENT_LABELS,
15
- DELIVERY_LABELS,
16
17
  LABEL_COLORS,
17
- PERSONA_LABEL_PREFIX,
18
18
  PLANNING_LABELS,
19
19
  STATUS_LABELS,
20
20
  TYPE_LABELS,
21
21
  } from './label-constants.js';
22
22
 
23
- const PERSONAS_DIR = path.resolve(
24
- path.dirname(fileURLToPath(import.meta.url)),
25
- '..',
26
- '..',
27
- 'personas',
28
- );
29
-
30
- /**
31
- * Discover persona labels from `.agents/personas/*.md`. The filename
32
- * (without extension) is the label suffix — this is the same value the
33
- * context hydrator uses to resolve `persona::<name>` to its markdown file.
34
- */
35
- function buildPersonaLabels() {
36
- return fs
37
- .readdirSync(PERSONAS_DIR)
38
- .filter((f) => f.endsWith('.md'))
39
- .map((f) => f.slice(0, -3))
40
- .sort()
41
- .map((name) => ({
42
- name: `${PERSONA_LABEL_PREFIX}${name}`,
43
- color: LABEL_COLORS.PERSONA,
44
- description: `${name} persona`,
45
- }));
46
- }
47
-
48
23
  /** @type {Array<{ name: string, color: string, description: string }>} */
49
24
  export const LABEL_TAXONOMY = [
50
25
  // Type
51
- {
52
- name: TYPE_LABELS.EPIC,
53
- color: LABEL_COLORS.TYPE,
54
- description: 'Epic-level work item',
55
- },
56
26
  {
57
27
  name: TYPE_LABELS.STORY,
58
28
  color: LABEL_COLORS.TYPE,
59
- description: 'User story under an Epic',
29
+ description: 'Story work item',
60
30
  },
61
31
 
62
32
  // Agent State
@@ -80,7 +50,7 @@ export const LABEL_TAXONOMY = [
80
50
  {
81
51
  name: AGENT_LABELS.CLOSING,
82
52
  color: LABEL_COLORS.AGENT,
83
- description: 'Close preflight passed; awaiting merge into the Epic branch',
53
+ description: 'Close preflight passed; awaiting merge into the base branch',
84
54
  },
85
55
  {
86
56
  name: AGENT_LABELS.DONE,
@@ -95,9 +65,6 @@ export const LABEL_TAXONOMY = [
95
65
  description: 'Blocked by a dependency',
96
66
  },
97
67
 
98
- // Persona — dynamically derived from .agents/personas/*.md
99
- ...buildPersonaLabels(),
100
-
101
68
  // Acceptance axis — explicit opt-out signal for Epics that
102
69
  // intentionally have no acceptance-table coverage (waives the Epic
103
70
  // body's ## Acceptance Table section — Story #4324).
@@ -108,25 +75,13 @@ export const LABEL_TAXONOMY = [
108
75
  },
109
76
 
110
77
  // Planning axis — operator-applied waivers for the planning → delivery
111
- // handoff gates. Currently the sole entry is the `healthcheck-waived`
112
- // override consumed by `plan-persist.js` when the inline healthcheck
113
- // (`runPlanHealthcheck`) returned `ok: false` for a reason the
114
- // operator has triaged and accepted.
78
+ // handoff gates. `healthcheck-waived` remains for tickets that still
79
+ // carry the historical label; the healthcheck CLI was retired.
115
80
  {
116
81
  name: PLANNING_LABELS.HEALTHCHECK_WAIVED,
117
82
  color: LABEL_COLORS.PLANNING,
118
83
  description:
119
- 'Operator override allows agent::ready handoff despite a failing post-plan healthcheck',
120
- },
121
-
122
- // Delivery routing — applied by `plan-persist.js` when the risk verdict
123
- // declares `deliveryShape: "single"` (Epic #4474 PR4). Inert until #4475
124
- // lands the deliver-side reader.
125
- {
126
- name: DELIVERY_LABELS.SINGLE,
127
- color: LABEL_COLORS.DELIVERY,
128
- description:
129
- 'Single-delivery plan — no Story tree; the Delivery Slicing table is the audit trail (#4474/#4475)',
84
+ 'Historical operator override for the retired post-plan healthcheck',
130
85
  },
131
86
  ];
132
87
 
@@ -2,14 +2,14 @@
2
2
  * Active-Story env-var propagation (Epic #1030 Story #1043 / Task #1061).
3
3
  *
4
4
  * The PreToolUse / PostToolUse trace hook in
5
- * `lib/observability/tool-trace-hook.js` resolves the active Epic +
6
- * Story from `process.env.CC_EPIC_ID` and `process.env.CC_STORY_ID`.
7
- * This module is the single writer/clearer of those vars:
8
- *
9
- * - `setActiveStoryEnv({ epicId, storyId, workCwd })` is called from
10
- * `story-init.js` after the worktree is materialised. It sets the
11
- * vars on the current `process.env` (so any child commands the
12
- * orchestrator spawns inherit them) and exports them to a sibling
5
+ * `lib/observability/tool-trace-hook.js` resolves the active Story from
6
+ * `process.env.CC_STORY_ID`. This module is the single writer/clearer of
7
+ * that var:
8
+ *
9
+ * - `setActiveStoryEnv({ storyId, workCwd })` is called from
10
+ * `single-story-init.js` after the worktree is materialised. It sets the
11
+ * var on the current `process.env` (so any child commands the
12
+ * orchestrator spawns inherit it) and exports it to a sibling
13
13
  * `.env.local` inside the worktree. The harness re-spawns the
14
14
  * agent with that file's contents loaded, so the trace hook fires
15
15
  * with the right ids on the *next* tool call after init returns.
@@ -37,96 +37,76 @@ const ENV_LOCAL_BASENAME = '.env.local';
37
37
  /**
38
38
  * Names of the env vars we own. Keeping the list central makes the
39
39
  * round-trip (set on init, clear on close) trivially auditable —
40
- * grep `CC_EPIC_ID` / `CC_STORY_ID` / `CC_SLICE_ID` to find every read site.
41
- *
42
- * Epic #4476 (M5) added `CC_SLICE_ID` (the single-delivery analogue of
43
- * `CC_STORY_ID` set on the ONE long guarded session so the PostToolUse
44
- * hook can emit `slice.heartbeat` off the token stream) and `CC_OPERATOR`
45
- * (the resolved lease-owner handle, stamped onto hook-emitted heartbeats so
46
- * `latestHeartbeatForOwner` keeps resolving a live claim). The clear path
47
- * wipes all four so no stale context leaks past close.
40
+ * grep `CC_STORY_ID` / `CC_EPIC_ID` to find every read site.
41
+ *
42
+ * `CC_STORY_ID` is the one var this module writes. `CC_EPIC_ID` is retained
43
+ * on the CLEAR path only: v2 has no Epics and nothing here sets it, but
44
+ * `tool-trace-hook.js`'s `resolveActiveStory` still reads it, so wiping it at
45
+ * close keeps the trace path's "no stale context past close" contract honest
46
+ * against a value that leaked in from outside (a pre-upgrade `.env.local` the
47
+ * harness already loaded, or an operator's shell).
48
+ *
49
+ * `CC_SLICE_ID` / `CC_OPERATOR` were removed with the heartbeat substrate:
50
+ * their only writer was the never-called `setActiveSliceEnv` and their only
51
+ * reader the deleted `hook-heartbeat.js`.
48
52
  */
49
- export const ACTIVE_STORY_ENV_KEYS = [
50
- 'CC_EPIC_ID',
51
- 'CC_STORY_ID',
52
- 'CC_SLICE_ID',
53
- 'CC_OPERATOR',
54
- ];
53
+ export const ACTIVE_STORY_ENV_KEYS = ['CC_EPIC_ID', 'CC_STORY_ID'];
55
54
 
56
55
  /**
57
56
  * Render the `.env.local` body. One `KEY=value` line per var, LF
58
57
  * line endings (the harness's dotenv parser tolerates CRLF too but LF
59
58
  * keeps the file deterministic across Windows / macOS / Linux).
60
59
  *
61
- * Story #2874 when `epicId === null` (standalone Story, no parent
62
- * Epic), the `CC_EPIC_ID=` line is omitted entirely. The trace
63
- * hook's no-op contract reads "var absent from env" as the signal,
64
- * so emitting an empty `CC_EPIC_ID=` line would set the var to the
65
- * empty string and change the contract.
60
+ * Only `CC_STORY_ID` is emitted: v2 Stories are standalone, so there is no
61
+ * parent Epic to key. The trace hook's no-op contract reads "var absent from
62
+ * env" as the signal, so no `CC_EPIC_ID=` line is written at all an empty
63
+ * one would set the var to the empty string and change the contract.
66
64
  *
67
65
  * Exported for testing.
68
66
  *
69
- * @param {{ epicId: number|null, storyId: number }} input
67
+ * @param {{ storyId: number }} input
70
68
  * @returns {string}
71
69
  */
72
- export function renderActiveStoryEnvFile({ epicId, storyId }) {
73
- const lines = [
70
+ export function renderActiveStoryEnvFile({ storyId }) {
71
+ return [
74
72
  '# Auto-managed by .agents/scripts/lib/observability/active-story-env.js',
75
73
  '# Re-generated on every story-init; deleted on story-close.',
76
- ];
77
- if (epicId !== null) lines.push(`CC_EPIC_ID=${epicId}`);
78
- lines.push(`CC_STORY_ID=${storyId}`, '');
79
- return lines.join('\n');
74
+ `CC_STORY_ID=${storyId}`,
75
+ '',
76
+ ].join('\n');
80
77
  }
81
78
 
82
79
  /**
83
- * Set `CC_EPIC_ID` / `CC_STORY_ID` on the current process and (when
84
- * `workCwd` is provided) export them to `<workCwd>/.env.local`.
80
+ * Set `CC_STORY_ID` on the current process and (when `workCwd` is provided)
81
+ * export it to `<workCwd>/.env.local`.
85
82
  *
86
- * Idempotent: re-running with the same ids is a no-op on disk; with
87
- * different ids the `.env.local` is overwritten.
83
+ * Idempotent: re-running with the same id is a no-op on disk; with a
84
+ * different id the `.env.local` is overwritten.
88
85
  *
89
- * Story #2874`epicId: null` is the standalone-Story sentinel.
90
- * When passed:
91
- * - `CC_EPIC_ID` is removed from `env` (the var MUST NOT be set
92
- * to an empty string the trace hook's `resolveActiveStory`
93
- * no-op contract is keyed on the var's absence).
94
- * - The rendered `.env.local` omits the `CC_EPIC_ID=` line.
95
- * - `CC_STORY_ID` behaviour is unchanged.
96
- * All other invalid `epicId` values (`0`, negative, NaN, non-integer)
97
- * still throw — `null` is the only standalone signal.
86
+ * v2 Stories are standalone there is no parent Epic — so `CC_EPIC_ID` is
87
+ * never set, and any pre-existing value is removed: the trace hook's
88
+ * `resolveActiveStory` no-op contract is keyed on the var's absence, and a
89
+ * stale epic id would key this Story's traces to a foreign Epic directory.
98
90
  *
99
- * @param {{ epicId: number|null, storyId: number, workCwd?: string,
91
+ * @param {{ storyId: number, workCwd?: string,
100
92
  * env?: NodeJS.ProcessEnv, fs?: typeof nodeFs,
101
93
  * logger?: { warn?: (m: string) => void } }} args
102
94
  * @returns {{ envSet: boolean, fileWritten: boolean, filePath: string|null }}
103
95
  */
104
96
  export function setActiveStoryEnv({
105
- epicId,
106
97
  storyId,
107
98
  workCwd,
108
99
  env = process.env,
109
100
  fs = nodeFs,
110
101
  logger,
111
102
  } = {}) {
112
- if (epicId !== null && (!Number.isInteger(epicId) || epicId <= 0)) {
113
- throw new Error(
114
- `[active-story-env] epicId must be a positive integer or null; got ${epicId}`,
115
- );
116
- }
117
103
  if (!Number.isInteger(storyId) || storyId <= 0) {
118
104
  throw new Error(
119
105
  `[active-story-env] storyId must be a positive integer; got ${storyId}`,
120
106
  );
121
107
  }
122
108
 
123
- if (epicId === null) {
124
- // Standalone Story — ensure CC_EPIC_ID is absent so the trace
125
- // hook's no-op contract sees "no epic" rather than "epic=''".
126
- if ('CC_EPIC_ID' in env) delete env.CC_EPIC_ID;
127
- } else {
128
- env.CC_EPIC_ID = String(epicId);
129
- }
109
+ if ('CC_EPIC_ID' in env) delete env.CC_EPIC_ID;
130
110
  env.CC_STORY_ID = String(storyId);
131
111
 
132
112
  let fileWritten = false;
@@ -134,13 +114,9 @@ export function setActiveStoryEnv({
134
114
  if (typeof workCwd === 'string' && workCwd.length > 0) {
135
115
  filePath = nodePath.join(workCwd, ENV_LOCAL_BASENAME);
136
116
  try {
137
- fs.writeFileSync(
138
- filePath,
139
- renderActiveStoryEnvFile({ epicId, storyId }),
140
- {
141
- encoding: 'utf8',
142
- },
143
- );
117
+ fs.writeFileSync(filePath, renderActiveStoryEnvFile({ storyId }), {
118
+ encoding: 'utf8',
119
+ });
144
120
  fileWritten = true;
145
121
  } catch (err) {
146
122
  logger?.warn?.(
@@ -192,100 +168,3 @@ export function clearActiveStoryEnv({
192
168
  }
193
169
  return { envCleared: true, fileRemoved, filePath };
194
170
  }
195
-
196
- /**
197
- * Render the single-delivery `.env.local` body. The single-delivery executor
198
- * (`deliver-epic-single.md`) walks the Delivery Slicing table inside ONE long
199
- * session; there is no Story fan-out and thus no `CC_STORY_ID`. Instead the
200
- * "current slice" is exported as `CC_SLICE_ID` so the PostToolUse hook emits
201
- * `slice.heartbeat` — the watchdog's forward-progress signal for the single
202
- * session — as a free byproduct of tool activity.
203
- *
204
- * `CC_STORY_ID` MUST be absent (its presence would make the hook emit
205
- * `story.heartbeat` and the trace path key off a non-existent Story). The
206
- * optional `operator` handle is emitted as `CC_OPERATOR` only when supplied.
207
- *
208
- * Exported for testing.
209
- *
210
- * @param {{ epicId: number, sliceId: string, operator?: string }} input
211
- * @returns {string}
212
- */
213
- export function renderActiveSliceEnvFile({ epicId, sliceId, operator }) {
214
- const lines = [
215
- '# Auto-managed by .agents/scripts/lib/observability/active-story-env.js',
216
- '# Re-generated on every slice-start; deleted on epic-close.',
217
- `CC_EPIC_ID=${epicId}`,
218
- `CC_SLICE_ID=${sliceId}`,
219
- ];
220
- if (typeof operator === 'string' && operator.length > 0) {
221
- lines.push(`CC_OPERATOR=${operator}`);
222
- }
223
- lines.push('');
224
- return lines.join('\n');
225
- }
226
-
227
- /**
228
- * Set `CC_EPIC_ID` / `CC_SLICE_ID` (+ optional `CC_OPERATOR`) on the current
229
- * process and, when `workCwd` is provided, export them to
230
- * `<workCwd>/.env.local` for the harness to reload on the next tool call. The
231
- * single-delivery analogue of {@link setActiveStoryEnv}; called at each
232
- * `slice.start` boundary so the hook's throttled `slice.heartbeat` is keyed to
233
- * the slice currently being implemented.
234
- *
235
- * `CC_STORY_ID` is explicitly removed so a prior Story context (if any ever
236
- * leaked in) cannot make the hook emit the wrong heartbeat shape.
237
- *
238
- * @param {{ epicId: number, sliceId: string, operator?: string|null,
239
- * workCwd?: string, env?: NodeJS.ProcessEnv, fs?: typeof nodeFs,
240
- * logger?: { warn?: (m: string) => void } }} args
241
- * @returns {{ envSet: boolean, fileWritten: boolean, filePath: string|null }}
242
- */
243
- export function setActiveSliceEnv({
244
- epicId,
245
- sliceId,
246
- operator,
247
- workCwd,
248
- env = process.env,
249
- fs = nodeFs,
250
- logger,
251
- } = {}) {
252
- if (!Number.isInteger(epicId) || epicId <= 0) {
253
- throw new Error(
254
- `[active-story-env] epicId must be a positive integer; got ${epicId}`,
255
- );
256
- }
257
- if (typeof sliceId !== 'string' || sliceId.length === 0) {
258
- throw new Error(
259
- `[active-story-env] sliceId must be a non-empty string; got ${sliceId}`,
260
- );
261
- }
262
- const normOperator =
263
- typeof operator === 'string' && operator.length > 0 ? operator : undefined;
264
-
265
- if ('CC_STORY_ID' in env) delete env.CC_STORY_ID;
266
- env.CC_EPIC_ID = String(epicId);
267
- env.CC_SLICE_ID = sliceId;
268
- if (normOperator) env.CC_OPERATOR = normOperator;
269
- else if ('CC_OPERATOR' in env) delete env.CC_OPERATOR;
270
-
271
- let fileWritten = false;
272
- let filePath = null;
273
- if (typeof workCwd === 'string' && workCwd.length > 0) {
274
- filePath = nodePath.join(workCwd, ENV_LOCAL_BASENAME);
275
- try {
276
- fs.writeFileSync(
277
- filePath,
278
- renderActiveSliceEnvFile({ epicId, sliceId, operator: normOperator }),
279
- { encoding: 'utf8' },
280
- );
281
- fileWritten = true;
282
- } catch (err) {
283
- logger?.warn?.(
284
- `[active-story-env] Failed to write ${filePath}: ${
285
- err instanceof Error ? err.message : String(err)
286
- }`,
287
- );
288
- }
289
- }
290
- return { envSet: true, fileWritten, filePath };
291
- }