mandrel 2.60.0 → 2.62.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 (662) hide show
  1. package/.agents/README.md +10 -10
  2. package/.agents/agents/story-worker.md +1 -1
  3. package/.agents/docs/agentrc-reference.json +4 -82
  4. package/.agents/docs/configuration.md +20 -87
  5. package/.agents/docs/workflows.md +1 -1
  6. package/.agents/instructions.md +1 -3
  7. package/.agents/rules/gherkin-standards.md +4 -0
  8. package/.agents/schemas/agentrc.schema.json +11 -486
  9. package/.agents/schemas/story-deliver-terminal.schema.json +10 -0
  10. package/.agents/schemas/validation-evidence.schema.json +2 -1
  11. package/.agents/scripts/README.md +14 -14
  12. package/.agents/scripts/acceptance-eval.js +32 -164
  13. package/.agents/scripts/agents-bootstrap-github.js +27 -129
  14. package/.agents/scripts/apply-quality-bootstrap.js +4 -40
  15. package/.agents/scripts/audit-baselines.js +6 -27
  16. package/.agents/scripts/audit-labels-bootstrap.js +5 -29
  17. package/.agents/scripts/audit-to-stories.js +91 -361
  18. package/.agents/scripts/boot-sweep.js +19 -72
  19. package/.agents/scripts/bootstrap.js +74 -395
  20. package/.agents/scripts/ceremony-derive.js +9 -45
  21. package/.agents/scripts/check-arch-cycles.js +14 -64
  22. package/.agents/scripts/check-baselines.js +8 -48
  23. package/.agents/scripts/check-context-budget.js +46 -172
  24. package/.agents/scripts/check-cyclomatic.js +12 -44
  25. package/.agents/scripts/check-dead-exports.js +13 -64
  26. package/.agents/scripts/check-doc-links.js +38 -186
  27. package/.agents/scripts/check-gherkin-corpus.js +24 -127
  28. package/.agents/scripts/check-test-temp-hygiene.js +28 -169
  29. package/.agents/scripts/coverage-capture.js +32 -99
  30. package/.agents/scripts/deliver-light.js +14 -101
  31. package/.agents/scripts/deliver-recover.js +6 -42
  32. package/.agents/scripts/deliver-run.js +36 -133
  33. package/.agents/scripts/diagnose-friction.js +24 -116
  34. package/.agents/scripts/drain-pending-cleanup.js +1 -1
  35. package/.agents/scripts/evidence-gate.js +23 -85
  36. package/.agents/scripts/file-ci-gap.js +10 -50
  37. package/.agents/scripts/generate-config-docs.js +30 -170
  38. package/.agents/scripts/generate-lens-checklists.js +8 -52
  39. package/.agents/scripts/generate-skills-index.js +14 -112
  40. package/.agents/scripts/generate-workflows-doc.js +10 -70
  41. package/.agents/scripts/git-cleanup.js +2 -34
  42. package/.agents/scripts/lib/Graph.js +24 -81
  43. package/.agents/scripts/lib/ITicketingProvider.js +47 -143
  44. package/.agents/scripts/lib/Logger.js +14 -76
  45. package/.agents/scripts/lib/audit-baselines/engine.js +11 -31
  46. package/.agents/scripts/lib/audit-baselines/gate-surface.js +3 -17
  47. package/.agents/scripts/lib/audit-baselines/headroom.js +4 -20
  48. package/.agents/scripts/lib/audit-baselines/hotspots.js +3 -15
  49. package/.agents/scripts/lib/audit-baselines/kinds.js +23 -89
  50. package/.agents/scripts/lib/audit-baselines/outliers.js +6 -23
  51. package/.agents/scripts/lib/audit-baselines/read.js +3 -16
  52. package/.agents/scripts/lib/audit-baselines/staleness.js +7 -26
  53. package/.agents/scripts/lib/audit-baselines/surface-entry.js +7 -28
  54. package/.agents/scripts/lib/audit-baselines/trend.js +7 -20
  55. package/.agents/scripts/lib/audit-baselines/weights.js +9 -37
  56. package/.agents/scripts/lib/audit-suite/audit-rules-reader.js +3 -18
  57. package/.agents/scripts/lib/audit-suite/checklist-threading.js +26 -124
  58. package/.agents/scripts/lib/audit-suite/dispatch-checklist.js +14 -45
  59. package/.agents/scripts/lib/audit-suite/findings.js +12 -52
  60. package/.agents/scripts/lib/audit-suite/frontmatter.js +5 -29
  61. package/.agents/scripts/lib/audit-suite/index.js +1 -15
  62. package/.agents/scripts/lib/audit-suite/lens-checklist.js +10 -45
  63. package/.agents/scripts/lib/audit-suite/lens-diff-floor.js +11 -76
  64. package/.agents/scripts/lib/audit-suite/runner.js +13 -43
  65. package/.agents/scripts/lib/audit-suite/selector.js +49 -349
  66. package/.agents/scripts/lib/audit-suite/substitutions.js +12 -40
  67. package/.agents/scripts/lib/audit-suite/workflow-loader.js +3 -15
  68. package/.agents/scripts/lib/audit-to-stories/audit-label-taxonomy.js +11 -73
  69. package/.agents/scripts/lib/audit-to-stories/audit-lenses.js +8 -37
  70. package/.agents/scripts/lib/audit-to-stories/build-story-body.js +25 -143
  71. package/.agents/scripts/lib/audit-to-stories/dedupe-against-github.js +14 -80
  72. package/.agents/scripts/lib/audit-to-stories/epic-grouping-directive.js +4 -18
  73. package/.agents/scripts/lib/audit-to-stories/finding-adapter.js +7 -40
  74. package/.agents/scripts/lib/audit-to-stories/group-findings.js +9 -39
  75. package/.agents/scripts/lib/audit-to-stories/issue-corpus.js +10 -66
  76. package/.agents/scripts/lib/audit-to-stories/issue-index.js +6 -30
  77. package/.agents/scripts/lib/audit-to-stories/issues-file.js +6 -36
  78. package/.agents/scripts/lib/audit-to-stories/ledger-commit.js +17 -69
  79. package/.agents/scripts/lib/audit-to-stories/ledger-pr.js +17 -85
  80. package/.agents/scripts/lib/audit-to-stories/ledger-record.js +10 -48
  81. package/.agents/scripts/lib/audit-to-stories/parse-audit-md.js +38 -146
  82. package/.agents/scripts/lib/audit-to-stories/seed-from-findings.js +7 -42
  83. package/.agents/scripts/lib/audit-to-stories/wire-dependencies.js +10 -57
  84. package/.agents/scripts/lib/baseline-loader.js +12 -51
  85. package/.agents/scripts/lib/baseline-schema-registry.js +5 -22
  86. package/.agents/scripts/lib/baselines/component-matcher.js +3 -12
  87. package/.agents/scripts/lib/baselines/components.js +10 -61
  88. package/.agents/scripts/lib/baselines/coverage-updater-cli.js +7 -36
  89. package/.agents/scripts/lib/baselines/crap-preview-incremental.js +5 -21
  90. package/.agents/scripts/lib/baselines/crap-preview-scan.js +19 -45
  91. package/.agents/scripts/lib/baselines/crap-updater-cli.js +16 -65
  92. package/.agents/scripts/lib/baselines/diff-scope-cli.js +5 -33
  93. package/.agents/scripts/lib/baselines/duplication-scanner.js +11 -60
  94. package/.agents/scripts/lib/baselines/env-overrides.js +12 -67
  95. package/.agents/scripts/lib/baselines/envelope.js +13 -129
  96. package/.agents/scripts/lib/baselines/exit-codes.js +6 -49
  97. package/.agents/scripts/lib/baselines/git-base.js +23 -142
  98. package/.agents/scripts/lib/baselines/kernel.js +11 -111
  99. package/.agents/scripts/lib/baselines/kinds/_crap-new-method-gate.js +9 -47
  100. package/.agents/scripts/lib/baselines/kinds/_crap-read.js +8 -51
  101. package/.agents/scripts/lib/baselines/kinds/_shared-metric.js +7 -62
  102. package/.agents/scripts/lib/baselines/kinds/bundle-size.js +8 -29
  103. package/.agents/scripts/lib/baselines/kinds/coverage.js +3 -15
  104. package/.agents/scripts/lib/baselines/kinds/crap.js +94 -415
  105. package/.agents/scripts/lib/baselines/kinds/duplication.js +4 -30
  106. package/.agents/scripts/lib/baselines/kinds/kind-factory.js +7 -53
  107. package/.agents/scripts/lib/baselines/kinds/maintainability.js +15 -80
  108. package/.agents/scripts/lib/baselines/kinds/mutation.js +12 -72
  109. package/.agents/scripts/lib/baselines/maintainability-baseline-io.js +4 -11
  110. package/.agents/scripts/lib/baselines/merge-envelopes.js +30 -146
  111. package/.agents/scripts/lib/baselines/path-canon.js +19 -128
  112. package/.agents/scripts/lib/baselines/preview-gates.js +8 -37
  113. package/.agents/scripts/lib/baselines/reader.js +14 -107
  114. package/.agents/scripts/lib/baselines/refresh-service.js +35 -252
  115. package/.agents/scripts/lib/baselines/scope.js +11 -135
  116. package/.agents/scripts/lib/baselines/writer.js +16 -149
  117. package/.agents/scripts/lib/bdd-runner-detect.js +18 -113
  118. package/.agents/scripts/lib/bdd-scenario-budget.js +9 -36
  119. package/.agents/scripts/lib/bdd-scenario-scanner.js +11 -73
  120. package/.agents/scripts/lib/bdd-step-index.js +26 -100
  121. package/.agents/scripts/lib/bootstrap/baseline-merge-driver.js +23 -103
  122. package/.agents/scripts/lib/bootstrap/branch-protection.js +2 -5
  123. package/.agents/scripts/lib/bootstrap/commit-push.js +12 -50
  124. package/.agents/scripts/lib/bootstrap/gh-preflight.js +14 -101
  125. package/.agents/scripts/lib/bootstrap/hitl-confirm.js +5 -30
  126. package/.agents/scripts/lib/bootstrap/install-ledger.js +17 -73
  127. package/.agents/scripts/lib/bootstrap/issue-forms-template.js +17 -121
  128. package/.agents/scripts/lib/bootstrap/manifest.js +15 -86
  129. package/.agents/scripts/lib/bootstrap/merge-methods.js +4 -33
  130. package/.agents/scripts/lib/bootstrap/preflight.js +12 -61
  131. package/.agents/scripts/lib/bootstrap/project-bootstrap.js +34 -235
  132. package/.agents/scripts/lib/bootstrap/prompt.js +21 -129
  133. package/.agents/scripts/lib/bootstrap/quality-bootstrap.js +27 -141
  134. package/.agents/scripts/lib/bootstrap/summary.js +1 -8
  135. package/.agents/scripts/lib/bootstrap/workflow-audit.js +11 -84
  136. package/.agents/scripts/lib/branch-name-guard.js +4 -23
  137. package/.agents/scripts/lib/changed-files.js +31 -143
  138. package/.agents/scripts/lib/checks/core-bare-clean.js +4 -24
  139. package/.agents/scripts/lib/checks/index.js +18 -101
  140. package/.agents/scripts/lib/checks/loop-health.js +11 -53
  141. package/.agents/scripts/lib/checks/state.js +16 -91
  142. package/.agents/scripts/lib/checks/story-init-not-backgrounded.js +10 -61
  143. package/.agents/scripts/lib/checks/subagent-agent-tool-required.js +14 -83
  144. package/.agents/scripts/lib/child-exec.js +39 -108
  145. package/.agents/scripts/lib/cli/standard-args.js +9 -116
  146. package/.agents/scripts/lib/cli-args.js +31 -146
  147. package/.agents/scripts/lib/cli-usage.js +5 -27
  148. package/.agents/scripts/lib/cli-utils.js +2 -12
  149. package/.agents/scripts/lib/close-validation/commands.js +13 -76
  150. package/.agents/scripts/lib/close-validation/gates.js +92 -331
  151. package/.agents/scripts/lib/close-validation/process.js +121 -151
  152. package/.agents/scripts/lib/close-validation/projections/advisories.js +5 -31
  153. package/.agents/scripts/lib/close-validation/projections/crap.js +19 -67
  154. package/.agents/scripts/lib/close-validation/projections/head-sha.js +1 -17
  155. package/.agents/scripts/lib/close-validation/projections/inputs.js +4 -34
  156. package/.agents/scripts/lib/close-validation/projections/maintainability.js +11 -58
  157. package/.agents/scripts/lib/close-validation/runner.js +53 -110
  158. package/.agents/scripts/lib/command-header.js +6 -28
  159. package/.agents/scripts/lib/config/acceptance-eval.js +4 -30
  160. package/.agents/scripts/lib/config/baselines.js +3 -14
  161. package/.agents/scripts/lib/config/ci.js +8 -38
  162. package/.agents/scripts/lib/config/commands.js +1 -15
  163. package/.agents/scripts/lib/config/defaults.js +4 -33
  164. package/.agents/scripts/lib/config/delivery-routing.js +6 -35
  165. package/.agents/scripts/lib/config/explain.js +9 -80
  166. package/.agents/scripts/lib/config/gates/coverage.schema.js +0 -12
  167. package/.agents/scripts/lib/config/gates/crap-incremental-coverage.schema.js +2 -30
  168. package/.agents/scripts/lib/config/gates/crap.schema.js +1 -34
  169. package/.agents/scripts/lib/config/gates/duplication.schema.js +1 -8
  170. package/.agents/scripts/lib/config/gates/index.js +2 -17
  171. package/.agents/scripts/lib/config/gates/maintainability.schema.js +1 -20
  172. package/.agents/scripts/lib/config/gates/mutation.schema.js +1 -7
  173. package/.agents/scripts/lib/config/gates/shared.js +4 -64
  174. package/.agents/scripts/lib/config/github.js +4 -22
  175. package/.agents/scripts/lib/config/limits.js +4 -57
  176. package/.agents/scripts/lib/config/paths.js +2 -21
  177. package/.agents/scripts/lib/config/qa.js +4 -38
  178. package/.agents/scripts/lib/config/quality.js +76 -432
  179. package/.agents/scripts/lib/config/runners.js +12 -56
  180. package/.agents/scripts/lib/config/runtime.js +13 -57
  181. package/.agents/scripts/lib/config/shared.js +2 -16
  182. package/.agents/scripts/lib/config/sync-agentrc.js +9 -50
  183. package/.agents/scripts/lib/config/temp-paths.js +40 -280
  184. package/.agents/scripts/lib/config/validate-orchestration.js +5 -17
  185. package/.agents/scripts/lib/config/worktree-isolation.js +9 -28
  186. package/.agents/scripts/lib/config-resolver.js +10 -52
  187. package/.agents/scripts/lib/config-schema-shared.js +1 -4
  188. package/.agents/scripts/lib/config-settings-schema-delivery.js +12 -294
  189. package/.agents/scripts/lib/config-settings-schema-quality.js +7 -219
  190. package/.agents/scripts/lib/config-settings-schema.js +37 -274
  191. package/.agents/scripts/lib/coverage-baseline.js +20 -110
  192. package/.agents/scripts/lib/coverage-capture-fullscope.js +12 -37
  193. package/.agents/scripts/lib/coverage-capture-incremental.js +12 -43
  194. package/.agents/scripts/lib/coverage-capture-usage.js +4 -24
  195. package/.agents/scripts/lib/coverage-capture.js +99 -224
  196. package/.agents/scripts/lib/coverage-utils.js +14 -79
  197. package/.agents/scripts/lib/cpu-pool.js +17 -123
  198. package/.agents/scripts/lib/crap-baseline-join.js +16 -88
  199. package/.agents/scripts/lib/crap-coordinates.js +6 -25
  200. package/.agents/scripts/lib/crap-engine.js +40 -153
  201. package/.agents/scripts/lib/crap-method-identity.js +16 -78
  202. package/.agents/scripts/lib/crap-utils.js +31 -155
  203. package/.agents/scripts/lib/cyclomatic-ceiling.js +14 -87
  204. package/.agents/scripts/lib/cyclomatic-scope.js +10 -50
  205. package/.agents/scripts/lib/dead-exports-knip.js +18 -56
  206. package/.agents/scripts/lib/dead-exports-mode.js +5 -24
  207. package/.agents/scripts/lib/degraded-mode.js +3 -26
  208. package/.agents/scripts/lib/dependency-parser.js +8 -40
  209. package/.agents/scripts/lib/dependency-version.js +13 -35
  210. package/.agents/scripts/lib/detect-package-manager.js +6 -36
  211. package/.agents/scripts/lib/doc-tiers.js +22 -126
  212. package/.agents/scripts/lib/duplicate-search.js +8 -72
  213. package/.agents/scripts/lib/env-loader.js +5 -27
  214. package/.agents/scripts/lib/error-redactor.js +6 -31
  215. package/.agents/scripts/lib/errors/index.js +2 -22
  216. package/.agents/scripts/lib/escomplex-ast-compat.js +22 -163
  217. package/.agents/scripts/lib/escomplex-kernel.js +21 -123
  218. package/.agents/scripts/lib/feedback-loop/graduator-core.js +93 -419
  219. package/.agents/scripts/lib/feedback-loop/prior-feedback-fetcher.js +20 -98
  220. package/.agents/scripts/lib/feedback-loop/retro-proposals-graduator.js +27 -151
  221. package/.agents/scripts/lib/findings/audit-ledger.js +23 -97
  222. package/.agents/scripts/lib/findings/classify-finding.js +14 -69
  223. package/.agents/scripts/lib/findings/promote-finding.js +14 -112
  224. package/.agents/scripts/lib/findings/provenance-field.js +11 -52
  225. package/.agents/scripts/lib/findings/route-finding.js +37 -255
  226. package/.agents/scripts/lib/findings/semantic-issue-search.js +14 -59
  227. package/.agents/scripts/lib/findings/severity.js +18 -104
  228. package/.agents/scripts/lib/format-generated-json.js +12 -44
  229. package/.agents/scripts/lib/full-suite-lock.js +160 -429
  230. package/.agents/scripts/lib/full-suite-queue.js +213 -0
  231. package/.agents/scripts/lib/gates/baseline-store.js +5 -9
  232. package/.agents/scripts/lib/gates/friction.js +1 -3
  233. package/.agents/scripts/lib/generated/agentrc-validator.js +2 -2
  234. package/.agents/scripts/lib/gh-exec.js +31 -259
  235. package/.agents/scripts/lib/git/cached-fetch.js +9 -52
  236. package/.agents/scripts/lib/git/sync-from-base.js +15 -107
  237. package/.agents/scripts/lib/git-branch-cleanup.js +14 -61
  238. package/.agents/scripts/lib/git-branch-lifecycle.js +16 -87
  239. package/.agents/scripts/lib/git-utils.js +37 -161
  240. package/.agents/scripts/lib/github/framework-repo.js +8 -71
  241. package/.agents/scripts/lib/github-url.js +2 -17
  242. package/.agents/scripts/lib/import-graph.js +11 -38
  243. package/.agents/scripts/lib/install-cmd-parser.js +4 -13
  244. package/.agents/scripts/lib/json-utils.js +3 -18
  245. package/.agents/scripts/lib/label-constants.js +16 -111
  246. package/.agents/scripts/lib/label-taxonomy.js +4 -30
  247. package/.agents/scripts/lib/maintainability-engine.js +12 -80
  248. package/.agents/scripts/lib/maintainability-unscorable.js +5 -25
  249. package/.agents/scripts/lib/maintainability-utils.js +16 -92
  250. package/.agents/scripts/lib/mandrel-catalog.js +12 -70
  251. package/.agents/scripts/lib/notifications/notifier.js +13 -38
  252. package/.agents/scripts/lib/npm-scripts.js +4 -23
  253. package/.agents/scripts/lib/observability/metrics-ledger.js +16 -76
  254. package/.agents/scripts/lib/observability/runtime-friction.js +44 -286
  255. package/.agents/scripts/lib/observability/signal-validator.js +5 -37
  256. package/.agents/scripts/lib/observability/signals-writer.js +11 -121
  257. package/.agents/scripts/lib/observability/source-classifier.js +21 -203
  258. package/.agents/scripts/lib/observability/terse-result.js +14 -47
  259. package/.agents/scripts/lib/onboard/init-tail.js +13 -74
  260. package/.agents/scripts/lib/onboard/scaffold-docs.js +11 -34
  261. package/.agents/scripts/lib/orchestration/acceptance-eval-decision.js +25 -139
  262. package/.agents/scripts/lib/orchestration/auto-merge-cwd.js +11 -66
  263. package/.agents/scripts/lib/orchestration/behind-recovery.js +10 -55
  264. package/.agents/scripts/lib/orchestration/ceremony-routing.js +5 -75
  265. package/.agents/scripts/lib/orchestration/change-set.js +7 -36
  266. package/.agents/scripts/lib/orchestration/check-baselines/phases/compare.js +9 -46
  267. package/.agents/scripts/lib/orchestration/check-baselines/phases/evaluate.js +11 -44
  268. package/.agents/scripts/lib/orchestration/check-baselines/phases/floors.js +5 -24
  269. package/.agents/scripts/lib/orchestration/check-baselines/phases/friction.js +3 -12
  270. package/.agents/scripts/lib/orchestration/check-baselines/phases/parse-args.js +5 -38
  271. package/.agents/scripts/lib/orchestration/check-baselines/phases/pipeline.js +3 -8
  272. package/.agents/scripts/lib/orchestration/check-baselines/phases/refresh-ack.js +28 -136
  273. package/.agents/scripts/lib/orchestration/check-baselines/phases/report.js +3 -13
  274. package/.agents/scripts/lib/orchestration/check-state.js +92 -0
  275. package/.agents/scripts/lib/orchestration/ci-gap-intake.js +37 -144
  276. package/.agents/scripts/lib/orchestration/ci-rerun-guard.js +42 -189
  277. package/.agents/scripts/lib/orchestration/code-review.js +24 -128
  278. package/.agents/scripts/lib/orchestration/column-sync.js +23 -111
  279. package/.agents/scripts/lib/orchestration/complexity-gate.js +42 -214
  280. package/.agents/scripts/lib/orchestration/deliver-recover.js +36 -168
  281. package/.agents/scripts/lib/orchestration/dependency-analyzer.js +4 -35
  282. package/.agents/scripts/lib/orchestration/dependency-candidates.js +9 -41
  283. package/.agents/scripts/lib/orchestration/diff-magnitude.js +25 -115
  284. package/.agents/scripts/lib/orchestration/doc-reader.js +2 -6
  285. package/.agents/scripts/lib/orchestration/docs-digest.js +13 -51
  286. package/.agents/scripts/lib/orchestration/epic-candidates.js +13 -53
  287. package/.agents/scripts/lib/orchestration/epic-checklist.js +9 -33
  288. package/.agents/scripts/lib/orchestration/epic-container.js +41 -167
  289. package/.agents/scripts/lib/orchestration/epic-expansion.js +10 -40
  290. package/.agents/scripts/lib/orchestration/epic-rollup.js +55 -207
  291. package/.agents/scripts/lib/orchestration/file-assumption-enum.js +2 -22
  292. package/.agents/scripts/lib/orchestration/file-assumptions.js +45 -253
  293. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-detect.js +9 -46
  294. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches-reap.js +7 -57
  295. package/.agents/scripts/lib/orchestration/git-cleanup/phases/branches.js +21 -126
  296. package/.agents/scripts/lib/orchestration/git-cleanup/phases/cli.js +2 -6
  297. package/.agents/scripts/lib/orchestration/git-cleanup/phases/fast-forward.js +1 -4
  298. package/.agents/scripts/lib/orchestration/git-cleanup/phases/filters.js +1 -5
  299. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes-ff.js +9 -34
  300. package/.agents/scripts/lib/orchestration/git-cleanup/phases/git-probes.js +41 -190
  301. package/.agents/scripts/lib/orchestration/git-cleanup/phases/merged-tip.js +9 -45
  302. package/.agents/scripts/lib/orchestration/git-cleanup/phases/parse-args.js +1 -4
  303. package/.agents/scripts/lib/orchestration/git-cleanup/phases/phase-drivers.js +19 -85
  304. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prompts.js +3 -17
  305. package/.agents/scripts/lib/orchestration/git-cleanup/phases/prune.js +1 -5
  306. package/.agents/scripts/lib/orchestration/git-cleanup/phases/render.js +16 -100
  307. package/.agents/scripts/lib/orchestration/git-cleanup/phases/stashes.js +1 -4
  308. package/.agents/scripts/lib/orchestration/lease-guard-shared.js +16 -67
  309. package/.agents/scripts/lib/orchestration/lifecycle/emit-ledger-event.js +9 -33
  310. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-flip-failed.js +8 -29
  311. package/.agents/scripts/lib/orchestration/lifecycle/emit-merge-unlanded.js +15 -68
  312. package/.agents/scripts/lib/orchestration/light-backstop.js +11 -49
  313. package/.agents/scripts/lib/orchestration/light-escalation.js +21 -89
  314. package/.agents/scripts/lib/orchestration/light-suitability.js +26 -231
  315. package/.agents/scripts/lib/orchestration/merge-block-class.js +39 -216
  316. package/.agents/scripts/lib/orchestration/merge-poll.js +104 -377
  317. package/.agents/scripts/lib/orchestration/merge-queue.js +158 -0
  318. package/.agents/scripts/lib/orchestration/pinned-identifier-lint.js +17 -57
  319. package/.agents/scripts/lib/orchestration/plan-context.js +52 -303
  320. package/.agents/scripts/lib/orchestration/plan-critic-conditions.js +22 -79
  321. package/.agents/scripts/lib/orchestration/plan-critics-evaluate.js +5 -31
  322. package/.agents/scripts/lib/orchestration/plan-metrics.js +29 -108
  323. package/.agents/scripts/lib/orchestration/plan-navigation.js +8 -27
  324. package/.agents/scripts/lib/orchestration/plan-persist/acceptance-handle-repair.js +12 -49
  325. package/.agents/scripts/lib/orchestration/plan-persist/audit-provenance.js +18 -73
  326. package/.agents/scripts/lib/orchestration/plan-persist/changes-repair.js +14 -78
  327. package/.agents/scripts/lib/orchestration/plan-persist/cross-plan-links.js +6 -30
  328. package/.agents/scripts/lib/orchestration/plan-persist/epic-adoption.js +14 -65
  329. package/.agents/scripts/lib/orchestration/plan-persist/epic-ops.js +21 -76
  330. package/.agents/scripts/lib/orchestration/plan-persist/external-deps.js +6 -43
  331. package/.agents/scripts/lib/orchestration/plan-persist/persist-helpers.js +14 -68
  332. package/.agents/scripts/lib/orchestration/plan-persist/plan-context-source.js +9 -41
  333. package/.agents/scripts/lib/orchestration/plan-persist/run-plan-persist.js +49 -248
  334. package/.agents/scripts/lib/orchestration/plan-persist/soft-findings.js +2 -12
  335. package/.agents/scripts/lib/orchestration/plan-persist/story-ops.js +85 -368
  336. package/.agents/scripts/lib/orchestration/plan-persist/summary.js +8 -38
  337. package/.agents/scripts/lib/orchestration/plan-persist/supersede-ops.js +30 -190
  338. package/.agents/scripts/lib/orchestration/plan-persist/wave-collision-gate.js +9 -49
  339. package/.agents/scripts/lib/orchestration/plan-persist/wave-serialisation.js +7 -28
  340. package/.agents/scripts/lib/orchestration/plan-reachability.js +13 -42
  341. package/.agents/scripts/lib/orchestration/plan-run-labels/reap.js +16 -91
  342. package/.agents/scripts/lib/orchestration/plan-runner/worktree-sweep.js +16 -54
  343. package/.agents/scripts/lib/orchestration/plan-text-hygiene.js +10 -52
  344. package/.agents/scripts/lib/orchestration/planning/authoring-context.js +14 -109
  345. package/.agents/scripts/lib/orchestration/planning/memory-pool-advisory.js +11 -83
  346. package/.agents/scripts/lib/orchestration/pr-watch.js +48 -306
  347. package/.agents/scripts/lib/orchestration/project-meta-cache.js +15 -80
  348. package/.agents/scripts/lib/orchestration/project-meta-resolver.js +10 -51
  349. package/.agents/scripts/lib/orchestration/reassert-status-column.js +12 -76
  350. package/.agents/scripts/lib/orchestration/remote-verifier.js +12 -36
  351. package/.agents/scripts/lib/orchestration/resolve-stories.js +33 -164
  352. package/.agents/scripts/lib/orchestration/retro-proposals.js +66 -361
  353. package/.agents/scripts/lib/orchestration/review-base-ref.js +9 -43
  354. package/.agents/scripts/lib/orchestration/review-depth.js +12 -94
  355. package/.agents/scripts/lib/orchestration/review-providers/codex.js +10 -111
  356. package/.agents/scripts/lib/orchestration/review-providers/degraded-gates.js +13 -71
  357. package/.agents/scripts/lib/orchestration/review-providers/findings-renderer.js +7 -51
  358. package/.agents/scripts/lib/orchestration/review-providers/mi-exemptions.js +8 -53
  359. package/.agents/scripts/lib/orchestration/review-providers/native.js +30 -214
  360. package/.agents/scripts/lib/orchestration/review-providers/parse-findings.js +7 -52
  361. package/.agents/scripts/lib/orchestration/review-providers/review-depth.js +4 -33
  362. package/.agents/scripts/lib/orchestration/review-providers/review-provider-factory.js +11 -71
  363. package/.agents/scripts/lib/orchestration/review-providers/scoped-lint.js +19 -131
  364. package/.agents/scripts/lib/orchestration/review-providers/security-review.js +6 -89
  365. package/.agents/scripts/lib/orchestration/review-providers/types.js +26 -56
  366. package/.agents/scripts/lib/orchestration/review-providers/ultrareview.js +3 -46
  367. package/.agents/scripts/lib/orchestration/run-epilogue.js +40 -199
  368. package/.agents/scripts/lib/orchestration/run-scoped-config.js +13 -81
  369. package/.agents/scripts/lib/orchestration/single-story-close/close-note.js +7 -34
  370. package/.agents/scripts/lib/orchestration/single-story-close/failed-terminal.js +16 -89
  371. package/.agents/scripts/lib/orchestration/single-story-close/gate-log.js +18 -109
  372. package/.agents/scripts/lib/orchestration/single-story-close/phases/auto-merge.js +190 -280
  373. package/.agents/scripts/lib/orchestration/single-story-close/phases/base-sync.js +18 -80
  374. package/.agents/scripts/lib/orchestration/single-story-close/phases/close-validation.js +103 -97
  375. package/.agents/scripts/lib/orchestration/single-story-close/phases/code-review.js +8 -64
  376. package/.agents/scripts/lib/orchestration/single-story-close/phases/confirm-merge.js +183 -485
  377. package/.agents/scripts/lib/orchestration/single-story-close/phases/conventional-subject.js +30 -134
  378. package/.agents/scripts/lib/orchestration/single-story-close/phases/graphql-preflight.js +9 -50
  379. package/.agents/scripts/lib/orchestration/single-story-close/phases/lock-wait-pending.js +49 -0
  380. package/.agents/scripts/lib/orchestration/single-story-close/phases/normalize-pr-title.js +13 -86
  381. package/.agents/scripts/lib/orchestration/single-story-close/phases/options.js +20 -95
  382. package/.agents/scripts/lib/orchestration/single-story-close/phases/post-land.js +46 -203
  383. package/.agents/scripts/lib/orchestration/single-story-close/phases/pre-gate-steps.js +8 -50
  384. package/.agents/scripts/lib/orchestration/single-story-close/phases/pull-request.js +12 -83
  385. package/.agents/scripts/lib/orchestration/single-story-close/phases/push.js +6 -39
  386. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-block.js +1 -6
  387. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-outcome.js +4 -28
  388. package/.agents/scripts/lib/orchestration/single-story-close/phases/review-override.js +6 -51
  389. package/.agents/scripts/lib/orchestration/single-story-close/phases/worktree-reap.js +6 -34
  390. package/.agents/scripts/lib/orchestration/single-story-close/phases/wrong-tree-guard.js +23 -121
  391. package/.agents/scripts/lib/orchestration/single-story-close/runner.js +110 -290
  392. package/.agents/scripts/lib/orchestration/single-story-lease-guard.js +15 -69
  393. package/.agents/scripts/lib/orchestration/story-body-gate.js +4 -23
  394. package/.agents/scripts/lib/orchestration/story-close/baseline-upward-writeback.js +50 -179
  395. package/.agents/scripts/lib/orchestration/story-close/context-budget-writeback.js +11 -41
  396. package/.agents/scripts/lib/orchestration/story-close/format-autofix.js +23 -311
  397. package/.agents/scripts/lib/orchestration/story-close/phases/local-lens-review.js +22 -147
  398. package/.agents/scripts/lib/orchestration/story-close/phases/review-core.js +16 -67
  399. package/.agents/scripts/lib/orchestration/story-deliver-terminal-schema.js +12 -68
  400. package/.agents/scripts/lib/orchestration/story-deliver-terminal.js +42 -201
  401. package/.agents/scripts/lib/orchestration/story-follow-ups.js +43 -245
  402. package/.agents/scripts/lib/orchestration/story-init-envelope.js +4 -23
  403. package/.agents/scripts/lib/orchestration/story-init-remote.js +2 -6
  404. package/.agents/scripts/lib/orchestration/story-reachability.js +3 -23
  405. package/.agents/scripts/lib/orchestration/task-body-validator.js +12 -126
  406. package/.agents/scripts/lib/orchestration/ticket-lease.js +28 -131
  407. package/.agents/scripts/lib/orchestration/ticket-validator-conflicts.js +15 -149
  408. package/.agents/scripts/lib/orchestration/ticket-validator-sizing.js +5 -33
  409. package/.agents/scripts/lib/orchestration/ticket-validator.js +39 -181
  410. package/.agents/scripts/lib/orchestration/ticketing/bulk.js +51 -244
  411. package/.agents/scripts/lib/orchestration/ticketing/reads.js +39 -250
  412. package/.agents/scripts/lib/orchestration/ticketing/state.js +14 -68
  413. package/.agents/scripts/lib/orchestration/ticketing/transition.js +46 -263
  414. package/.agents/scripts/lib/orchestration/ticketing.js +2 -26
  415. package/.agents/scripts/lib/orchestration/verify-credit.js +18 -79
  416. package/.agents/scripts/lib/orchestration/worktree-dirty.js +5 -30
  417. package/.agents/scripts/lib/path-security.js +3 -6
  418. package/.agents/scripts/lib/plan-phase-cleanup.js +9 -49
  419. package/.agents/scripts/lib/preflight-runner.js +13 -69
  420. package/.agents/scripts/lib/process-group.js +143 -0
  421. package/.agents/scripts/lib/project-root.js +2 -8
  422. package/.agents/scripts/lib/provider-factory.js +2 -25
  423. package/.agents/scripts/lib/qa/console-allowlist.js +10 -59
  424. package/.agents/scripts/lib/qa/qa-session.js +15 -69
  425. package/.agents/scripts/lib/qa/redact-evidence.js +18 -129
  426. package/.agents/scripts/lib/qa/resolve-qa-contract.js +26 -135
  427. package/.agents/scripts/lib/qa/resolve-selection.js +16 -84
  428. package/.agents/scripts/lib/reserved-test-ids.js +9 -47
  429. package/.agents/scripts/lib/runtime-deps/dep-resolution.js +13 -53
  430. package/.agents/scripts/lib/runtime-deps/ensure-installed.js +10 -44
  431. package/.agents/scripts/lib/runtime-deps/manifest.js +10 -30
  432. package/.agents/scripts/lib/runtime-deps/parser-major.js +15 -51
  433. package/.agents/scripts/lib/runtime-deps/preflight.js +4 -22
  434. package/.agents/scripts/lib/runtime-deps/scan-imports.js +11 -55
  435. package/.agents/scripts/lib/signals/detectors/common.js +12 -38
  436. package/.agents/scripts/lib/signals/index.js +2 -19
  437. package/.agents/scripts/lib/signals/schema.js +14 -109
  438. package/.agents/scripts/lib/signals/write.js +2 -11
  439. package/.agents/scripts/lib/single-story/confirm-merge.js +31 -72
  440. package/.agents/scripts/lib/single-story/story-merged-notify.js +8 -49
  441. package/.agents/scripts/lib/single-story-sweep/protection-ctx.js +4 -26
  442. package/.agents/scripts/lib/single-story-sweep/protection.js +13 -100
  443. package/.agents/scripts/lib/single-story-sweep/sweep-lock.js +60 -258
  444. package/.agents/scripts/lib/single-story-sweep.js +14 -97
  445. package/.agents/scripts/lib/skills/parse-skill.js +13 -59
  446. package/.agents/scripts/lib/skills/skills-index.js +8 -29
  447. package/.agents/scripts/lib/skills/walk-skill-files.js +17 -78
  448. package/.agents/scripts/lib/source-extensions.js +11 -42
  449. package/.agents/scripts/lib/source-text/strip-js-comments.js +8 -41
  450. package/.agents/scripts/lib/stdio-flush.js +9 -36
  451. package/.agents/scripts/lib/story-adjacency.js +8 -40
  452. package/.agents/scripts/lib/story-body/body-format-lints.js +22 -83
  453. package/.agents/scripts/lib/story-body/footer-block.js +11 -44
  454. package/.agents/scripts/lib/story-body/story-body.js +83 -358
  455. package/.agents/scripts/lib/temp-retention.js +42 -143
  456. package/.agents/scripts/lib/templates/decomposer-prompts.js +11 -65
  457. package/.agents/scripts/lib/test-env.js +12 -65
  458. package/.agents/scripts/lib/test-run-credit.js +10 -65
  459. package/.agents/scripts/lib/test-runner-contract.js +19 -74
  460. package/.agents/scripts/lib/test-temp.js +38 -184
  461. package/.agents/scripts/lib/test-tiers.js +12 -96
  462. package/.agents/scripts/lib/ticket-body-sections.js +21 -96
  463. package/.agents/scripts/lib/transpile.js +15 -74
  464. package/.agents/scripts/lib/util/concurrent-map.js +6 -25
  465. package/.agents/scripts/lib/util/parse-id-list.js +8 -34
  466. package/.agents/scripts/lib/util/poll-loop.js +8 -28
  467. package/.agents/scripts/lib/util/with-timeout.js +2 -11
  468. package/.agents/scripts/lib/validation-evidence.js +21 -96
  469. package/.agents/scripts/lib/wave-runner/footprint.js +17 -70
  470. package/.agents/scripts/lib/wave-runner/live-probe.js +53 -221
  471. package/.agents/scripts/lib/wave-runner/ready-set.js +72 -301
  472. package/.agents/scripts/lib/workers/crap-worker.js +11 -64
  473. package/.agents/scripts/lib/workers/maintainability-report-worker.js +8 -45
  474. package/.agents/scripts/lib/workers/maintainability-worker.js +5 -21
  475. package/.agents/scripts/lib/workers/serve-worker-messages.js +2 -18
  476. package/.agents/scripts/lib/workflow-closure.js +22 -105
  477. package/.agents/scripts/lib/workspace-provisioner.js +16 -54
  478. package/.agents/scripts/lib/worktree/git-hooks.js +15 -60
  479. package/.agents/scripts/lib/worktree/lifecycle/force-drain.js +20 -60
  480. package/.agents/scripts/lib/worktree/lifecycle/merge-reachability.js +10 -62
  481. package/.agents/scripts/lib/worktree/lifecycle/pending-cleanup.js +22 -86
  482. package/.agents/scripts/lib/worktree/lifecycle/reap.js +24 -126
  483. package/.agents/scripts/lib/worktree/lifecycle-manager.js +2 -20
  484. package/.agents/scripts/lib/worktree/node-modules-strategy.js +46 -180
  485. package/.agents/scripts/lib/worktree-manager.js +15 -40
  486. package/.agents/scripts/lint-issue-body.js +12 -68
  487. package/.agents/scripts/mandrel-update-preflight.js +10 -70
  488. package/.agents/scripts/merge-baseline.js +30 -104
  489. package/.agents/scripts/nav-registry-diff.js +22 -108
  490. package/.agents/scripts/notify.js +12 -69
  491. package/.agents/scripts/plan-context.js +27 -111
  492. package/.agents/scripts/plan-critics.js +12 -66
  493. package/.agents/scripts/plan-persist.js +31 -148
  494. package/.agents/scripts/plan-run-epilogue.js +11 -37
  495. package/.agents/scripts/pr-watch-with-update.js +76 -267
  496. package/.agents/scripts/providers/github/auth.js +3 -8
  497. package/.agents/scripts/providers/github/blocked-by-add.js +14 -61
  498. package/.agents/scripts/providers/github/board-add.js +5 -21
  499. package/.agents/scripts/providers/github/branch-protection.js +11 -43
  500. package/.agents/scripts/providers/github/cache.js +2 -14
  501. package/.agents/scripts/providers/github/comments.js +7 -40
  502. package/.agents/scripts/providers/github/compose.js +3 -19
  503. package/.agents/scripts/providers/github/errors.js +22 -125
  504. package/.agents/scripts/providers/github/issues.js +31 -123
  505. package/.agents/scripts/providers/github/labels.js +24 -124
  506. package/.agents/scripts/providers/github/mappers.js +5 -27
  507. package/.agents/scripts/providers/github/merge-methods.js +3 -22
  508. package/.agents/scripts/providers/github/project-board.js +2 -17
  509. package/.agents/scripts/providers/github/projects-v2-graphql.js +3 -6
  510. package/.agents/scripts/providers/github/request-helpers.js +5 -32
  511. package/.agents/scripts/providers/github/search-budget.js +9 -39
  512. package/.agents/scripts/providers/github/search-query.js +5 -26
  513. package/.agents/scripts/providers/github/sub-issue-add.js +15 -65
  514. package/.agents/scripts/providers/github/sub-issues.js +7 -36
  515. package/.agents/scripts/providers/github/tickets.js +32 -134
  516. package/.agents/scripts/providers/github.js +18 -59
  517. package/.agents/scripts/prune-plan-run-labels.js +12 -46
  518. package/.agents/scripts/quality-preview.js +35 -220
  519. package/.agents/scripts/resolve-doc-tiers.js +3 -26
  520. package/.agents/scripts/resolve-stories.js +16 -67
  521. package/.agents/scripts/resync-status-column.js +6 -25
  522. package/.agents/scripts/run-tests.js +29 -104
  523. package/.agents/scripts/single-story-close.js +23 -135
  524. package/.agents/scripts/single-story-confirm-merge.js +32 -139
  525. package/.agents/scripts/single-story-init.js +47 -209
  526. package/.agents/scripts/stories-wave-tick.js +102 -472
  527. package/.agents/scripts/sync-agentrc.js +3 -21
  528. package/.agents/scripts/sync-claude-agents.js +9 -55
  529. package/.agents/scripts/sync-claude-commands.js +20 -110
  530. package/.agents/scripts/test-wrapper.js +6 -43
  531. package/.agents/scripts/update-coverage-baseline.js +5 -22
  532. package/.agents/scripts/update-crap-baseline.js +7 -30
  533. package/.agents/scripts/update-duplication-baseline.js +16 -92
  534. package/.agents/scripts/update-maintainability-baseline.js +8 -62
  535. package/.agents/scripts/update-ticket-state.js +1 -7
  536. package/.agents/scripts/validate-skills.js +6 -26
  537. package/.agents/templates/agent-protocol.md +2 -2
  538. package/.agents/templates/docs/audit-sweep-runbook.md +3 -4
  539. package/.agents/workflows/audit-accessibility.md +4 -7
  540. package/.agents/workflows/audit-adrs.md +3 -6
  541. package/.agents/workflows/audit-architecture.md +3 -11
  542. package/.agents/workflows/audit-baselines.md +6 -9
  543. package/.agents/workflows/audit-clean-code.md +8 -12
  544. package/.agents/workflows/audit-data-model.md +3 -7
  545. package/.agents/workflows/audit-dependencies.md +4 -7
  546. package/.agents/workflows/audit-devops.md +4 -8
  547. package/.agents/workflows/audit-documentation.md +1 -4
  548. package/.agents/workflows/audit-mobile.md +4 -7
  549. package/.agents/workflows/audit-navigability.md +3 -6
  550. package/.agents/workflows/audit-performance.md +2 -4
  551. package/.agents/workflows/audit-privacy.md +4 -7
  552. package/.agents/workflows/audit-quality.md +4 -7
  553. package/.agents/workflows/audit-security.md +4 -7
  554. package/.agents/workflows/audit-seo.md +4 -7
  555. package/.agents/workflows/audit-sre.md +4 -7
  556. package/.agents/workflows/audit-to-stories.md +17 -30
  557. package/.agents/workflows/audit-ux-ui.md +4 -7
  558. package/.agents/workflows/helpers/audit-lens-core.md +1 -1
  559. package/.agents/workflows/helpers/code-quality-guardrails.md +12 -15
  560. package/.agents/workflows/helpers/deliver-digest.md +6 -4
  561. package/.agents/workflows/helpers/deliver-reference.md +114 -188
  562. package/.agents/workflows/helpers/deliver-story-reference.md +189 -533
  563. package/.agents/workflows/helpers/plan-reference.md +86 -139
  564. package/.agents/workflows/helpers/qa-core.md +12 -0
  565. package/.agents/workflows/memory-consolidate.md +1 -1
  566. package/.agents/workflows/qa-assist.md +27 -71
  567. package/.agents/workflows/qa-explore.md +19 -59
  568. package/.agents/workflows/qa-run.md +11 -33
  569. package/README.md +1 -1
  570. package/bin/mandrel.js +5 -46
  571. package/bin/postinstall.js +18 -107
  572. package/docs/CHANGELOG.md +32 -0
  573. package/lib/cli/doctor.js +11 -71
  574. package/lib/cli/init.js +26 -165
  575. package/lib/cli/migrate.js +5 -64
  576. package/lib/cli/registry.js +84 -467
  577. package/lib/cli/sync-agents.js +4 -64
  578. package/lib/cli/sync-commands.js +11 -64
  579. package/lib/cli/sync.js +34 -213
  580. package/lib/cli/uninstall.js +40 -219
  581. package/lib/cli/update.js +105 -661
  582. package/lib/cli/version-check.js +8 -72
  583. package/lib/cli/version-helpers.js +14 -87
  584. package/lib/migrations/helpers/retire-agentrc-key.js +11 -52
  585. package/lib/migrations/index.js +15 -92
  586. package/lib/migrations/steps/2.1.0-retire-mi-drop-knobs.js +2 -15
  587. package/lib/migrations/steps/2.1.0-retire-verify-concurrency-cap.js +1 -13
  588. package/lib/migrations/steps/2.11.0-retire-max-seed-words.js +2 -15
  589. package/lib/migrations/steps/2.2.0-retire-epic-ac-tags.js +9 -38
  590. package/lib/migrations/steps/2.20.0-retire-codebase-snapshot.js +1 -13
  591. package/lib/migrations/steps/2.32.0-retire-lint-baseline-command.js +2 -27
  592. package/lib/migrations/steps/2.57.0-retire-delivery-limit-knobs.js +2 -23
  593. package/lib/migrations/steps/2.57.0-retire-planning-limit-knobs.js +2 -27
  594. package/lib/migrations/steps/2.60.0-retire-audit-results-autofile.js +2 -21
  595. package/lib/migrations/steps/strip-removed-agentrc-keys.js +333 -0
  596. package/package.json +16 -14
  597. package/.agents/docs/SDLC.md +0 -590
  598. package/.agents/docs/quality-gates.md +0 -1183
  599. package/.agents/rules/known-tooling-behavior.md +0 -200
  600. package/.agents/rules/orchestration-error-handling.md +0 -61
  601. package/.agents/rules/test-seams.md +0 -59
  602. package/.agents/schemas/baselines/lighthouse.schema.json +0 -59
  603. package/.agents/schemas/baselines/lint.schema.json +0 -47
  604. package/.agents/scripts/check-action-pinning.js +0 -260
  605. package/.agents/scripts/check-audit-attribution.js +0 -302
  606. package/.agents/scripts/check-baseline-drift.js +0 -211
  607. package/.agents/scripts/check-baseline-scope.js +0 -362
  608. package/.agents/scripts/check-generated-validator.js +0 -202
  609. package/.agents/scripts/check-knip-entries.js +0 -159
  610. package/.agents/scripts/check-lifecycle-lint.js +0 -294
  611. package/.agents/scripts/check-pinned-override-notes.js +0 -102
  612. package/.agents/scripts/check-schema-references.js +0 -368
  613. package/.agents/scripts/check-test-portability.js +0 -512
  614. package/.agents/scripts/check-workflow-citations.js +0 -218
  615. package/.agents/scripts/check-workflow-cli-lint.js +0 -299
  616. package/.agents/scripts/check-workflow-timeouts.js +0 -291
  617. package/.agents/scripts/install-matrix-assert.js +0 -326
  618. package/.agents/scripts/lib/audit-advisories.js +0 -195
  619. package/.agents/scripts/lib/audit-attribution.js +0 -134
  620. package/.agents/scripts/lib/baselines/drift-detector.js +0 -351
  621. package/.agents/scripts/lib/baselines/kinds/lighthouse.js +0 -87
  622. package/.agents/scripts/lib/baselines/kinds/lint.js +0 -184
  623. package/.agents/scripts/lib/baselines/orphan-pruner.js +0 -233
  624. package/.agents/scripts/lib/baselines/scope-assert.js +0 -223
  625. package/.agents/scripts/lib/baselines/scope-inventory.js +0 -314
  626. package/.agents/scripts/lib/c8-cli-path.js +0 -21
  627. package/.agents/scripts/lib/config/gates/lighthouse.schema.js +0 -51
  628. package/.agents/scripts/lib/config/gates/lint.schema.js +0 -18
  629. package/.agents/scripts/lib/dynamic-workflow/architecture-report-contract.js +0 -70
  630. package/.agents/scripts/lib/dynamic-workflow/audit-orchestrator.js +0 -284
  631. package/.agents/scripts/lib/dynamic-workflow/clean-code-report-contract.js +0 -80
  632. package/.agents/scripts/lib/dynamic-workflow/degraded-coverage.js +0 -81
  633. package/.agents/scripts/lib/dynamic-workflow/documentation-report-contract.js +0 -87
  634. package/.agents/scripts/lib/dynamic-workflow/performance-report-contract.js +0 -74
  635. package/.agents/scripts/lib/dynamic-workflow/quality-report-contract.js +0 -90
  636. package/.agents/scripts/lib/dynamic-workflow/report-contract-core.js +0 -43
  637. package/.agents/scripts/lib/dynamic-workflow/security-report-contract.js +0 -83
  638. package/.agents/scripts/lib/fs-walk.js +0 -52
  639. package/.agents/scripts/lib/knip-config-resolver.js +0 -181
  640. package/.agents/scripts/lib/knip-entry-sync.js +0 -452
  641. package/.agents/scripts/lib/pinned-override-notes.js +0 -88
  642. package/.agents/scripts/lib/pinned-override-resolve.js +0 -212
  643. package/.agents/scripts/lib/test-isolate/cli-options.js +0 -93
  644. package/.agents/scripts/lib/test-isolate/env-snapshot-loader.js +0 -52
  645. package/.agents/scripts/lib/test-isolate/list-files.js +0 -90
  646. package/.agents/scripts/lib/test-isolate/parse-tap.js +0 -75
  647. package/.agents/scripts/lib/test-isolate/progress-log.js +0 -45
  648. package/.agents/scripts/lib/test-isolate/render-report.js +0 -97
  649. package/.agents/scripts/lib/test-isolate/run-isolate.js +0 -87
  650. package/.agents/scripts/lib/test-isolate/runner.js +0 -483
  651. package/.agents/scripts/lib/test-profile/parse-tap.js +0 -136
  652. package/.agents/scripts/lib/test-profile/render-report.js +0 -45
  653. package/.agents/scripts/lint-label-vocabulary.js +0 -214
  654. package/.agents/scripts/post-structured-comment.js +0 -127
  655. package/.agents/scripts/provision-git-hooks.js +0 -85
  656. package/.agents/scripts/prune-baseline-orphans.js +0 -181
  657. package/.agents/scripts/run-coverage.js +0 -197
  658. package/.agents/scripts/run-lint.js +0 -133
  659. package/.agents/scripts/run-test-profile.js +0 -129
  660. package/.agents/scripts/run-verify.js +0 -125
  661. package/.agents/scripts/test-isolate.js +0 -55
  662. package/.agents/scripts/update-dead-exports-baseline.js +0 -321
@@ -1,55 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * bootstrap.js — single-command consumer setup for Mandrel.
4
- *
5
- * The sole bootstrap orchestrator (Story #3690 collapsed the temporary
6
- * bootstrap-new.js fork into this file). Key behaviours:
7
- * - No config profiles — `.agentrc.json` always seeds from the bundled
8
- * `.agents/starter-agentrc.json` starter reference.
9
- * - Runs even when the directory is NOT a git repo yet (preflight detects
10
- * git state instead of failing on it).
11
- * - Adds a Projects V2 permission check to preflight (warns rather than
12
- * failing when classic token scopes cannot be read, e.g. fine-grained
13
- * PATs).
14
- * - Uses a plain summary + confirm loop (interactive runs can go back and
15
- * re-answer) instead of a phased-approval manifest.
16
- * - Provisions the missing pieces of a cold start: initializes the local
17
- * git repo (with a first commit) when absent, creates the GitHub repo
18
- * (linking + pushing the local tree), and creates the Projects V2 board
19
- * from a typed name — capturing its number for the rest of the run.
20
- *
21
- * Usage:
22
- * node .agents/scripts/bootstrap.js [flags]
23
- *
24
- * Flags:
25
- * --owner <name> GitHub owner (default: parsed from origin remote)
26
- * --repo <name> GitHub repo (default: parsed from origin remote)
27
- * --visibility <v> Visibility for a newly created repo:
28
- * private | public | internal (default: private)
29
- * --operator-handle <name> GitHub handle for github.operatorHandle
30
- * --base-branch <name> Base branch (default: origin/HEAD or 'main')
31
- * --project-number <n> Projects V2 number/name (optional)
32
- * --assume-yes Accept every default + approve GitHub-admin
33
- * mutations. A non-TTY run requires this (or
34
- * --approve-github-admin) — there is no operator
35
- * to confirm the summary.
36
- * --approve-github-admin Consent to the irreversible GitHub-admin phase
37
- * (labels, Projects V2, branch protection, merge
38
- * methods) without accepting every other default.
39
- * --skip-github Skip the GitHub-side bootstrap entirely
40
- * --with-quality Opt-in: install local quality gates (pre-commit
41
- * hook + quality:preview/watch scripts). Off by
42
- * default — prompted y/N.
43
- * --dry-run Collect info and print the plan; change nothing
44
- * --with-project-board Opt-in: provision the Projects V2 Status field
45
- * and custom fields. Off by default — the project
46
- * board object is still created when a project
47
- * name is supplied, but decoration is skipped.
48
- * --with-issue-forms Opt-in: generate .github/ISSUE_TEMPLATE/story.yml.
49
- * Off by default.
50
- * --reap-conflicting-workflows Delete Projects V2 built-in workflows that
51
- * race against the orchestrator (destructive)
52
- * --help Print this help
3
+ * bootstrap.js — single-command consumer setup for Mandrel (flags: see HELP).
4
+ * Works on a folder that is not yet a git repo, and provisions the missing
5
+ * pieces of a cold start: local repo, GitHub repo, Projects V2 board.
53
6
  */
54
7
 
55
8
  import { spawnSync } from 'node:child_process';
@@ -58,7 +11,6 @@ import path from 'node:path';
58
11
  import readline from 'node:readline/promises';
59
12
  import { fileURLToPath } from 'node:url';
60
13
 
61
- // Reused bootstrap library helpers (unchanged).
62
14
  import {
63
15
  buildManualInstructions,
64
16
  COMMIT_SUBJECT,
@@ -118,27 +70,14 @@ Flags:
118
70
  --help Print this help
119
71
  `;
120
72
 
121
- // ---------------------------------------------------------------------------
122
- // Small helpers
123
- // ---------------------------------------------------------------------------
124
-
125
- /** Strip an `owner/` prefix off a repo slug, leaving the bare repo name. */
126
73
  function bareRepoName(slug) {
127
74
  const slash = slug.indexOf('/');
128
75
  return slash === -1 ? slug : slug.slice(slash + 1);
129
76
  }
130
77
 
131
78
  /**
132
- * Normalize an operator handle to the bare login the starter template expects.
133
- *
134
- * The starter `.agentrc.json` carries `"operatorHandle": "@[USERNAME]"` and the
135
- * seed step substitutes `[USERNAME]` with this answer — so the answer MUST be
136
- * the bare handle (no leading `@`), or the seeded value becomes `@@foo`. The
137
- * interactive validator already rejects a leading `@`, but the
138
- * `--operator-handle @x` flag and `GH_OPERATOR_HANDLE=@x` env paths skip that
139
- * validator (Story #3700). Stripping a single leading `@` here closes that gap
140
- * for every resolution path. Idempotent: a bare handle is returned unchanged,
141
- * so a re-run never re-strips or re-accumulates.
79
+ * Strip one leading `@`: the starter template's `@[USERNAME]` would otherwise
80
+ * seed `@@foo`, and the flag/env paths bypass the interactive validator.
142
81
  *
143
82
  * @param {string|undefined|null} handle
144
83
  * @returns {string|undefined|null} the input with a single leading `@` removed
@@ -148,7 +87,6 @@ export function normalizeHandleAnswer(handle) {
148
87
  return handle.replace(/^@/, '');
149
88
  }
150
89
 
151
- /** Run a list-producing fn, returning [] on any throw. */
152
90
  function safeList(fn) {
153
91
  try {
154
92
  return fn() ?? [];
@@ -171,11 +109,7 @@ export function resolveOwnerForPicker(defaults, flags, env = process.env) {
171
109
  return null;
172
110
  }
173
111
 
174
- /**
175
- * Ask a yes/no question. `defaultAnswer` controls the default when the
176
- * operator presses Enter without typing (true = Y/n, false = y/N). In
177
- * non-interactive mode the default is returned immediately.
178
- */
112
+ /** Yes/no prompt; non-interactive returns `defaultAnswer`. */
179
113
  async function confirmYesNo(message, interactive, defaultAnswer = true) {
180
114
  if (!interactive) return defaultAnswer;
181
115
  const rl = readline.createInterface({
@@ -194,12 +128,7 @@ async function confirmYesNo(message, interactive, defaultAnswer = true) {
194
128
  }
195
129
  }
196
130
 
197
- /**
198
- * Run a git command in `cwd`. Returns the normalized
199
- * `{ ok, status, stdout, stderr, error }` shape (mirroring the bootstrap
200
- * preflight/gh-list runners) so callers branch on `ok` without juggling
201
- * spawnSync internals.
202
- */
131
+ /** Run git in `cwd` → `{ ok, status, stdout, stderr, error }`. */
203
132
  function runGit(args, cwd) {
204
133
  const result = spawnSync('git', args, { cwd, encoding: 'utf8' });
205
134
  return {
@@ -211,11 +140,7 @@ function runGit(args, cwd) {
211
140
  };
212
141
  }
213
142
 
214
- /**
215
- * Surface a `gh`/exec failure with the same detail the GitHub bootstrap
216
- * step prints — message plus the real gh stderr/stdout/args carried on a
217
- * `GhExecError` — so a bare "gh exited with code 1" is actually diagnosable.
218
- */
143
+ /** Log a `GhExecError` with its gh stderr/stdout/args so it is diagnosable. */
219
144
  function logGhError(label, err) {
220
145
  Logger.error(`[Bootstrap] ${label} failed: ${err.message}`);
221
146
  if (err.stderr)
@@ -228,11 +153,8 @@ function logGhError(label, err) {
228
153
  }
229
154
 
230
155
  /**
231
- * Per-command git identity args. The first commit fails when neither a repo-
232
- * nor global-level `user.name`/`user.email` is configured, which is common on
233
- * a freshly provisioned machine. When either is missing we supply a
234
- * non-persistent identity via `-c` (derived from the operator handle) so the
235
- * commit succeeds without mutating the operator's git config.
156
+ * A non-persistent `-c` identity when `user.name`/`user.email` is unset (fresh
157
+ * machine), so the commit succeeds without mutating the operator's config.
236
158
  */
237
159
  function gitIdentityArgs(cwd, answers) {
238
160
  const haveName = runGit(['config', 'user.name'], cwd).ok;
@@ -248,19 +170,15 @@ function gitIdentityArgs(cwd, answers) {
248
170
  }
249
171
 
250
172
  /**
251
- * Initialize the local git repo when one is not already present, and ensure
252
- * at least one commit exists so `gh repo create --source=. --push` has
253
- * something to push. Idempotent: a repo that already resolves `HEAD` is left
254
- * untouched. Returns `{ ok, initialized, committed }` (or `{ ok:false, error }`
255
- * on failure).
173
+ * Idempotently init the repo and ensure a commit exists for
174
+ * `gh repo create --push`.
256
175
  */
257
176
  function ensureGitInitialized(state) {
258
177
  const cwd = state.projectRoot;
259
178
  const branch = state.answers.baseBranch || 'main';
260
179
  let initialized = false;
261
180
  if (!state.gitInitialized) {
262
- // `git init -b <branch>` (git ≥ 2.28) sets the initial branch directly;
263
- // fall back to a plain init + symbolic-ref for older git.
181
+ // `init -b` needs git ≥ 2.28; fall back to init + symbolic-ref.
264
182
  let init = runGit(['init', '-b', branch], cwd);
265
183
  if (!init.ok) {
266
184
  init = runGit(['init'], cwd);
@@ -275,18 +193,8 @@ function ensureGitInitialized(state) {
275
193
  );
276
194
  }
277
195
 
278
- // A push needs a commit; create one only when HEAD does not resolve yet.
279
- //
280
- // SECURITY (Story #3894): do NOT `git add -A` here. `.gitignore` seeding
281
- // (`ensureGitignore`) runs two phases later in the pipeline, so at this
282
- // point a cold-start folder may still contain secret-bearing files
283
- // (`.env`, `.mcp.json`). Staging the whole tree before any gitignore
284
- // exists — followed immediately by `gh repo create --push` — would push
285
- // those secrets to a brand-new (often public) remote with no per-file
286
- // consent, violating `security-baseline.md` § Secrets Management. The
287
- // push only needs a commit to *exist*, so we create an empty one; the
288
- // operator's own first content commit lands after the gitignore phase has
289
- // already excluded the secret-bearing paths.
196
+ // SECURITY: the commit is EMPTY, never `git add -A` — `.gitignore` is seeded
197
+ // later, so staging now would push `.env` / `.mcp.json` to the new remote.
290
198
  let committed = false;
291
199
  if (!runGit(['rev-parse', '--verify', 'HEAD'], cwd).ok) {
292
200
  const commit = runGit(
@@ -309,14 +217,9 @@ function ensureGitInitialized(state) {
309
217
  }
310
218
 
311
219
  /**
312
- * Wire the local `origin` remote to owner/repo when it is missing, so the
313
- * GitHub bootstrap — which infers the target repo from the local remote —
314
- * can run. This is the companion to `createGithubRepo`: that path wires
315
- * `origin` itself via `--remote origin`, but a repo that already exists (or
316
- * a re-run after a partial failure) leaves the local folder unlinked. Only
317
- * acts when the repo actually exists on GitHub; pushes the base branch to
318
- * set upstream, downgrading a rejected push to a warning since the bootstrap
319
- * only needs the remote to resolve (content sync is the operator's to settle).
220
+ * Wire a missing `origin` to an existing GitHub repo (the GitHub bootstrap
221
+ * infers its target from it). A rejected push only warns: the remote just
222
+ * needs to resolve.
320
223
  */
321
224
  async function ensureGitRemote(state, execImpl = exec) {
322
225
  const cwd = state.projectRoot;
@@ -345,12 +248,8 @@ async function ensureGitRemote(state, execImpl = exec) {
345
248
  }
346
249
 
347
250
  /**
348
- * Authoritatively check whether `owner/repo` exists, via `gh repo view`.
349
- * Returns false on a not-found (so the repo can be created), true when it
350
- * resolves, and true on any other error (auth/network/etc.) so a transient
351
- * failure never triggers a spurious create attempt. Used instead of an
352
- * `is it in the repo-list?` heuristic, which mis-fires for a brand-new
353
- * account whose `gh repo list` is empty.
251
+ * `gh repo view` probe: false only on not-found, so a transient error never
252
+ * triggers a spurious create. (A repo-list check mis-fires on empty accounts.)
354
253
  */
355
254
  async function repoExists(owner, repo, execImpl = exec) {
356
255
  try {
@@ -364,14 +263,7 @@ async function repoExists(owner, repo, execImpl = exec) {
364
263
  }
365
264
  }
366
265
 
367
- /**
368
- * Link the repo to the Projects V2 board (`gh project link`) so issues and
369
- * PRs from the repo surface on the project. Runs whenever both a numeric
370
- * project number and a repo are resolved — a freshly created project or an
371
- * existing one picked from the list. Non-fatal and re-run-safe: an
372
- * already-linked repo or a transient hiccup is downgraded to a warning so it
373
- * never fails the bootstrap.
374
- */
266
+ /** `gh project link` the repo to the board; non-fatal and re-run-safe. */
375
267
  async function ensureProjectLinked(state, execImpl = exec) {
376
268
  const { owner, repo } = state.answers;
377
269
  const pn = String(state.answers.projectNumber ?? '');
@@ -397,11 +289,7 @@ export const REPO_VISIBILITIES = Object.freeze([
397
289
  'internal',
398
290
  ]);
399
291
 
400
- /**
401
- * Resolve the new-repo visibility from `--visibility` (default `private`).
402
- * Case-insensitive. Returns `null` for an unrecognized value so the caller
403
- * can reject it with a clear message instead of silently defaulting.
404
- */
292
+ /** `--visibility` (default `private`); `null` for an unknown value. */
405
293
  export function resolveRepoVisibility(flags = {}) {
406
294
  const raw = flags.visibility;
407
295
  if (typeof raw !== 'string' || raw.length === 0) return 'private';
@@ -409,14 +297,7 @@ export function resolveRepoVisibility(flags = {}) {
409
297
  return REPO_VISIBILITIES.includes(value) ? value : null;
410
298
  }
411
299
 
412
- /**
413
- * Create the GitHub repo from the resolved owner/repo. `--source` links the
414
- * existing local repo, `--remote origin` wires the remote, and `--push`
415
- * uploads the current branch — so the local tree and the new remote stay in
416
- * lockstep and Step 1's auto-detection works on a re-run. Visibility comes
417
- * from `--visibility` (default private). Throws GhExecError on failure
418
- * (surfaced by the caller).
419
- */
300
+ /** Create, link as `origin`, and push the repo. Throws GhExecError. */
420
301
  async function createGithubRepo(state, execImpl = exec) {
421
302
  const { owner, repo } = state.answers;
422
303
  const slug = `${owner}/${repo}`;
@@ -440,13 +321,8 @@ async function createGithubRepo(state, execImpl = exec) {
440
321
  }
441
322
 
442
323
  /**
443
- * Find an existing Projects V2 board owned by `owner` whose title matches
444
- * `title` exactly (case-insensitive, trimmed), returning its numeric id or
445
- * `null` when none matches. Lists through the injected `execImpl` seam (the
446
- * same `gh project list --owner X --format json` shape `gh-list` parses) so
447
- * the dedupe is unit-testable without spawning a real `gh`. Any non-zero
448
- * exit, spawn error, or unparseable payload degrades to `null` (no match) so
449
- * a transient list failure never blocks creation.
324
+ * The number of the owner's board titled `title` (case-insensitive), or
325
+ * `null` — including on any list failure, which must not block creation.
450
326
  *
451
327
  * @param {string} owner
452
328
  * @param {string} title
@@ -486,14 +362,8 @@ async function findExistingProjectNumber(owner, title, execImpl) {
486
362
  }
487
363
 
488
364
  /**
489
- * Resolve the typed Projects V2 name into a numeric id and rewrite
490
- * `state.answers.projectNumber` so the downstream persist + GitHub bootstrap
491
- * steps treat it as an existing project (and never create a duplicate). Before
492
- * creating, it **dedupes against the owner's existing project titles**: if a
493
- * board with the same title already exists, that board is adopted instead of
494
- * running `gh project create` — so a re-run that re-types the same name never
495
- * spawns a second same-titled board (Story #3896 / review Finding B.3). Throws
496
- * on create failure or when gh returns no number.
365
+ * Resolve the typed board name to a number (adopting a same-titled board so a
366
+ * re-run never duplicates it) and write it onto `answers.projectNumber`.
497
367
  */
498
368
  async function createGithubProject(state, execImpl = exec) {
499
369
  const { owner } = state.answers;
@@ -506,8 +376,7 @@ async function createGithubProject(state, execImpl = exec) {
506
376
  );
507
377
  return existing;
508
378
  }
509
- // `gh project create` uses `--format json` (not `--json`), so exec returns
510
- // the raw `{ stdout }` envelope — parse the number ourselves.
379
+ // `--format json` (not `--json`): exec returns raw stdout to parse.
511
380
  const res = await execImpl({
512
381
  args: [
513
382
  'project',
@@ -536,32 +405,16 @@ async function createGithubProject(state, execImpl = exec) {
536
405
  return number;
537
406
  }
538
407
 
539
- // ---------------------------------------------------------------------------
540
- // Question list (Step 3).
541
- // ---------------------------------------------------------------------------
542
-
543
- /**
544
- * Build the Step 3 question list. `silentAccept` keys (owner/repo/baseBranch/
545
- * operatorHandle) are git-inferred and accepted without prompting unless an
546
- * override is supplied. The `operatorHandle` and `projectNumber` defaults
547
- * track the repo owner / repo name respectively (see post-processing in
548
- * `collectAndConfirm`).
549
- */
408
+ /** The Step 3 question list. */
550
409
  export function buildQuestions(defaults, flags, env = process.env, lists = {}) {
551
410
  const owner = resolveOwnerForPicker(defaults, flags, env);
552
- // Pre-fetched lists (shared with the summary display) are a fast path used
553
- // only when populated. They're empty when the owner is unknown up front
554
- // (a folder with no git remote), so the pickers fall back to a live fetch
555
- // keyed off the owner the operator just typed (`answers.owner`).
411
+ // Pre-fetched lists are empty when the owner was unknown up front, so the
412
+ // pickers fall back to a live fetch keyed off the typed `answers.owner`.
556
413
  const reposList = lists.reposList;
557
414
  const projectsList = lists.projectsList;
558
415
  const pickerOwner = (answers) => answers?.owner || owner;
559
- // `owner` / `repo` are GitHub-side answers. When `--skip-github` suppresses
560
- // the entire GitHub bootstrap, they are not required — this lets a
561
- // non-interactive `--assume-yes --skip-github` run materialize and configure
562
- // a fresh non-git directory (no inferable remote) without hard-failing on
563
- // `missing required answers: owner, repo`. With GitHub bootstrap active they
564
- // remain required (the target repo must be resolvable).
416
+ // owner/repo are optional under --skip-github, so a remote-less folder can
417
+ // still be configured non-interactively.
565
418
  const skipGithub = Boolean(flags?.['skip-github']);
566
419
  return [
567
420
  {
@@ -580,7 +433,6 @@ export function buildQuestions(defaults, flags, env = process.env, lists = {}) {
580
433
  env: 'GH_OPERATOR_HANDLE',
581
434
  message:
582
435
  'GitHub username/handle without preceding@ (default: same as owner)',
583
- // Default tracks the repo owner; resolved post-collect if left blank.
584
436
  default: defaults.owner,
585
437
  required: false,
586
438
  validate: (v) =>
@@ -624,11 +476,7 @@ export function buildQuestions(defaults, flags, env = process.env, lists = {}) {
624
476
  message: 'New GitHub Project V2 name',
625
477
  pickerMessage:
626
478
  'GitHub Project V2 name - Select existing or press ENTER to create',
627
- // Prefer the already-stored numeric project number (an
628
- // already-provisioned project on a re-run) so `--assume-yes` resolves a
629
- // numeric answer that `detectCreation` treats as existing — never a
630
- // duplicate board (Story #3896). Falls back to the repo name only on a
631
- // genuine first run where nothing is stored yet.
479
+ // A stored number first, so a re-run never reads as a new board.
632
480
  default: defaults.projectNumber || defaults.repo,
633
481
  required: false,
634
482
  picker: {
@@ -640,8 +488,7 @@ export function buildQuestions(defaults, flags, env = process.env, lists = {}) {
640
488
  return o ? listProjects({ owner: o }) : [];
641
489
  },
642
490
  },
643
- // Accept blank (skip), an existing project number, or a new project
644
- // name (letters/digits/space/._-).
491
+ // Blank (skip), an existing number, or a new project name.
645
492
  validate: (v) =>
646
493
  v.length === 0 || /^\d+$/.test(v) || /^[A-Za-z0-9 ._-]+$/.test(v)
647
494
  ? null
@@ -682,10 +529,6 @@ export function resolveSilentAccept(defaults, flags, env = process.env) {
682
529
  return out;
683
530
  }
684
531
 
685
- // ---------------------------------------------------------------------------
686
- // GitHub-side bootstrap (Step 6) — same wiring as bootstrap.js.
687
- // ---------------------------------------------------------------------------
688
-
689
532
  async function runGithubBootstrap(answers, opts) {
690
533
  const { runBootstrap, preflightGh, preflightRuntimeDeps } = await import(
691
534
  './agents-bootstrap-github.js'
@@ -695,10 +538,8 @@ async function runGithubBootstrap(answers, opts) {
695
538
  const { resolveConfig, validateOrchestrationConfig } = await import(
696
539
  './lib/config-resolver.js'
697
540
  );
698
- // `resolveConfig` reads github.projectNumber from .agentrc.json, which the
699
- // persistProjectNumber step writes BEFORE this runs — so the provider reuses
700
- // the existing project instead of creating a new one (Bug: gave #8, created
701
- // #12 because the number never reached the provider config).
541
+ // persistProjectNumber has already written the number, so the provider
542
+ // reuses the board instead of creating another.
702
543
  const config = resolveConfig();
703
544
  validateOrchestrationConfig(config);
704
545
  return runBootstrap(config, {
@@ -706,15 +547,9 @@ async function runGithubBootstrap(answers, opts) {
706
547
  github: config.github,
707
548
  assumeYes: opts.assumeYes,
708
549
  baseBranch: answers.baseBranch,
709
- // Real consent signal threaded from `parseAndValidate` (Story #3897):
710
- // interactive operator confirmation, `--assume-yes`, or
711
- // `--approve-github-admin`. Default-deny at the boundary gate when absent.
550
+ // Default-deny at the boundary gate (see parseAndValidate).
712
551
  githubAdminApproved: opts.githubAdminApproved === true,
713
- // Opt-in: provision Status field + custom fields on the project board.
714
- // Default off — prompted y/N during collect/confirm or via --with-project-board.
715
552
  withProjectBoard: opts.withProjectBoard === true,
716
- // Opt-in: delete the Projects V2 built-in workflows that race against the
717
- // orchestrator's ColumnSync (e.g. "Pull request merged"). Off by default.
718
553
  reapConflictingWorkflows: Boolean(opts.reapConflictingWorkflows),
719
554
  });
720
555
  }
@@ -727,13 +562,8 @@ function githubSubMutationsSucceeded(gh) {
727
562
  }
728
563
 
729
564
  /**
730
- * Phase groups whose mutations actually landed, for the install ledger.
731
- *
732
- * Every project-side group runs on every install (Story #3690 replaced the
733
- * consent-first phased-approval install with a plain summary+confirm loop),
734
- * so the only variable is whether the irreversible GitHub-admin mutations
735
- * landed. Story #5007 collapsed the set-threading this used to carry down to
736
- * that one boolean.
565
+ * Phase groups that landed, for the install ledger. Every project-side group
566
+ * always runs; only GitHub-admin is variable.
737
567
  *
738
568
  * @param {object|undefined} report — the live execution report.
739
569
  * @returns {Set<string>}
@@ -748,29 +578,11 @@ function resolveAppliedGroups(report) {
748
578
  return applied;
749
579
  }
750
580
 
751
- // ---------------------------------------------------------------------------
752
- // Pipeline phases
753
- // ---------------------------------------------------------------------------
754
-
755
581
  /**
756
- * Step 1 — Parse argv, handle `--help`, and enforce the non-TTY contract.
757
- *
758
- * Consent contract (Story #3897). A non-TTY run has no operator to confirm
759
- * the summary loop in `collectAndConfirm`, so the irreversible GitHub-admin
760
- * mutations cannot ride on a real confirmation — they need an explicit
761
- * up-front signal. The gate therefore requires **either** `--assume-yes`
762
- * **or** `--approve-github-admin` on any non-TTY run (matching the
763
- * `--help` text), and computes `githubAdminApproved` once for the whole run:
764
- *
765
- * - **interactive (TTY)** → consent is the operator's `Is this correct?`
766
- * confirmation in `collectAndConfirm`, so the run is approved.
767
- * - **non-TTY** → consent is `--assume-yes` or `--approve-github-admin`;
768
- * without one of those the run halts before any mutation.
769
- *
770
- * `githubAdminApproved` flows down to `runGithubBootstrap`, which forwards it
771
- * to the boundary gate in `agents-bootstrap-github.js#runBootstrap`. That
772
- * gate is default-deny, so a non-approved value makes the GitHub-admin phase
773
- * a verified no-op instead of a silent mutation.
582
+ * Step 1 — parse argv and compute GitHub-admin consent once: an interactive
583
+ * run consents via the summary confirmation; a non-TTY run MUST pass
584
+ * `--assume-yes` or `--approve-github-admin` or halts before any mutation.
585
+ * The downstream gate in `runBootstrap` is default-deny.
774
586
  */
775
587
  export function parseAndValidate(argv, opts = {}) {
776
588
  const stdout = opts.stdout ?? process.stdout;
@@ -783,12 +595,6 @@ export function parseAndValidate(argv, opts = {}) {
783
595
  const interactive = Boolean(stdin.isTTY) && !flags['assume-yes'];
784
596
  const assumeYes = Boolean(flags['assume-yes']);
785
597
  const approveGithubAdmin = Boolean(flags['approve-github-admin']);
786
- // A non-TTY run cannot collect operator consent interactively, so it MUST
787
- // carry an explicit consent signal. This restores parity with the --help
788
- // text, which has always claimed --assume-yes is required for non-TTY runs.
789
- // (owner/repo are resolved from flags/env/git-remote downstream — a consent
790
- // signal alone is sufficient to advance, exactly as the pre-Story #3897
791
- // `--assume-yes` path did.)
792
598
  if (!interactive && !assumeYes && !approveGithubAdmin) {
793
599
  Logger.error(
794
600
  '[Bootstrap] non-TTY run requires --assume-yes or --approve-github-admin ' +
@@ -796,8 +602,6 @@ export function parseAndValidate(argv, opts = {}) {
796
602
  );
797
603
  return { ok: false, exit: 1 };
798
604
  }
799
- // Real GitHub-admin consent: an interactive run confirms it in
800
- // `collectAndConfirm`; a non-TTY run signals it via flag (above).
801
605
  const githubAdminApproved = interactive || assumeYes || approveGithubAdmin;
802
606
  if (resolveRepoVisibility(flags) === null) {
803
607
  Logger.error(
@@ -812,10 +616,7 @@ export function parseAndValidate(argv, opts = {}) {
812
616
  };
813
617
  }
814
618
 
815
- /**
816
- * Step 1b — Resolve paths, infer defaults from git, and echo the detected
817
- * values back to the operator (the "share found values" requirement).
818
- */
619
+ /** Step 1b — resolve paths, infer defaults from git, and echo them. */
819
620
  export function prepareContext(state, opts = {}) {
820
621
  const scriptUrl = opts.scriptUrl ?? import.meta.url;
821
622
  const here = path.dirname(fileURLToPath(scriptUrl));
@@ -837,11 +638,7 @@ export function prepareContext(state, opts = {}) {
837
638
  };
838
639
  }
839
640
 
840
- /**
841
- * Step 2 — Preflight. Work-tree check is informational (does not fail the
842
- * gate); adds the Projects V2 permission check. Prints a pass/fail line for
843
- * every check.
844
- */
641
+ /** Step 2 — preflight; the work-tree check is informational only. */
845
642
  export async function runPreflightPhase(state, opts = {}) {
846
643
  const run = opts.run ?? runPreflight;
847
644
  const skipGithub = Boolean(state.flags['skip-github']);
@@ -853,10 +650,7 @@ export async function runPreflightPhase(state, opts = {}) {
853
650
 
854
651
  for (const check of result.checks) {
855
652
  if (check.ok) {
856
- // A non-fatal informational check (it carries `gitInitialized`) shows a
857
- // glyph reflecting the real state rather than its always-true gate pass:
858
- // ✓ when the git repo exists, ✗ when it does not (bootstrap initialises
859
- // it in a later phase regardless — the ✗ never aborts the run).
653
+ // The informational git check shows the real state; its ✗ never aborts.
860
654
  const glyph =
861
655
  typeof check.gitInitialized === 'boolean' && !check.gitInitialized
862
656
  ? '✗'
@@ -876,18 +670,12 @@ export async function runPreflightPhase(state, opts = {}) {
876
670
  return { ok: false, exit: 1 };
877
671
  }
878
672
 
879
- // The git-repo state is already reported by the (non-fatal) "Local git
880
- // initialized" check above — both derive from the same
881
- // `git rev-parse --is-inside-work-tree` probe — so there is no separate
882
- // "git initialized" line here (it would duplicate, and contradict, that
883
- // check). The boolean is still threaded through the payload for later phases.
884
673
  return {
885
674
  ok: true,
886
675
  payload: { preflight: result, gitInitialized: result.gitInitialized },
887
676
  };
888
677
  }
889
678
 
890
- /** Render the resolved answers as a human-readable summary block. */
891
679
  function renderAnswerSummary(
892
680
  answers,
893
681
  creation,
@@ -912,14 +700,8 @@ function renderAnswerSummary(
912
700
  }
913
701
 
914
702
  /**
915
- * Determine whether the answers ask for resources that do not exist yet.
916
- * The repo is "new" when `gh repo view owner/repo` reports it does not
917
- * exist — an authoritative per-repo probe rather than an "is it in the
918
- * repo-list?" check, which mis-fired for a brand-new account whose
919
- * `gh repo list` is empty (it then assumed the repo already existed and
920
- * skipped creation). A non-numeric project answer (a typed name, not a
921
- * picked number) is "new". When GitHub is skipped there is nothing to
922
- * create, so detection is bypassed.
703
+ * Which answers name resources that do not exist yet: a repo `repoExists`
704
+ * denies, or a non-numeric (typed) project answer.
923
705
  */
924
706
  async function detectCreation(answers, skipGithub) {
925
707
  const creation = { newRepo: false, newProject: false };
@@ -935,10 +717,8 @@ async function detectCreation(answers, skipGithub) {
935
717
  }
936
718
 
937
719
  /**
938
- * Resolve the Projects V2 answer into a `{ name, number }` pair for the
939
- * summary. The picker stores only the numeric value, so for an existing
940
- * project (numeric answer) we look the name up in the owner's project list.
941
- * A typed answer (non-numeric) is a new project name with no number yet.
720
+ * `{ name, number }` for the summary; the picker stores only the number, so
721
+ * an existing project's name is looked up.
942
722
  */
943
723
  function resolveProjectDisplay(answers, skipGithub, projectsList) {
944
724
  const pn = answers.projectNumber;
@@ -956,23 +736,17 @@ function resolveProjectDisplay(answers, skipGithub, projectsList) {
956
736
  }
957
737
  return { name, number: pn };
958
738
  }
959
- // Typed name → new project; number is assigned at creation time.
960
739
  return { name: pn, number: '(new)' };
961
740
  }
962
741
 
963
742
  /**
964
- * Steps 3 + 4 — Collect answers, show a summary, and confirm. Interactive
965
- * runs that answer "no" loop back and re-ask. Non-interactive runs
966
- * auto-accept. Then collect creation approval when a new repo/project was
967
- * requested.
743
+ * Steps 3 + 4 — collect answers and loop until the summary is confirmed, then
744
+ * get creation approval and the opt-ins.
968
745
  */
969
746
  export async function collectAndConfirm(state) {
970
747
  const skipGithub = Boolean(state.flags['skip-github']);
971
748
  const owner = resolveOwnerForPicker(state.defaults, state.flags);
972
- // Fetch the owner's repos + projects ONCE and reuse for the pickers and
973
- // the summary display — so the resolved project name never depends on a
974
- // second (flaky) `gh` call. (Repo existence for the creation check is a
975
- // separate, authoritative `gh repo view` probe in `detectCreation`.)
749
+ // Fetched once for pickers and summary, so the name never needs a second call.
976
750
  const reposList =
977
751
  !skipGithub && owner
978
752
  ? safeList(() => listRepos({ owner }).map(bareRepoName))
@@ -981,7 +755,6 @@ export async function collectAndConfirm(state) {
981
755
  !skipGithub && owner ? safeList(() => listProjects({ owner })) : [];
982
756
 
983
757
  let silentAccept = state.silentAccept;
984
- // Loop until the operator confirms the summary (or we auto-accept).
985
758
  for (;;) {
986
759
  const { answers, missing } = await collectAnswers({
987
760
  questions: buildQuestions(state.defaults, state.flags, process.env, {
@@ -1002,12 +775,7 @@ export async function collectAndConfirm(state) {
1002
775
  );
1003
776
  return { ok: false, exit: 1 };
1004
777
  }
1005
- // Defaults that track another answer: handle ⇐ owner, project ⇐ repo.
1006
778
  if (!answers.operatorHandle) answers.operatorHandle = answers.owner;
1007
- // Strip a single leading `@` so the starter template's `@[USERNAME]`
1008
- // substitution yields `@foo`, not `@@foo` (Story #3700). The flag/env
1009
- // paths bypass the interactive validator that already rejects a leading
1010
- // `@`, so normalize uniformly here.
1011
779
  answers.operatorHandle = normalizeHandleAnswer(answers.operatorHandle);
1012
780
 
1013
781
  const creation = await detectCreation(answers, skipGithub);
@@ -1024,12 +792,10 @@ export async function collectAndConfirm(state) {
1024
792
  const correct = await confirmYesNo('Is this correct?', state.interactive);
1025
793
  if (!correct) {
1026
794
  Logger.info('[Bootstrap] Okay — let’s try again.');
1027
- // Re-prompt everything on the next pass (drop silent-accept).
1028
795
  silentAccept = [];
1029
796
  continue;
1030
797
  }
1031
798
 
1032
- // In --dry-run we only collect/confirm info, so never ask to create.
1033
799
  if (!state.flags['dry-run'] && (creation.newRepo || creation.newProject)) {
1034
800
  const approved = await confirmYesNo(
1035
801
  'Create the new GitHub repo/project listed above?',
@@ -1043,8 +809,7 @@ export async function collectAndConfirm(state) {
1043
809
  }
1044
810
  }
1045
811
 
1046
- // Opt-in: board decoration (Status field, custom fields). Default off.
1047
- // Dry-run halts immediately after this step — resolve without prompting.
812
+ // Opt-ins default off; dry-run resolves them without prompting.
1048
813
  let withProjectBoard = Boolean(state.flags['with-project-board']);
1049
814
  if (!state.flags['dry-run'] && !withProjectBoard) {
1050
815
  withProjectBoard = await confirmYesNo(
@@ -1054,7 +819,6 @@ export async function collectAndConfirm(state) {
1054
819
  );
1055
820
  }
1056
821
 
1057
- // Opt-in: GitHub Issue Form templates. Default off.
1058
822
  let withIssueForms = Boolean(state.flags['with-issue-forms']);
1059
823
  if (!state.flags['dry-run'] && !withIssueForms) {
1060
824
  withIssueForms = await confirmYesNo(
@@ -1064,7 +828,6 @@ export async function collectAndConfirm(state) {
1064
828
  );
1065
829
  }
1066
830
 
1067
- // Opt-in: local quality gates. Default off.
1068
831
  let withQuality = Boolean(state.flags['with-quality']);
1069
832
  if (!state.flags['dry-run'] && !withQuality) {
1070
833
  withQuality = await confirmYesNo(
@@ -1087,12 +850,6 @@ export async function collectAndConfirm(state) {
1087
850
  }
1088
851
  }
1089
852
 
1090
- /**
1091
- * --dry-run gate — print the resolved answers and the full mutation plan,
1092
- * then halt BEFORE any file write, GitHub change, or label creation. Runs
1093
- * after collect/confirm so the operator sees exactly what would happen.
1094
- */
1095
- /** Render the dry-run plan as a per-section layout (no mutations happen). */
1096
853
  function renderDryRunPlan(state) {
1097
854
  const a = state.answers ?? {};
1098
855
  const c = state.creation ?? {};
@@ -1118,6 +875,7 @@ function renderDryRunPlan(state) {
1118
875
  ].join('\n');
1119
876
  }
1120
877
 
878
+ /** --dry-run gate: print the plan and halt before any mutation. */
1121
879
  export function dryRunPlan(state) {
1122
880
  if (!state.flags['dry-run']) return { ok: true, payload: {} };
1123
881
  Logger.info(
@@ -1128,34 +886,14 @@ export function dryRunPlan(state) {
1128
886
  }
1129
887
 
1130
888
  /**
1131
- * Step 5 — Provision the missing pieces of a cold start, in dependency order:
1132
- *
1133
- * 1. Local git — `git init` + an initial commit when the folder is not a
1134
- * repo yet (so the repo create below has something to push).
1135
- * 2. GitHub repo — `gh repo create --source --remote --push` when the repo
1136
- * does not exist for the owner; otherwise wire the `origin` remote to the
1137
- * existing repo when the local folder is not yet linked. Either way the
1138
- * GitHub bootstrap can resolve the target from the local remote.
1139
- * 3. GitHub Project V2 — `gh project create` from the typed name when the
1140
- * project answer is a name rather than an existing number; the assigned
1141
- * number is written back onto `state.answers.projectNumber`.
1142
- * 4. Link — `gh project link` ties the repo to the project board so its
1143
- * issues/PRs surface there (non-fatal; safe to re-run).
1144
- *
1145
- * Every action is idempotent and guarded by the detection done in
1146
- * `collectAndConfirm`, so a re-run on an already-provisioned project is a
1147
- * no-op. `--skip-github` suppresses the GitHub mutations but still runs the
1148
- * local git init. `--dry-run` never reaches this step (it halts earlier).
1149
- *
1150
- * `deps.exec` injects the `gh-exec` seam so the GitHub-touching branches
1151
- * (`gh repo create`, `gh project create`, `gh project link`) are unit-testable
1152
- * without spawning a real `gh`; it defaults to the module's `exec`.
889
+ * Step 5 — provision a cold start in dependency order: local git, GitHub repo
890
+ * (or `origin` wiring), Projects V2 board, repo↔board link. Every step is
891
+ * idempotent; `--skip-github` still runs the local git init.
1153
892
  */
1154
893
  export async function provisionResources(state, deps = {}) {
1155
894
  const execImpl = deps.exec ?? exec;
1156
895
  const skipGithub = Boolean(state.flags['skip-github']);
1157
896
 
1158
- // 1. Local git — initialize + first commit when missing (idempotent).
1159
897
  const git = ensureGitInitialized(state);
1160
898
  if (!git.ok) {
1161
899
  Logger.error(`[Bootstrap] git initialization failed: ${git.error}`);
@@ -1175,10 +913,6 @@ export async function provisionResources(state, deps = {}) {
1175
913
  return { ok: true, payload: {} };
1176
914
  }
1177
915
 
1178
- // 2. GitHub repo — create + link + push when it does not exist yet;
1179
- // otherwise ensure the local `origin` remote points at the existing repo
1180
- // so the GitHub bootstrap can resolve the target (idempotent re-runs and
1181
- // pre-created repos would otherwise leave the folder unlinked).
1182
916
  if (newRepo) {
1183
917
  try {
1184
918
  await createGithubRepo(state, execImpl);
@@ -1190,12 +924,9 @@ export async function provisionResources(state, deps = {}) {
1190
924
  await ensureGitRemote(state, execImpl);
1191
925
  }
1192
926
 
1193
- // 3. GitHub Project V2 — create from the typed name; capture its number so
1194
- // the persist + GitHub bootstrap steps reuse it instead of duplicating.
1195
927
  if (newProject) {
1196
928
  try {
1197
929
  await createGithubProject(state, execImpl);
1198
- // It now exists with a real number; downstream treats it as existing.
1199
930
  state.creation.newProject = false;
1200
931
  } catch (err) {
1201
932
  logGhError('project create', err);
@@ -1207,19 +938,12 @@ export async function provisionResources(state, deps = {}) {
1207
938
  Logger.info('[Bootstrap] No new GitHub resources needed.');
1208
939
  }
1209
940
 
1210
- // 4. Link the repo to the project board so issues/PRs surface on it
1211
- // (idempotent + non-fatal; runs for both freshly created and existing
1212
- // repo/project pairs).
1213
941
  await ensureProjectLinked(state, execImpl);
1214
942
 
1215
943
  return { ok: true, payload: {} };
1216
944
  }
1217
945
 
1218
- /**
1219
- * Step 6a — Project-side bootstrap. Every project-side phase runs; the
1220
- * install ledger decides afterwards which phase groups actually landed
1221
- * ({@link resolveAppliedGroups}).
1222
- */
946
+ /** Step 6a — project-side bootstrap (every phase runs). */
1223
947
  export async function executeBootstrap(state) {
1224
948
  Logger.info(
1225
949
  `[Bootstrap] Starting project bootstrap at ${state.projectRoot} (owner=${state.answers.owner} repo=${state.answers.repo} base=${state.answers.baseBranch})`,
@@ -1235,13 +959,9 @@ export async function executeBootstrap(state) {
1235
959
  }
1236
960
 
1237
961
  /**
1238
- * Step 6 (between project + GitHub) — Persist the chosen Projects V2 number
1239
- * into .agentrc.json's github block so it is the stored source of truth that
1240
- * resolveConfig (and the orchestrator) read back. Runs AFTER the project-side
1241
- * bootstrap has ensured .agentrc.json exists and BEFORE the GitHub bootstrap,
1242
- * so the provider reuses the existing project instead of creating a new one.
1243
- * Merges into an existing file (ensureAgentrc never overwrites one). Stored as
1244
- * an integer per the schema; a blank/new-project answer stores nothing.
962
+ * Persist the numeric project number into `.agentrc.json` — after the
963
+ * project-side bootstrap creates the file, before the GitHub bootstrap reads
964
+ * it, so the provider reuses the board.
1245
965
  */
1246
966
  export function persistProjectNumber(state) {
1247
967
  const pn = String(state.answers.projectNumber ?? '');
@@ -1259,10 +979,7 @@ export function persistProjectNumber(state) {
1259
979
  return { ok: true, payload: {} };
1260
980
  }
1261
981
  config.github = config.github ?? {};
1262
- // Minimal-write contract (Story #3700): only re-serialize `.agentrc.json`
1263
- // when the stored number actually changes. When the value is already present
1264
- // and equal, leave the file byte-for-byte untouched — a re-run must not churn
1265
- // the consumer's hand-formatting or whitespace.
982
+ // Unchanged → leave the file byte-for-byte (keep the consumer's formatting).
1266
983
  if (config.github.projectNumber === Number(pn)) {
1267
984
  return { ok: true, payload: {} };
1268
985
  }
@@ -1288,8 +1005,6 @@ export async function executeGithubBootstrap(state) {
1288
1005
  ),
1289
1006
  });
1290
1007
  } catch (err) {
1291
- // GhExecError carries the real gh stderr/stdout/exit code — surface it so
1292
- // a generic "gh exited with code 1" is actually diagnosable.
1293
1008
  logGhError('GitHub bootstrap', err);
1294
1009
  state.report.github = { error: err.message };
1295
1010
  }
@@ -1304,10 +1019,6 @@ export function recordLedger(state) {
1304
1019
  skipGithub: Boolean(state.flags['skip-github']),
1305
1020
  withQuality: state.withQuality === true,
1306
1021
  };
1307
- // The manifest always carries the unconditional ide-wiring / repo-config
1308
- // entries and `appliedGroups` always contains those groups, so the filter
1309
- // never empties. (Story #5007 removed the phased-approval gate that was the
1310
- // only way to reach an empty set.)
1311
1022
  const entries = buildMutationManifest(manifestCtx).filter((e) =>
1312
1023
  appliedGroups.has(e.phaseGroup),
1313
1024
  );
@@ -1315,9 +1026,8 @@ export function recordLedger(state) {
1315
1026
  entries,
1316
1027
  approvedGroups: appliedGroups,
1317
1028
  answers: state.answers,
1318
- // The live execution report lets the ledger record `already-present` vs
1319
- // `seeded` per entry, so uninstall never deletes a pre-existing
1320
- // `.agentrc.json` the install merely left in place (Story #3895).
1029
+ // Records `already-present` vs `seeded`, so uninstall never deletes a
1030
+ // pre-existing `.agentrc.json`.
1321
1031
  report: state.report,
1322
1032
  });
1323
1033
  const result = writeInstallLedger(state.projectRoot, record);
@@ -1326,32 +1036,11 @@ export function recordLedger(state) {
1326
1036
  }
1327
1037
 
1328
1038
  /**
1329
- * Step 7 — Offer to commit + push the bootstrap wiring (Story #3899).
1330
- *
1331
- * Story delivery runs in git worktrees that check out **tracked files only**,
1332
- * so an uncommitted `.agents/` tree means every Story sub-agent breaks. This
1333
- * step closes that "worked in my checkout, broke in delivery" trap by offering
1334
- * the commit + push at the end of the run.
1335
- *
1336
- * Ordering: this phase runs LAST in the pipeline, after `executeBootstrap`
1337
- * (which seeds the secret-safe `.gitignore`) and `recordLedger`. The stage
1338
- * step also uses an explicit allowlist and refuses to stage `.env` /
1339
- * `.mcp.json` / `.agentrc.local.json` regardless of `.gitignore` state, so the
1340
- * commit never carries a secret even before the gitignore-ordering Story
1341
- * (#3894) lands.
1342
- *
1343
- * Behaviour:
1344
- * - `--dry-run` → no-op (the dry-run gate already halted earlier; this is a
1345
- * belt-and-braces guard for direct calls).
1346
- * - Interactive + accept → stage the allowlist, commit with a conventional
1347
- * subject, push the base branch.
1348
- * - Interactive + decline → print the exact manual commands; no git mutation.
1349
- * - Non-interactive (`--assume-yes` / no TTY) → the defined safe path is to
1350
- * print the manual commands and make NO git mutation, so a CI run never
1351
- * surprises the operator with a push it did not ask for.
1352
- *
1353
- * `deps.runGit` injects the git seam and `deps.confirm` the yes/no prompt seam
1354
- * for unit testing; both default to the module's implementations.
1039
+ * Step 7 — offer to commit + push the wiring: delivery worktrees check out
1040
+ * tracked files only, so an uncommitted `.agents/` breaks every Story. Runs
1041
+ * last, after `.gitignore` is seeded; staging is an allowlist that refuses
1042
+ * secret files regardless. Non-interactive runs only print the commands —
1043
+ * never an unasked-for push.
1355
1044
  */
1356
1045
  export async function offerCommitPush(state, deps = {}) {
1357
1046
  if (state.flags['dry-run']) return { ok: true, payload: {} };
@@ -1365,8 +1054,6 @@ export async function offerCommitPush(state, deps = {}) {
1365
1054
  baseBranch: branch,
1366
1055
  });
1367
1056
 
1368
- // Non-interactive (--assume-yes / no TTY): never push unprompted. Print the
1369
- // exact commands and leave the working tree untouched.
1370
1057
  if (!state.interactive) {
1371
1058
  Logger.info(`\n[Bootstrap] ${instructions}`);
1372
1059
  return { ok: true, payload: { commitPush: { action: 'instructed' } } };
@@ -1392,7 +1079,7 @@ export async function offerCommitPush(state, deps = {}) {
1392
1079
  cwd,
1393
1080
  );
1394
1081
  if (!commit.ok) {
1395
- // A "nothing to commit" exit is benign — the wiring is already committed.
1082
+ // Benign when the wiring is already committed.
1396
1083
  Logger.warn(
1397
1084
  `[Bootstrap] git commit did not create a commit (already committed?): ${commit.stderr || commit.stdout}`,
1398
1085
  );
@@ -1411,7 +1098,6 @@ export async function offerCommitPush(state, deps = {}) {
1411
1098
  return { ok: true, payload: { commitPush: { action: 'committed-pushed' } } };
1412
1099
  }
1413
1100
 
1414
- /** Pipeline driver — threads accumulated state through each phase. */
1415
1101
  export async function runPipeline(phases) {
1416
1102
  let state = {};
1417
1103
  for (const phase of phases) {
@@ -1423,9 +1109,6 @@ export async function runPipeline(phases) {
1423
1109
  }
1424
1110
 
1425
1111
  export async function main(argv = process.argv.slice(2), deps = {}) {
1426
- // `deps.phases` lets tests inject a substitute pipeline so the
1427
- // post-pipeline GitHub-failure detection can be exercised
1428
- // deterministically without spawning `gh` (Story #3898).
1429
1112
  const phases = deps.phases ?? [
1430
1113
  () => parseAndValidate(argv),
1431
1114
  (s) => prepareContext(s),
@@ -1442,12 +1125,8 @@ export async function main(argv = process.argv.slice(2), deps = {}) {
1442
1125
  const result = await runPipeline(phases);
1443
1126
  if (!result.ok) return result.exit;
1444
1127
 
1445
- // GitHub-side bootstrap failures are non-fatal to the pipeline (so the
1446
- // ledger still records the project-side mutations that already landed —
1447
- // the failure is surfaced, not silently rolled back), but they MUST NOT
1448
- // exit 0. `executeGithubBootstrap` records `report.github.error` instead
1449
- // of throwing; detect it here and exit non-zero with a distinct final
1450
- // status line so `mandrel init` and CI see the failure (Story #3898).
1128
+ // A GitHub failure is non-fatal to the pipeline (the ledger still records
1129
+ // what landed) but MUST NOT exit 0.
1451
1130
  const githubError = result.state?.report?.github?.error;
1452
1131
  if (githubError) {
1453
1132
  Logger.error(