@event4u/agent-config 15.0.0 → 16.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/.augment-plugin/marketplace.json +3 -3
  2. package/.augment-plugin/plugin.json +1 -1
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/CHANGELOG.md +301 -347
  5. package/CONTRIBUTING.md +9 -0
  6. package/README.md +2 -2
  7. package/dist/agent-src/commands/analyze/inbox.md +26 -0
  8. package/dist/agent-src/commands/analyze/roadmap-repos.md +27 -0
  9. package/dist/agent-src/commands/challenge-me/closure.md +178 -0
  10. package/dist/agent-src/commands/challenge-me.md +9 -2
  11. package/dist/agent-src/commands/council/default.md +25 -5
  12. package/dist/agent-src/commands/feature/plan.md +28 -1
  13. package/dist/agent-src/commands/feature/roadmap.md +28 -1
  14. package/dist/agent-src/commands/implement-ticket.md +27 -0
  15. package/dist/agent-src/commands/jira-ticket.md +27 -0
  16. package/dist/agent-src/commands/pr/create.md +29 -0
  17. package/dist/agent-src/commands/pr/merge.md +60 -9
  18. package/dist/agent-src/commands/roadmap/ai-council.md +7 -1
  19. package/dist/agent-src/commands/roadmap/create.md +77 -29
  20. package/dist/agent-src/commands/roadmap/materialize.md +27 -0
  21. package/dist/agent-src/commands/roadmap/process-full.md +123 -18
  22. package/dist/agent-src/commands/team.md +22 -0
  23. package/dist/agent-src/contexts/authority/scope-growth-ownership.md +80 -0
  24. package/dist/agent-src/contexts/communication/rules-auto/user-interaction-mechanics.md +97 -0
  25. package/dist/agent-src/contexts/execution/auto-orchestration-activation.md +44 -3
  26. package/dist/agent-src/contexts/execution/autonomy-mechanics.md +15 -15
  27. package/dist/agent-src/contexts/execution/decision-closure-execution.md +93 -0
  28. package/dist/agent-src/contexts/execution/fix-loop-ladder.md +108 -0
  29. package/dist/agent-src/contexts/execution/plan-confidence-gate.md +4 -2
  30. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +75 -6
  31. package/dist/agent-src/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  32. package/dist/agent-src/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  33. package/dist/agent-src/guidelines/design-fidelity-routing.md +29 -0
  34. package/dist/agent-src/rules/autonomous-execution.md +15 -8
  35. package/dist/agent-src/rules/delegation-policy.md +23 -45
  36. package/dist/agent-src/rules/design-fidelity.md +32 -37
  37. package/dist/agent-src/rules/evaluator-independence.md +43 -49
  38. package/dist/agent-src/rules/test-first.md +41 -0
  39. package/dist/agent-src/rules/user-interaction.md +31 -30
  40. package/dist/agent-src/skills/accessibility-auditor/data/manifest.json +3 -3
  41. package/dist/agent-src/skills/ai-council/SKILL.md +11 -3
  42. package/dist/agent-src/skills/api-design/data/manifest.json +3 -3
  43. package/dist/agent-src/skills/database/data/manifest.json +4 -4
  44. package/dist/agent-src/skills/database/data/query-tuning.csv +3 -3
  45. package/dist/agent-src/skills/design-review/SKILL.md +50 -0
  46. package/dist/agent-src/skills/error-handling-patterns/SKILL.md +9 -0
  47. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +14 -4
  48. package/dist/agent-src/skills/experiment-loop/SKILL.md +31 -1
  49. package/dist/agent-src/skills/roadmap-writing/SKILL.md +1 -1
  50. package/dist/agent-src/skills/storybook-workshop/SKILL.md +42 -3
  51. package/dist/agent-src/skills/threat-modeling/SKILL.md +9 -4
  52. package/dist/agent-src/skills/threat-modeling/data/manifest.json +4 -4
  53. package/dist/agent-src/skills/verify-repair-loop/SKILL.md +37 -3
  54. package/dist/agent-src/templates/agent-settings.md +1 -1
  55. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  56. package/dist/agent-src/templates/roadmaps.md +188 -0
  57. package/dist/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  58. package/dist/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  59. package/dist/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  60. package/dist/cli-delegate/check_update_banner.js +40 -2
  61. package/dist/cli-delegate/chunk-4E2W63DA.js +335 -0
  62. package/dist/cli-delegate/chunk-5R7HOLAF.js +99 -0
  63. package/dist/cli-delegate/{chunk-IVBPRCQO.js → chunk-6KFEC3G7.js} +1 -1
  64. package/dist/cli-delegate/{chunk-2TAQ2K4V.js → chunk-6KM6ORRY.js} +55 -386
  65. package/dist/cli-delegate/{chunk-2XY7ILBT.js → chunk-FC75PGJE.js} +42 -2
  66. package/dist/cli-delegate/{chunk-GYC3VRYN.js → chunk-FXYUYU4N.js} +57 -13
  67. package/dist/cli-delegate/{chunk-55ACLDUE.js → chunk-GJCBB2UG.js} +168 -10
  68. package/dist/cli-delegate/{chunk-AK6HODNQ.js → chunk-HDVVGPQW.js} +873 -539
  69. package/dist/cli-delegate/chunk-NUHLI2RX.js +80 -0
  70. package/dist/cli-delegate/{chunk-HZ52BRGG.js → chunk-P6ZHP5W2.js} +15 -90
  71. package/dist/cli-delegate/{chunk-TYSY33MD.js → chunk-QJWAUMJW.js} +12 -2
  72. package/dist/cli-delegate/{chunk-57PN4GYJ.js → chunk-RGNIWTEA.js} +1 -1
  73. package/dist/cli-delegate/chunk-ROYYTEZU.js +39 -0
  74. package/dist/cli-delegate/{chunk-2KKXJW25.js → chunk-S3VFXMTM.js} +1 -1
  75. package/dist/cli-delegate/{chunk-3FKR64R5.js → chunk-UNCRJBT3.js} +31 -7
  76. package/dist/cli-delegate/{chunk-2DK2VJWG.js → chunk-WGXTVKCQ.js} +20 -6
  77. package/dist/cli-delegate/chunk-YDPILCOL.js +152 -0
  78. package/dist/cli-delegate/cmd_analyze_session.js +1 -1
  79. package/dist/cli-delegate/cmd_brand_status.js +1 -1
  80. package/dist/cli-delegate/cmd_conformance.js +918 -325
  81. package/dist/cli-delegate/cmd_doctor.js +7 -5
  82. package/dist/cli-delegate/cmd_explain.js +5 -3
  83. package/dist/cli-delegate/cmd_export.js +9 -7
  84. package/dist/cli-delegate/cmd_fleet.js +4 -2
  85. package/dist/cli-delegate/cmd_handoff.js +6 -6
  86. package/dist/cli-delegate/cmd_mcp_available.js +1 -1
  87. package/dist/cli-delegate/cmd_migrate.js +2 -2
  88. package/dist/cli-delegate/cmd_packs_active.js +3 -2
  89. package/dist/cli-delegate/cmd_preflight.js +4 -2
  90. package/dist/cli-delegate/cmd_prune.js +10 -8
  91. package/dist/cli-delegate/cmd_route_audit.js +2 -2
  92. package/dist/cli-delegate/cmd_route_explain.js +1 -1
  93. package/dist/cli-delegate/cmd_session_recycle.js +4 -4
  94. package/dist/cli-delegate/cmd_settings_get.js +28 -2
  95. package/dist/cli-delegate/cmd_settings_migrate.js +9 -7
  96. package/dist/cli-delegate/cmd_settings_set.js +14 -1
  97. package/dist/cli-delegate/cmd_sync.js +10 -8
  98. package/dist/cli-delegate/cmd_uninstall.js +16 -13
  99. package/dist/cli-delegate/cmd_update.js +1 -1
  100. package/dist/cli-delegate/cmd_upgrade.js +1 -1
  101. package/dist/cli-delegate/cmd_validate.js +12 -10
  102. package/dist/cli-delegate/cmd_versions.js +1 -1
  103. package/dist/discovery/deprecation-report.md +1 -1
  104. package/dist/discovery/discovery-manifest.json +87 -40
  105. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  106. package/dist/discovery/discovery-manifest.summary.md +4 -4
  107. package/dist/discovery/dormancy-report.md +1 -1
  108. package/dist/discovery/orphan-report.md +1 -1
  109. package/dist/discovery/packs.json +10 -8
  110. package/dist/discovery/trust-report.md +3 -3
  111. package/dist/discovery/workspaces.json +8 -6
  112. package/dist/hooks/dispatch.js +2601 -1073
  113. package/dist/install/claudeRuleRewrite.js +14 -3
  114. package/dist/install/conflict.js +60 -10
  115. package/dist/install/conflictTracker.js +218 -0
  116. package/dist/install/fsPrimitives.js +54 -0
  117. package/dist/install/install.mjs +2008 -1481
  118. package/dist/install/manifestFiles.js +259 -0
  119. package/dist/install/preflight.js +14 -2
  120. package/dist/install/preserve.js +157 -0
  121. package/dist/install/recordedOwnership.js +132 -0
  122. package/dist/install/txlog.js +11 -2
  123. package/dist/mcp/registry-manifest.json +3 -3
  124. package/dist/mcp/server.json +2 -2
  125. package/dist/mcp/server.mjs +1612 -667
  126. package/dist/router.json +1 -1
  127. package/dist/scripts/_lib/agent_settings.js +3 -2
  128. package/dist/scripts/_lib/fs_atomic.js +167 -0
  129. package/dist/scripts/_lib/installed_lock.js +1 -1
  130. package/dist/scripts/_lib/installed_tools.js +460 -0
  131. package/dist/scripts/_lib/lean_projection_mode.js +3 -2
  132. package/dist/scripts/_lib/settings_renamed_keys.js +78 -0
  133. package/dist/server/io/yamlIO.js +50 -0
  134. package/dist/server/routes/install.js +8 -0
  135. package/dist/server/routes/wizard.js +9 -3
  136. package/dist/server/schemas/settings.js +17 -5
  137. package/dist/shared/missionExecution.js +97 -0
  138. package/dist/ui/assets/{index-D0jaCRPM.js → index-DH1xc62v.js} +17 -17
  139. package/dist/ui/index.html +1 -1
  140. package/docs/MIGRATION.md +103 -0
  141. package/docs/contracts/settings-classes.md +26 -7
  142. package/docs/guidelines/agent-infra/active-remediation-mechanics.md +57 -0
  143. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +102 -0
  144. package/docs/guidelines/design-fidelity-routing.md +29 -0
  145. package/package.json +1 -1
  146. package/src/agent-src/templates/scripts/work_engine/directives/backend/_self_fix.ts +62 -2
  147. package/src/agent-src/templates/scripts/work_engine/directives/backend/test.ts +1 -0
  148. package/src/agent-src/templates/scripts/work_engine/directives/backend/verify.ts +1 -0
  149. package/src/config/agent-settings.template.yml +139 -27
  150. package/src/config/auto-rule-budget.json +16 -0
  151. package/src/config/ci-local-parity.yml +18 -5
  152. package/src/config/continuity-surface.json +28 -0
  153. package/src/config/gate-coverage.yml +146 -13
  154. package/src/config/gate-violation-baselines.json +6 -6
  155. package/src/config/hook-token-budget.json +2 -0
  156. package/src/config/host-injection-effect.json +1 -1
  157. package/src/config/loop-surfaces.yaml +215 -0
  158. package/src/config/platform-anchor.json +3 -2
  159. package/src/config/preamble-payload-budget.json +12 -7
  160. package/src/config/preamble-payload-exceptions.json +28 -0
  161. package/src/config/release-gate-locality.yml +11 -0
  162. package/src/config/routing-coverage-seed.json +18 -4
  163. package/src/config/rule-enforcement-baseline.json +0 -1
  164. package/src/install/claudeRuleRewrite.ts +16 -2
  165. package/src/install/conflict.ts +65 -9
  166. package/src/install/conflictTracker.ts +299 -0
  167. package/src/install/fsPrimitives.ts +54 -0
  168. package/src/install/manifestFiles.ts +312 -0
  169. package/src/install/preflight.ts +16 -2
  170. package/src/install/preserve.ts +205 -0
  171. package/src/install/recordedOwnership.ts +149 -0
  172. package/src/install/txlog.ts +11 -2
  173. package/src/install/types.ts +19 -4
  174. package/src/scripts/_cli/cmd_conformance.ts +88 -15
  175. package/src/scripts/_cli/cmd_doctor.ts +4 -3
  176. package/src/scripts/_cli/cmd_route_explain.ts +9 -2
  177. package/src/scripts/_cli/cmd_settings_get.ts +44 -0
  178. package/src/scripts/_cli/doctor_execution.ts +90 -0
  179. package/src/scripts/_dispatch.bash +3 -1
  180. package/src/scripts/_lib/activation_payload.ts +247 -0
  181. package/src/scripts/_lib/agent_settings.ts +4 -2
  182. package/src/scripts/_lib/authority_path.ts +102 -0
  183. package/src/scripts/_lib/base_ref_payload.ts +315 -0
  184. package/src/scripts/_lib/cascade_base.ts +94 -0
  185. package/src/scripts/_lib/changelog_eras.ts +7 -2
  186. package/src/scripts/_lib/continuation_ladder.ts +149 -2
  187. package/src/scripts/_lib/council_transport.ts +129 -0
  188. package/src/scripts/_lib/delivery_ready.ts +112 -0
  189. package/src/scripts/_lib/dropped_decision.ts +142 -0
  190. package/src/scripts/_lib/forge_protection.ts +267 -0
  191. package/src/scripts/_lib/hook_platform_keys.ts +27 -0
  192. package/src/scripts/_lib/installed_lock.ts +1 -1
  193. package/src/scripts/_lib/json_python_parity.ts +127 -0
  194. package/src/scripts/_lib/lean_projection_mode.ts +14 -3
  195. package/src/scripts/_lib/loop_surfaces.ts +382 -0
  196. package/src/scripts/_lib/measured_payload_ceiling.ts +424 -0
  197. package/src/scripts/_lib/mission_record.ts +190 -0
  198. package/src/scripts/_lib/obligation_frequency.ts +217 -0
  199. package/src/scripts/_lib/obligations.ts +402 -0
  200. package/src/scripts/_lib/orchestration_record.ts +11 -20
  201. package/src/scripts/_lib/payload_catalogue_completeness.ts +211 -0
  202. package/src/scripts/_lib/release_findings_ingest.ts +324 -0
  203. package/src/scripts/_lib/release_highlights.ts +199 -10
  204. package/src/scripts/_lib/release_holds.ts +493 -0
  205. package/src/scripts/_lib/release_migration_gate.ts +184 -0
  206. package/src/scripts/_lib/release_tag_dispatch.ts +63 -0
  207. package/src/scripts/_lib/review_baseline.ts +254 -0
  208. package/src/scripts/_lib/review_skipped_record.ts +61 -1
  209. package/src/scripts/_lib/rides_along.ts +102 -0
  210. package/src/scripts/_lib/settings_renamed_keys.ts +82 -0
  211. package/src/scripts/_lib/standing_bound_ratchet.ts +216 -103
  212. package/src/scripts/_lib/test_delta.ts +166 -0
  213. package/src/scripts/_lib/test_provenance.ts +171 -0
  214. package/src/scripts/_lib/turn_end_refusals.ts +51 -4
  215. package/src/scripts/_lib/typed_op_grant.ts +246 -0
  216. package/src/scripts/_lib/typed_op_watch.ts +185 -0
  217. package/src/scripts/ai_council/config.ts +8 -11
  218. package/src/scripts/ai_council/fallback_config.ts +5 -3
  219. package/src/scripts/ai_council/ownership_classes.ts +118 -0
  220. package/src/scripts/ask_block_census.ts +285 -15
  221. package/src/scripts/check_beta_review_markers.ts +35 -4
  222. package/src/scripts/check_enforcement_matrix.ts +624 -0
  223. package/src/scripts/check_finding_dispositions.ts +167 -16
  224. package/src/scripts/check_gate_reachability.ts +173 -10
  225. package/src/scripts/check_generator_sync.ts +954 -0
  226. package/src/scripts/check_held_object_arrivals.ts +381 -0
  227. package/src/scripts/check_preamble_payload_budget.ts +474 -124
  228. package/src/scripts/check_release_highlights.ts +33 -1
  229. package/src/scripts/check_release_holds.ts +567 -0
  230. package/src/scripts/check_release_published.ts +1 -1
  231. package/src/scripts/check_reply_consistency.ts +86 -17
  232. package/src/scripts/check_rule_projection_integrity.ts +22 -12
  233. package/src/scripts/check_test_delta.ts +294 -0
  234. package/src/scripts/check_test_weakening.ts +299 -0
  235. package/src/scripts/closure_scan.ts +333 -0
  236. package/src/scripts/compile_hook_manifest.ts +43 -3
  237. package/src/scripts/council_record_shape.ts +209 -0
  238. package/src/scripts/hook_manifest.json +1 -1
  239. package/src/scripts/hook_manifest.yaml +127 -12
  240. package/src/scripts/hooks/block_kernel_rule_writes.ts +12 -2
  241. package/src/scripts/hooks/concern_registry.ts +6 -0
  242. package/src/scripts/hooks/design_pass_hook.ts +128 -3
  243. package/src/scripts/hooks/end_review_nudge_hook.ts +101 -21
  244. package/src/scripts/hooks/evidence_independence.ts +96 -0
  245. package/src/scripts/hooks/memory_recall_hook.ts +540 -0
  246. package/src/scripts/hooks/obligation_settle_hook.ts +182 -0
  247. package/src/scripts/hooks/review_baseline_hook.ts +130 -0
  248. package/src/scripts/hooks/rule_inject_hook.ts +49 -1
  249. package/src/scripts/hooks/run_continuation_hook.ts +17 -20
  250. package/src/scripts/hooks/turn_end_gate_hook.ts +232 -14
  251. package/src/scripts/hooks_doctor.ts +89 -1
  252. package/src/scripts/hooks_status.ts +19 -0
  253. package/src/scripts/install.ts +107 -207
  254. package/src/scripts/interruption_report.ts +8 -2
  255. package/src/scripts/janitor.ts +15 -1
  256. package/src/scripts/lint_decision_classes.ts +464 -0
  257. package/src/scripts/lint_hook_manifest.ts +11 -0
  258. package/src/scripts/lint_major_migration_sections.ts +450 -0
  259. package/src/scripts/lint_plan_risk_register.ts +47 -3
  260. package/src/scripts/lint_roadmap_blockers.ts +61 -0
  261. package/src/scripts/lint_roadmap_producers.ts +202 -0
  262. package/src/scripts/measure_rule_budget.ts +101 -5
  263. package/src/scripts/measure_turn_end_gate.ts +302 -5
  264. package/src/scripts/new_roadmap.ts +37 -0
  265. package/src/scripts/orchestration_record.ts +0 -5
  266. package/src/scripts/release.ts +66 -162
  267. package/src/scripts/release_drill.ts +460 -15
  268. package/src/scripts/release_env.ts +1 -1
  269. package/src/scripts/release_publication.ts +52 -1
  270. package/src/scripts/report_enforcement_drift.ts +566 -0
  271. package/src/scripts/report_held_object_arrivals.ts +456 -0
  272. package/src/scripts/report_host_injection_effect.ts +3 -11
  273. package/src/scripts/report_standing_payload_by_host.ts +26 -152
  274. package/src/scripts/schemas/agent-settings.schema.json +23 -0
  275. package/src/scripts/schemas/command.schema.json +4 -0
  276. package/src/scripts/scope_growth.ts +219 -0
  277. package/src/scripts/sync_agent_settings.ts +140 -18
  278. package/src/scripts/trigger_eval_grandfather.json +0 -1
  279. package/src/scripts/ui_conformance_probe.ts +622 -0
  280. package/src/server/io/yamlIO.ts +48 -0
  281. package/src/server/schemas/settings.ts +31 -7
  282. package/src/shared/missionExecution.ts +126 -0
  283. package/dist/cli-delegate/chunk-523HCFYO.js +0 -90
@@ -30,21 +30,21 @@
30
30
  * 3. Confirm — show preview, ask once (skippable with --yes;
31
31
  * `--ci` always needs --yes — CI has no terminal).
32
32
  * 4. Branch + bump — create `release/X.Y.Z`, update package.json,
33
- * .claude-plugin/marketplace.json, CHANGELOG.md,
34
- * then run `task release-prepare` so pack
35
- * manifests and tool projections pick up the
36
- * new version (otherwise the PR's own consistency
37
- * check fails — see PR #226 post-mortem).
33
+ * marketplace.json and CHANGELOG.md, then run
34
+ * `task release-prepare` so pack manifests and tool
35
+ * projections pick up the new version (skip it and
36
+ * the PR's own consistency check fails — PR #226).
38
37
  * 5. Commit + push — `release: X.Y.Z`, push branch, open PR.
39
38
  * 6. Wait for CI — `gh pr checks --watch` (skippable with --no-wait).
40
- * 7. Merge — `gh pr merge --merge --delete-branch`.
41
- * 8. Tag main — fast-forward main, tag the merge commit, push
42
- * the tag (triggers publish-npm.yml — except
43
- * under `--ci`, see step 9).
44
- * 9. GitHub Release — `gh release create X.Y.Z --notes <changelog>`;
45
- * under `--ci`, also dispatches
46
- * release-guard.yml + publish-npm.yml +
47
- * cloud-release.yml explicitly.
39
+ * 7. Findings ledger — VERIFY it is on the branch and dispositioned, and
40
+ * STOP otherwise; `self-review-gate.yml` builds it.
41
+ * 8. Merge — `gh pr merge --merge --delete-branch`.
42
+ * 9. Tag main — fast-forward main, tag the merge commit, push the
43
+ * tag (triggers publish-npm.yml, except under --ci).
44
+ * 10. GitHub Release — `gh release create X.Y.Z --notes <changelog>`; under
45
+ * `--ci`, also dispatches release-guard.yml,
46
+ * publish-npm.yml and cloud-release.yml explicitly.
47
+ * 11. Cleanup — delete the merged release branch, local + remote.
48
48
  *
49
49
  * Idempotency: pass `--resume` to recover from a partial failure. Each
50
50
  * step then probes existing state (branch, commit, PR, tag, GitHub
@@ -122,12 +122,12 @@ import {
122
122
  import {
123
123
  HEAD_LABELS,
124
124
  type MixObligation,
125
- collect_span_commits,
126
- derive_category_hits,
127
- render_derived_head_values,
125
+ derive_head_prefill,
128
126
  } from './_lib/release_highlights.js';
129
127
  import { canPrompt, promptLine } from './_lib/tty_prompt.js';
130
128
  import { preflightPosition } from './_lib/release_position.js';
129
+ import { settleFindingsLedger } from './_lib/release_findings_ingest.js';
130
+ import { TAG_TRIGGERED_WORKFLOWS, dispatchTagWorkflows } from './_lib/release_tag_dispatch.js';
131
131
  import {
132
132
  RELEASE_HEAD_DEFAULT,
133
133
  extract_changelog_section,
@@ -135,6 +135,11 @@ import {
135
135
  release_notes_from_section,
136
136
  render_mix_response,
137
137
  } from './_lib/release_material.js';
138
+ import {
139
+ assert_major_migration_section,
140
+ assert_scheduled_deprecations_clear,
141
+ } from './_lib/release_migration_gate.js';
142
+ import { releaseHoldPreflight } from './_lib/release_holds.js';
138
143
 
139
144
  // `__doc__.splitlines()[0]` in `_parse_args` — the argparse description. Kept
140
145
  // as a referenceable constant so the first docstring line is preserved exactly.
@@ -142,7 +147,6 @@ const MODULE_DOC_FIRST_LINE = 'End-to-end release automation for `event4u/agent-
142
147
 
143
148
  const _HERE = fileURLToPath(import.meta.url);
144
149
 
145
-
146
150
  import {
147
151
  ArgparseExit,
148
152
  AUGMENT_MARKETPLACE_JSON,
@@ -167,7 +171,6 @@ import {
167
171
  _rstrip,
168
172
  _splitlines,
169
173
  } from './release_env.js';
170
- import type { RunResult } from './release_publication.js';
171
174
  // Re-export surface for the names tests import from `release.js` and that moved
172
175
  // into the publication unit — eleven since the test-count-trend unit followed. `export ... from` rather than a bare import,
173
176
  // because these are not USED here — an unused import would be dropped and the
@@ -224,7 +227,6 @@ import {
224
227
  // existing block resolve. This is the whole of step 1.1's "re-export shape that
225
228
  // keeps callers unaffected": no caller and no test import path changes.
226
229
 
227
-
228
230
  // ---------------------------------------------------------------------------
229
231
  // Parity helpers — code-point length, comma grouping, regex escape, JSON
230
232
  // ---------------------------------------------------------------------------
@@ -302,8 +304,7 @@ export { RELEASE_HEAD_CAP_LINES } from './_lib/release_material.js';
302
304
  */
303
305
  function _derive_head_prefill(prev: string | null): Record<string, string> {
304
306
  try {
305
- const span = collect_span_commits(prev, 'HEAD', REPO_ROOT);
306
- return render_derived_head_values(derive_category_hits(span));
307
+ return derive_head_prefill(prev, 'HEAD', REPO_ROOT);
307
308
  } catch (err) {
308
309
  process.stderr.write(
309
310
  `warning: could not derive release-head highlights (${(err as Error).message}); ` +
@@ -696,93 +697,6 @@ function set_template_pin(p: string, version: string): void {
696
697
  fs.writeFileSync(p, lines.join('\n'), 'utf-8');
697
698
  }
698
699
 
699
- /**
700
- * Refuse a MAJOR cut that carries a scheduled deprecation due at or before it.
701
- *
702
- * **The trigger is the shape of the TARGET, not a comparison with the current
703
- * version.** A major target is `X.0.0` — and that one predicate covers every
704
- * path to a major: the `--as major` flag, an explicit `--version 13.0.0`,
705
- * auto-detection from a `feat!:` commit, AND `--resume`, where
706
- * `_detect_in_flight_target()` returns the already-bumped `package.json`
707
- * version so `target === current` and any current-vs-target comparison
708
- * silently returns. Resume was the fourth path an earlier version of this
709
- * guard missed while its own comment claimed three paths converged.
710
- *
711
- * Refusing a resumed release can strand a partially-completed one, and that is
712
- * the deliberate trade: a stranded release is recoverable by fixing the table
713
- * and resuming again, whereas a major shipped over a missed commitment is the
714
- * failure this whole surface exists to prevent.
715
- *
716
- * The target version is PASSED to the gate. Without it the gate falls back to
717
- * `package.json`, which at the cut to N still reads N-1 — so a row committed
718
- * to N reads as one major early and passes, and only rows already a major late
719
- * could ever be refused. That is the lateness being prevented, so measuring
720
- * against the shipped version would have made the refusal fire exactly one
721
- * major too late, forever.
722
- *
723
- * Runs under `--dry-run` too, unlike the rest of preflight: this check is one
724
- * subprocess reading two files, so the "keep a preview fast" rationale that
725
- * excludes the ~15s test-trend collection does not apply — and a preview that
726
- * reports green for the single condition that will refuse the real run is the
727
- * case an operator runs a preview to discover. It REPORTS there rather than
728
- * dying: `--dry-run` exiting 0 before `execute()` and before `preflight()` is a
729
- * contract this file's own tests assert, and an earlier revision of this guard
730
- * broke it by sitting above the dry-run branch with no preview mode.
731
- *
732
- * @param runner Seam for the gate invocation. Production passes nothing and
733
- * gets the real `run`; tests inject a stub, because the alternative — reaching
734
- * this branch only by mutating `docs/MIGRATION.md` — would make the refusal
735
- * path testable exclusively through a tracked-file edit.
736
- */
737
- export function assert_scheduled_deprecations_clear(
738
- target: string,
739
- runner: (args: readonly string[]) => RunResult = (args) => run(args, { check: false, capture: true }),
740
- opts: { previewOnly?: boolean } = {},
741
- ): void {
742
- const [, minor, patch] = parse_version(target);
743
- if (minor !== 0 || patch !== 0) {
744
- return;
745
- }
746
- const res = runner([
747
- './scripts-run',
748
- 'src/scripts/lint_scheduled_deprecations',
749
- '--cutting',
750
- target,
751
- ]);
752
- if (res.returncode === 0) {
753
- return;
754
- }
755
- process.stderr.write(res.stdout);
756
- process.stderr.write(res.stderr);
757
- if (res.returncode !== 1) {
758
- // The gate reserves 1 for a finding and 2 for a usage/environment
759
- // failure. Diagnosing the latter as "the table has an overdue row"
760
- // sends the releaser to edit a file that is not the problem.
761
- die(
762
- `refusing the ${target} cut: the scheduled-deprecations check could not run ` +
763
- `(exit ${String(res.returncode)}). That is an environment or usage failure, not a ` +
764
- 'finding in docs/MIGRATION.md — fix the invocation or the checkout, then re-run.',
765
- );
766
- }
767
- if (opts.previewOnly === true) {
768
- // The preview's job is to SHOW what the real run will refuse. Dying
769
- // here would break the `--dry-run exits 0` contract asserted elsewhere
770
- // in this file's tests — trading a documented exit code for a message
771
- // that has already been printed above.
772
- process.stderr.write(
773
- `\n(dry-run) the ${target} cut WOULD BE REFUSED for the reason above. ` +
774
- 'Previewing only; exit code unchanged.\n',
775
- );
776
- return;
777
- }
778
- die(
779
- `refusing the ${target} cut: the scheduled-deprecations table in docs/MIGRATION.md ` +
780
- 'has a row due at or before this major, or one that cannot be resolved. Act on ' +
781
- "it — perform the removal in its own change, or revise the row's commitment and " +
782
- 'record why the surface stays — then re-run.',
783
- );
784
- }
785
-
786
700
  // ─── preflight ────────────────────────────────────────────────────────────────
787
701
 
788
702
  /**
@@ -858,7 +772,7 @@ function preflight(target: string, opts: { resume?: boolean; ci?: boolean } = {}
858
772
  // The local-in-sync-with-origin check only applies to main; if we're
859
773
  // already on the release branch in resume mode, the relevant invariant
860
774
  // is "main hasn't moved beyond what release/X.Y.Z branched off", which
861
- // `git pull --ff-only` enforces in step 8 anyway.
775
+ // `git pull --ff-only` enforces in step 9 anyway.
862
776
  if (branch === MAIN_BRANCH) {
863
777
  const local = git(['rev-parse', 'HEAD'], { capture: true });
864
778
  const remote = git(['rev-parse', `${REMOTE}/${MAIN_BRANCH}`], { capture: true });
@@ -876,6 +790,7 @@ function preflight(target: string, opts: { resume?: boolean; ci?: boolean } = {}
876
790
  die(`tag '${target}' already exists; nothing to release`);
877
791
  }
878
792
  }
793
+ releaseHoldPreflight(REPO_ROOT, die);
879
794
  }
880
795
 
881
796
  // ─── plan ─────────────────────────────────────────────────────────────────────
@@ -972,7 +887,7 @@ export function confirmGate(target: string, yes: boolean): ConfirmVerdict {
972
887
  return { proceed: true };
973
888
  }
974
889
 
975
- // ─── orchestration ────────────────────────────────────────────────────────────
890
+ // Orchestration.
976
891
 
977
892
  function _step(n: number, total: number, msg: string): void {
978
893
  process.stdout.write(`[${n}/${total}] ${msg}\n`);
@@ -988,7 +903,7 @@ function execute(
988
903
  const ci = opts.ci ?? false;
989
904
 
990
905
  const branch = `release/${plan.target}`;
991
- const total = 10;
906
+ const total = 11;
992
907
 
993
908
  if (dry_run) {
994
909
  process.stdout.write('(dry-run) no git/gh mutations will be performed.\n');
@@ -1000,12 +915,12 @@ function execute(
1000
915
  const pr_state = pr_info ? pr_info['state'] : undefined;
1001
916
  const pr_merged = pr_state === 'MERGED';
1002
917
 
1003
- // ─── 1. branch ──────────────────────────────────────────────────────────
918
+ // Step 1 — branch
1004
919
  checkout_release_branch(branch, pr_merged, (m) => {
1005
920
  _step(1, total, m);
1006
921
  });
1007
922
 
1008
- // ─── 1b. era split (optional, separate commit) ─────────────────────────
923
+ // Step 1b — era split (optional, separate commit)
1009
924
  // Lands as `chore(changelog): split era ...` BEFORE the release commit
1010
925
  // so the split is reviewable on its own and the release commit only
1011
926
  // touches the bump + new entry. Idempotent: archive already on disk
@@ -1038,7 +953,7 @@ function execute(
1038
953
  }
1039
954
  }
1040
955
 
1041
- // ─── 2. file mutations ──────────────────────────────────────────────────
956
+ // Step 2 — file mutations
1042
957
  if (pr_merged) {
1043
958
  _step(2, total, 'PR already merged — skip file bumps');
1044
959
  } else {
@@ -1074,7 +989,7 @@ function execute(
1074
989
 
1075
990
  guard_release_curation(plan.target, pr_merged);
1076
991
 
1077
- // ─── 3. commit ──────────────────────────────────────────────────────────
992
+ // Step 3 — commit
1078
993
  if (pr_merged) {
1079
994
  _step(3, total, 'PR already merged — skip commit');
1080
995
  } else {
@@ -1107,10 +1022,10 @@ function execute(
1107
1022
  if (pr_merged) {
1108
1023
  _step(4, total, 'PR already merged — skip push');
1109
1024
  } else {
1110
- // `git push -u` is naturally idempotent — it prints "Everything
1111
- // up-to-date" when remote already matches. push_release_branch
1112
- // additionally absorbs a remote that moved under us.
1113
- // Not a `_step`: a second `[4/10]` makes the cited evidence anchors ambiguous.
1025
+ // push_release_branch reads the remote FIRST — it skips the push when
1026
+ // the remote is already at head (a no-op push still runs the pre-push
1027
+ // hook, which then refuses over pending CI) and merges one that moved.
1028
+ // Not a `_step`: a second `[4/11]` makes the cited evidence anchors ambiguous.
1114
1029
  process.stdout.write(' · verifying release gates locally (`task release:verify -- --cheap`)\n');
1115
1030
  run(local_release_gate_argv());
1116
1031
 
@@ -1147,7 +1062,7 @@ function execute(
1147
1062
  '--title', `release: ${plan.target}`, '--body', pr_body]);
1148
1063
  }
1149
1064
 
1150
- // ─── 6. wait for checks ─────────────────────────────────────────────────
1065
+ // Step 6 — wait for checks
1151
1066
  if (pr_merged) {
1152
1067
  _step(6, total, 'PR already merged — skip checks wait');
1153
1068
  } else if (wait_for_checks) {
@@ -1157,17 +1072,23 @@ function execute(
1157
1072
  _step(6, total, 'Skip waiting for checks (--no-wait)');
1158
1073
  }
1159
1074
 
1160
- // ─── 7. merge ───────────────────────────────────────────────────────────
1075
+ // Step 7 — the findings ledger: verify, never produce; the module says why.
1076
+ settleFindingsLedger({
1077
+ run, die, repoRoot: REPO_ROOT, remote: REMOTE, trunk: MAIN_BRANCH,
1078
+ step: (m) => { _step(7, total, m); }, write: (s) => process.stdout.write(s),
1079
+ resolvePr: () => Number((pr_info ?? _pr_for_branch(branch))?.['number'] ?? NaN) || null,
1080
+ }, plan.target, branch, pr_merged);
1081
+ // Step 8 — merge
1161
1082
  if (pr_merged) {
1162
- _step(7, total, `PR #${pr_info!['number']} already merged — skip`);
1083
+ _step(8, total, `PR #${pr_info!['number']} already merged — skip`);
1163
1084
  } else {
1164
- _step(7, total, 'Merge pull request (merge commit) and delete branch');
1085
+ _step(8, total, 'Merge pull request (merge commit) and delete branch');
1165
1086
  merge_release_pr(branch, wait_for_checks);
1166
1087
  }
1167
1088
 
1168
- // ─── 8. tag main + push tag ─────────────────────────────────────────────
1089
+ // Step 9 — tag main + push tag
1169
1090
  // Always idempotent — even outside resume mode this prevents a mid-flight
1170
- // crash on step 9 from leaving a half-tagged release that subsequent
1091
+ // crash on step 10 from leaving a half-tagged release that subsequent
1171
1092
  // `task release` invocations can't recover from without `--resume`.
1172
1093
  if (git(['rev-parse', '--abbrev-ref', 'HEAD'], { capture: true }) !== MAIN_BRANCH) {
1173
1094
  run(['git', 'checkout', MAIN_BRANCH]);
@@ -1176,29 +1097,29 @@ function execute(
1176
1097
 
1177
1098
  if (_tag_exists_local(plan.target)) {
1178
1099
  if (_tag_exists_remote(plan.target)) {
1179
- _step(8, total, `Tag ${plan.target} already on ${REMOTE} — skip`);
1100
+ _step(9, total, `Tag ${plan.target} already on ${REMOTE} — skip`);
1180
1101
  } else {
1181
- _step(8, total, `Tag ${plan.target} exists locally — push only`);
1102
+ _step(9, total, `Tag ${plan.target} exists locally — push only`);
1182
1103
  guard_publication(plan.target, 'tag push (resumed)');
1183
1104
  _push_tag(plan.target);
1184
1105
  }
1185
1106
  } else {
1186
1107
  // Sequencing is load-bearing (release-truth Phase 1, council
1187
- // 2026-08-03): merge FIRST (step 7), pull main (above), THEN derive
1108
+ // 2026-08-03): merge FIRST (step 8), pull main (above), THEN derive
1188
1109
  // the tag message from the MERGED changelog — tagging before the
1189
1110
  // merge would read a section that does not exist yet. The annotated
1190
1111
  // tag replaces the previous lightweight one so tag metadata is a
1191
1112
  // fourth surface carrying the same single-source content.
1192
- _step(8, total, `Tag merge commit (annotated, from merged CHANGELOG) and push ${plan.target}`);
1113
+ _step(9, total, `Tag merge commit (annotated, from merged CHANGELOG) and push ${plan.target}`);
1193
1114
  create_and_push_annotated_tag(plan.target);
1194
1115
  }
1195
1116
 
1196
- // ─── 9. GitHub Release ──────────────────────────────────────────────────
1117
+ // Step 10 — GitHub Release
1197
1118
  if (_release_exists(plan.target)) {
1198
- _step(9, total, `GitHub Release ${plan.target} already exists — skip`);
1119
+ _step(10, total, `GitHub Release ${plan.target} already exists — skip`);
1199
1120
  } else {
1200
1121
  _step(
1201
- 9,
1122
+ 10,
1202
1123
  total,
1203
1124
  ci
1204
1125
  ? 'Create GitHub Release (tag push under GITHUB_TOKEN triggers nothing — dispatching next)'
@@ -1223,7 +1144,7 @@ function execute(
1223
1144
  guard_publication(plan.target, 'GitHub Release notes');
1224
1145
  gh(['release', 'create', plan.target, '--title', plan.target, '--notes', notes]);
1225
1146
 
1226
- // ─── 9b. dispatch-chain the tag-triggered workflows (--ci only) ──────
1147
+ // Step 10b — dispatch-chain the tag-triggered workflows (--ci only)
1227
1148
  // release-guard.yml, publish-npm.yml, and cloud-release.yml all
1228
1149
  // trigger on `push: tags: [0-9]+.[0-9]+.[0-9]+`, but a tag pushed
1229
1150
  // with the default GITHUB_TOKEN does NOT fire other workflows
@@ -1234,41 +1155,21 @@ function execute(
1234
1155
  // branch above), so a --resume re-run never re-dispatches a
1235
1156
  // publish that already happened.
1236
1157
  if (ci) {
1237
- _step(9, total, 'Dispatch release-guard.yml + publish-npm.yml + cloud-release.yml for the tag');
1238
- // NON-FATAL by design. By this point the release is already complete
1239
- // — the tag is pushed and the GitHub Release is created above, and
1240
- // npm publish runs asynchronously. These explicit dispatches are a
1241
- // FALLBACK for a tag pushed with the default GITHUB_TOKEN, which does
1242
- // NOT fire tag-triggered workflows (GitHub's recursion guard). When
1243
- // the tag was pushed with a PAT (RELEASE_PR_TOKEN), those three
1244
- // workflows already fired on the push and this dispatch is redundant.
1245
- // Dispatching via the API additionally needs the token's
1246
- // `actions:write` scope; a 403 here (scope missing) must NOT mark an
1247
- // already-shipped release as failed — warn and continue.
1248
- for (const wf of ['release-guard.yml', 'publish-npm.yml', 'cloud-release.yml']) {
1249
- const r = run(['gh', 'workflow', 'run', wf, '--ref', MAIN_BRANCH, '-f', `tag=${plan.target}`], {
1250
- check: false,
1251
- });
1252
- if (r.returncode !== 0) {
1253
- process.stderr.write(
1254
- `⚠️ Could not dispatch ${wf} (exit ${r.returncode}) — the release ${plan.target} is ` +
1255
- `already complete (tag + GitHub Release created; npm publishes async). If the tag was ` +
1256
- `pushed with a PAT, ${wf} already fired on the tag push. If you rely on the explicit ` +
1257
- `dispatch, grant RELEASE_PR_TOKEN the "Actions: read and write" scope (fine-grained PAT) ` +
1258
- `or the "workflow" scope (classic PAT).\n`,
1259
- );
1260
- }
1261
- }
1158
+ _step(10, total, `Dispatch ${TAG_TRIGGERED_WORKFLOWS.join(' + ')} for the tag`);
1159
+ dispatchTagWorkflows(
1160
+ { run, warn: (s) => process.stderr.write(s), trunk: MAIN_BRANCH },
1161
+ plan.target,
1162
+ );
1262
1163
  }
1263
1164
  }
1264
1165
 
1265
- // ─── 10. delete the merged release branch (local + remote) ───────────────
1166
+ // Step 11 — delete the merged release branch (local + remote)
1266
1167
  // Branch hygiene: a merged-but-undeleted release/X.Y.Z is what made
1267
1168
  // `--resume` mis-detect an old version. Delete it now so it can never
1268
1169
  // accumulate. Idempotent — skips whatever is already gone. Never touches
1269
1170
  // `main` or any tag.
1270
1171
  if (dry_run) {
1271
- _step(10, total, `Would delete merged branch ${branch} (local + remote)`);
1172
+ _step(11, total, `Would delete merged branch ${branch} (local + remote)`);
1272
1173
  } else {
1273
1174
  const deleted: string[] = [];
1274
1175
  if (
@@ -1283,7 +1184,7 @@ function execute(
1283
1184
  deleted.push('remote');
1284
1185
  }
1285
1186
  const where = deleted.length > 0 ? deleted.join(' + ') : 'already gone';
1286
- _step(10, total, `Delete merged branch ${branch} (${where})`);
1187
+ _step(11, total, `Delete merged branch ${branch} (${where})`);
1287
1188
  }
1288
1189
 
1289
1190
  process.stdout.write('\n');
@@ -1292,7 +1193,7 @@ function execute(
1292
1193
  process.stdout.write(' npm publish runs asynchronously via publish-npm.yml on the tag.\n');
1293
1194
  }
1294
1195
 
1295
- // ─── entrypoint ───────────────────────────────────────────────────────────────
1196
+ // Entrypoint.
1296
1197
 
1297
1198
  /** Mirror of `argparse.Namespace` for this CLI. */
1298
1199
  interface Args {
@@ -1685,6 +1586,7 @@ function main(argv: readonly string[] | null = null): number {
1685
1586
  head: _derive_head_prefill(prev),
1686
1587
  mix: measure_mix_obligation(target, prev),
1687
1588
  });
1589
+ assert_major_migration_section(target, full, { previewOnly: args.dry_run });
1688
1590
 
1689
1591
  // Era-split planning — gate on the POST-release view (2026-07-07 fix).
1690
1592
  // The drift test measures the era AFTER this release's section is
@@ -1789,6 +1691,8 @@ export {
1789
1691
  bump_version,
1790
1692
  commits_since,
1791
1693
  infer_bump,
1694
+ assert_major_migration_section,
1695
+ assert_scheduled_deprecations_clear,
1792
1696
  render_changelog_entry,
1793
1697
  _changelog_line,
1794
1698
  _cap_body,