@event4u/agent-config 14.10.0 → 14.12.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 (667) 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 +161 -208
  5. package/README.md +1 -1
  6. package/dist/agent-src/commands/design.md +88 -0
  7. package/dist/agent-src/commands/project/analyze.md +47 -0
  8. package/dist/agent-src/commands/review/changes.md +67 -6
  9. package/dist/agent-src/commands/roadmap/create.md +49 -0
  10. package/dist/agent-src/commands/roadmap/next.md +27 -11
  11. package/dist/agent-src/commands/roadmap/process-full.md +14 -0
  12. package/dist/agent-src/commands/video/from-script.md +60 -3
  13. package/dist/agent-src/commands/video/stitch.md +14 -0
  14. package/dist/agent-src/contexts/communication/rules-auto/guidelines-mechanics.md +1 -0
  15. package/dist/agent-src/contexts/execution/evidence-discipline.md +26 -0
  16. package/dist/agent-src/contexts/execution/roadmap-process-loop.md +154 -2
  17. package/dist/agent-src/rules/active-remediation.md +3 -3
  18. package/dist/agent-src/rules/code-provenance.md +2 -2
  19. package/dist/agent-src/rules/context-hygiene.md +13 -33
  20. package/dist/agent-src/rules/council-availability.md +2 -2
  21. package/dist/agent-src/rules/decision-revisit-gate.md +3 -1
  22. package/dist/agent-src/rules/design-fidelity.md +18 -0
  23. package/dist/agent-src/rules/design-review-after-ui-write.md +2 -2
  24. package/dist/agent-src/rules/evaluator-independence.md +56 -44
  25. package/dist/agent-src/rules/fix-what-you-see.md +9 -1
  26. package/dist/agent-src/rules/framework-neutrality-in-generic-skills.md +1 -1
  27. package/dist/agent-src/rules/minimal-safe-diff.md +14 -20
  28. package/dist/agent-src/rules/missing-skill-recovery.md +13 -1
  29. package/dist/agent-src/rules/playbook-precedence.md +105 -0
  30. package/dist/agent-src/rules/recurring-criticism.md +3 -1
  31. package/dist/agent-src/rules/roadmap-progress-sync.md +14 -13
  32. package/dist/agent-src/rules/scale-discipline.md +24 -0
  33. package/dist/agent-src/rules/security-sensitive-stop.md +2 -2
  34. package/dist/agent-src/rules/settings-ask-protocol.md +2 -2
  35. package/dist/agent-src/rules/ui-audit-gate.md +27 -15
  36. package/dist/agent-src/rules/untrusted-input-defense.md +2 -2
  37. package/dist/agent-src/skills/accessibility-auditor/SKILL.md +19 -0
  38. package/dist/agent-src/skills/adr-create/SKILL.md +7 -0
  39. package/dist/agent-src/skills/agents-md-thin-root/SKILL.md +33 -0
  40. package/dist/agent-src/skills/ai-council/references/advanced-modes.md +17 -3
  41. package/dist/agent-src/skills/ai-council/references/output-and-synthesis.md +31 -0
  42. package/dist/agent-src/skills/ai-council/references/procedure.md +19 -0
  43. package/dist/agent-src/skills/alerting-doctrine/SKILL.md +225 -0
  44. package/dist/agent-src/skills/authz-review/SKILL.md +0 -1
  45. package/dist/agent-src/skills/blast-radius-analyzer/SKILL.md +32 -0
  46. package/dist/agent-src/skills/brand/SKILL.md +3 -0
  47. package/dist/agent-src/skills/brand-asset-generation/SKILL.md +3 -0
  48. package/dist/agent-src/skills/brand-audit/SKILL.md +3 -0
  49. package/dist/agent-src/skills/brand-identity/SKILL.md +3 -0
  50. package/dist/agent-src/skills/brand-strategy/SKILL.md +3 -0
  51. package/dist/agent-src/skills/brand-to-tokens/SKILL.md +3 -0
  52. package/dist/agent-src/skills/check-refs/SKILL.md +3 -0
  53. package/dist/agent-src/skills/code-refactoring/SKILL.md +45 -1
  54. package/dist/agent-src/skills/code-review/SKILL.md +75 -5
  55. package/dist/agent-src/skills/command-routing/SKILL.md +6 -0
  56. package/dist/agent-src/skills/command-writing/SKILL.md +35 -0
  57. package/dist/agent-src/skills/condense-memory/SKILL.md +3 -0
  58. package/dist/agent-src/skills/context-authoring/SKILL.md +1 -1
  59. package/dist/agent-src/skills/conventional-commits-writing/SKILL.md +3 -0
  60. package/dist/agent-src/skills/copilot-agents-optimization/SKILL.md +10 -0
  61. package/dist/agent-src/skills/corpus-grounding/SKILL.md +3 -0
  62. package/dist/agent-src/skills/design-intelligence/SKILL.md +3 -0
  63. package/dist/agent-src/skills/design-intelligence/data/landing.csv +36 -35
  64. package/dist/agent-src/skills/design-intelligence/data/stacks/threejs.csv +1 -0
  65. package/dist/agent-src/skills/design-review/SKILL.md +79 -1
  66. package/dist/agent-src/skills/design-review/references/verification-automation.md +41 -0
  67. package/dist/agent-src/skills/design-system-capture/SKILL.md +35 -40
  68. package/dist/agent-src/skills/design-system-capture/references/import-procedure.md +50 -0
  69. package/dist/agent-src/skills/design-tokens/SKILL.md +3 -0
  70. package/dist/agent-src/skills/design-variations/SKILL.md +3 -0
  71. package/dist/agent-src/skills/developer-like-execution/SKILL.md +3 -0
  72. package/dist/agent-src/skills/estimate-ticket/SKILL.md +3 -0
  73. package/dist/agent-src/skills/existing-ui-audit/SKILL.md +28 -4
  74. package/dist/agent-src/skills/fe-design/SKILL.md +74 -41
  75. package/dist/agent-src/skills/fe-design/references/craft-floor.md +52 -0
  76. package/dist/agent-src/skills/fe-design/references/source-led-port.md +36 -0
  77. package/dist/agent-src/skills/file-editor/SKILL.md +5 -0
  78. package/dist/agent-src/skills/finishing-a-development-branch/SKILL.md +2 -2
  79. package/dist/agent-src/skills/git-workflow/SKILL.md +3 -0
  80. package/dist/agent-src/skills/html-deck/SKILL.md +3 -0
  81. package/dist/agent-src/skills/iconography/SKILL.md +3 -0
  82. package/dist/agent-src/skills/image-editing/SKILL.md +3 -0
  83. package/dist/agent-src/skills/image-generation/SKILL.md +3 -0
  84. package/dist/agent-src/skills/image-provider-routing/SKILL.md +3 -0
  85. package/dist/agent-src/skills/incident-commander/SKILL.md +10 -0
  86. package/dist/agent-src/skills/js-library-packaging/SKILL.md +173 -0
  87. package/dist/agent-src/skills/js-library-packaging/scripts/check_package_surface.ts +270 -0
  88. package/dist/agent-src/skills/laravel-migration/SKILL.md +3 -0
  89. package/dist/agent-src/skills/learning-to-rule-or-skill/SKILL.md +3 -0
  90. package/dist/agent-src/skills/lint-skills/SKILL.md +3 -0
  91. package/dist/agent-src/skills/llm-provider-knowledge/SKILL.md +3 -0
  92. package/dist/agent-src/skills/logging-monitoring/SKILL.md +234 -51
  93. package/dist/agent-src/skills/logo-generation/SKILL.md +3 -0
  94. package/dist/agent-src/skills/md-language-check/SKILL.md +3 -0
  95. package/dist/agent-src/skills/monorepo-workspace/SKILL.md +149 -0
  96. package/dist/agent-src/skills/motion-choreographer/SKILL.md +6 -0
  97. package/dist/agent-src/skills/multi-tenancy/SKILL.md +4 -0
  98. package/dist/agent-src/skills/operational-readiness/SKILL.md +184 -0
  99. package/dist/agent-src/skills/override-management/SKILL.md +3 -0
  100. package/dist/agent-src/skills/persona-improvement/SKILL.md +3 -0
  101. package/dist/agent-src/skills/pest-testing/SKILL.md +3 -0
  102. package/dist/agent-src/skills/playbook-authoring/SKILL.md +162 -0
  103. package/dist/agent-src/skills/playwright-testing/SKILL.md +3 -0
  104. package/dist/agent-src/skills/privacy-review/SKILL.md +3 -0
  105. package/dist/agent-src/skills/project-analysis-core/SKILL.md +23 -0
  106. package/dist/agent-src/skills/prompt-engineering-image/SKILL.md +3 -0
  107. package/dist/agent-src/skills/quality-tools/SKILL.md +5 -0
  108. package/dist/agent-src/skills/react-shadcn-ui/SKILL.md +81 -33
  109. package/dist/agent-src/skills/readme-reviewer/SKILL.md +3 -0
  110. package/dist/agent-src/skills/readme-writing/SKILL.md +3 -0
  111. package/dist/agent-src/skills/readme-writing-package/SKILL.md +3 -0
  112. package/dist/agent-src/skills/receiving-code-review/SKILL.md +2 -2
  113. package/dist/agent-src/skills/refine-prompt/SKILL.md +3 -0
  114. package/dist/agent-src/skills/refine-ticket/SKILL.md +3 -0
  115. package/dist/agent-src/skills/requesting-code-review/SKILL.md +2 -2
  116. package/dist/agent-src/skills/review-routing/SKILL.md +2 -2
  117. package/dist/agent-src/skills/roadmap-writing/SKILL.md +23 -41
  118. package/dist/agent-src/skills/roadmap-writing/references/follow-up-roadmap-shape.md +47 -0
  119. package/dist/agent-src/skills/rtk-output-filtering/SKILL.md +22 -6
  120. package/dist/agent-src/skills/runway-cognition/SKILL.md +3 -0
  121. package/dist/agent-src/skills/scene-expander/scene-blueprint.schema.yaml +26 -0
  122. package/dist/agent-src/skills/secrets-management/SKILL.md +4 -0
  123. package/dist/agent-src/skills/server-hardening/SKILL.md +159 -0
  124. package/dist/agent-src/skills/skill-improvement-pipeline/SKILL.md +3 -0
  125. package/dist/agent-src/skills/skill-management/SKILL.md +3 -0
  126. package/dist/agent-src/skills/skill-reviewer/SKILL.md +3 -0
  127. package/dist/agent-src/skills/skill-writing/SKILL.md +6 -0
  128. package/dist/agent-src/skills/skill-writing/references/procedure.md +24 -2
  129. package/dist/agent-src/skills/spreadsheet-authoring/SKILL.md +3 -0
  130. package/dist/agent-src/skills/storybook-workshop/SKILL.md +203 -0
  131. package/dist/agent-src/skills/storybook-workshop/scripts/story_contrast_floor.ts +134 -0
  132. package/dist/agent-src/skills/subagent-orchestration/SKILL.md +1 -1
  133. package/dist/agent-src/skills/subagent-orchestration/prompts/README.md +25 -0
  134. package/dist/agent-src/skills/supply-chain-intake/SKILL.md +12 -0
  135. package/dist/agent-src/skills/systematic-debugging/SKILL.md +1 -1
  136. package/dist/agent-src/skills/terraform/SKILL.md +3 -0
  137. package/dist/agent-src/skills/test-driven-development/SKILL.md +1 -1
  138. package/dist/agent-src/skills/threat-modeling/SKILL.md +0 -3
  139. package/dist/agent-src/skills/token-optimizer/SKILL.md +3 -0
  140. package/dist/agent-src/skills/typography-system/SKILL.md +3 -0
  141. package/dist/agent-src/skills/ui-component-architect/SKILL.md +17 -1
  142. package/dist/agent-src/skills/upstream-contribute/SKILL.md +3 -0
  143. package/dist/agent-src/skills/validate-feature-fit/SKILL.md +3 -0
  144. package/dist/agent-src/skills/verify-completion-evidence/SKILL.md +2 -2
  145. package/dist/agent-src/skills/wireframe/SKILL.md +3 -0
  146. package/dist/agent-src/skills/wireframe/references/story-beat-ledger.schema.json +115 -0
  147. package/dist/agent-src/skills/workspace-link/SKILL.md +131 -0
  148. package/dist/agent-src/templates/agents/agent-project-settings.example.yml +1 -1
  149. package/dist/agent-src/templates/playbook.md +75 -0
  150. package/dist/agent-src/templates/roadmaps.md +37 -0
  151. package/dist/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  152. package/dist/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  153. package/dist/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  154. package/dist/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  155. package/dist/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  156. package/dist/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  157. package/dist/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  158. package/dist/cli/commands/uiAudit.js +221 -0
  159. package/dist/cli/commands/uiRender.js +206 -0
  160. package/dist/cli/main.js +22 -1
  161. package/dist/cli/mcp/content.js +64 -1
  162. package/dist/cli/mcp/dispatch.js +175 -10
  163. package/dist/cli/registry.js +3 -0
  164. package/dist/cli-delegate/{chunk-G23AT6GD.js → chunk-DMSZHXZS.js} +57 -1
  165. package/dist/cli-delegate/{chunk-77GR3VD4.js → chunk-FF7WAFMR.js} +58 -3
  166. package/dist/cli-delegate/{chunk-YM4GZDJG.js → chunk-JCW7ZLHK.js} +10 -0
  167. package/dist/cli-delegate/{chunk-H4VIVD4C.js → chunk-JJA2QEWA.js} +413 -391
  168. package/dist/cli-delegate/{chunk-PLSG6UL5.js → chunk-K4FFODTS.js} +341 -204
  169. package/dist/cli-delegate/{chunk-B2ERU2VA.js → chunk-WOKWX5PL.js} +1 -1
  170. package/dist/cli-delegate/cmd_brand_status.js +8 -6
  171. package/dist/cli-delegate/cmd_conformance.js +3 -3
  172. package/dist/cli-delegate/cmd_doctor.js +3 -3
  173. package/dist/cli-delegate/cmd_export.js +4 -4
  174. package/dist/cli-delegate/cmd_handoff.js +1 -1
  175. package/dist/cli-delegate/cmd_preflight.js +2 -2
  176. package/dist/cli-delegate/cmd_prune.js +4 -4
  177. package/dist/cli-delegate/cmd_session_recycle.js +70 -9
  178. package/dist/cli-delegate/cmd_settings_migrate.js +4 -4
  179. package/dist/cli-delegate/cmd_settings_set.js +1 -1
  180. package/dist/cli-delegate/cmd_sync.js +4 -4
  181. package/dist/cli-delegate/cmd_uninstall.js +4 -4
  182. package/dist/cli-delegate/cmd_validate.js +4 -4
  183. package/dist/discovery/deprecation-report.md +1 -1
  184. package/dist/discovery/discovery-manifest.json +362 -127
  185. package/dist/discovery/discovery-manifest.json.sha256 +1 -1
  186. package/dist/discovery/discovery-manifest.summary.md +4 -4
  187. package/dist/discovery/dormancy-report.md +1 -1
  188. package/dist/discovery/orphan-report.md +1 -1
  189. package/dist/discovery/packs.json +18 -8
  190. package/dist/discovery/trust-report.md +3 -3
  191. package/dist/discovery/workspaces.json +16 -6
  192. package/dist/hooks/dispatch.js +2575 -1472
  193. package/dist/install/install.mjs +800 -708
  194. package/dist/mcp/registry-manifest.json +3 -3
  195. package/dist/mcp/server.json +2 -2
  196. package/dist/mcp/server.mjs +1685 -1250
  197. package/dist/router.json +1 -1
  198. package/dist/scripts/_lib/lean_projection_mode.js +40 -0
  199. package/dist/scripts/_lib/scoped_projection.js +84 -0
  200. package/dist/scripts/_lib/ui_surface.js +89 -0
  201. package/dist/scripts/condense.js +6 -10
  202. package/dist/scripts/project_thin_rules.js +40 -2
  203. package/dist/server/schemas/settings.js +6 -0
  204. package/dist/shared/skillRanking.js +159 -0
  205. package/docs/contracts/provider-lifecycle.md +47 -18
  206. package/docs/contracts/settings-classes.md +35 -5
  207. package/docs/guidelines/agent-infra/context-hygiene-mechanics.md +49 -0
  208. package/docs/guidelines/agent-infra/downstream-changes-mechanics.md +91 -0
  209. package/docs/guidelines/agent-infra/evaluator-independence-mechanics.md +92 -0
  210. package/docs/guidelines/agent-infra/minimal-safe-diff-mechanics.md +45 -1
  211. package/docs/guidelines/agent-infra/roadmap-deferred-resolution-provenance.md +54 -0
  212. package/docs/guidelines/code-clarity.md +21 -0
  213. package/docs/guidelines/design-antipatterns.md +4 -2
  214. package/docs/guidelines/design-asset-discipline.md +38 -0
  215. package/docs/guidelines/design-fidelity-mechanics.md +45 -29
  216. package/docs/guidelines/design-handover-extraction.md +35 -5
  217. package/docs/guidelines/design-modes.md +41 -1
  218. package/docs/guidelines/monorepo-antipatterns.md +141 -0
  219. package/docs/guidelines/redundancy-taxonomy.md +180 -0
  220. package/llms.txt +50 -39
  221. package/package.json +6 -2
  222. package/src/agent-src/templates/scripts/check_playbook_invokes.ts +231 -0
  223. package/src/agent-src/templates/scripts/work_engine/directives/ui/apply.ts +24 -0
  224. package/src/agent-src/templates/scripts/work_engine/directives/ui/polish.ts +2 -0
  225. package/src/agent-src/templates/scripts/work_engine/directives/ui/review.ts +216 -0
  226. package/src/agent-src/templates/scripts/work_engine/directives/ui/scaffold.ts +159 -0
  227. package/src/agent-src/templates/scripts/work_engine/directives/ui/stack_bundles.ts +73 -4
  228. package/src/agent-src/templates/scripts/work_engine/stack/detect.ts +325 -40
  229. package/src/config/agent-settings.template.yml +44 -0
  230. package/src/config/assurance-capability-registry.json +223 -0
  231. package/src/config/assurance-threshold-budget.json +65 -0
  232. package/src/config/budgets.yml +19 -0
  233. package/src/config/ci-local-parity.yml +29 -0
  234. package/src/config/discovery/prompt-patterns.yml +56 -0
  235. package/src/config/discovery/unassigned-artefacts.yml +2 -0
  236. package/src/config/dispatch-economy-metrics.json +4 -2
  237. package/src/config/estate-count-budget.json +8 -3
  238. package/src/config/evaluator-budgets.json +14 -14
  239. package/src/config/gate-coverage.yml +392 -8
  240. package/src/config/gate-violation-baselines.json +76 -72
  241. package/src/config/hook-latency-budget.json +1 -0
  242. package/src/config/hook-token-budget.json +137 -125
  243. package/src/config/pack-size-budget.json +39 -10
  244. package/src/config/preamble-payload-budget.json +97 -71
  245. package/src/config/quorum-attendance-budget.json +12 -4
  246. package/src/config/routing-coverage-seed.json +29 -0
  247. package/src/config/rule-activation-census.json +7 -3
  248. package/src/config/rule-enforcement-baseline.json +0 -1
  249. package/src/config/rule-stub-ceilings.json +112 -91
  250. package/src/config/suggestion-capture.json +28 -0
  251. package/src/config/surface-matrix.yml +21 -2
  252. package/src/config/web-launch-readiness.json +188 -0
  253. package/src/scripts/_cli/cmd_doctor.ts +15 -16
  254. package/src/scripts/_cli/doctor_install_mode.ts +49 -0
  255. package/src/scripts/_cli/doctor_overrides.ts +154 -0
  256. package/src/scripts/_dispatch.bash +17 -0
  257. package/src/scripts/_lib/as_of.ts +412 -0
  258. package/src/scripts/_lib/exec_evidence.ts +7 -0
  259. package/src/scripts/_lib/gate_baseline.ts +150 -1
  260. package/src/scripts/_lib/hook_settings.ts +33 -0
  261. package/src/scripts/_lib/host_listing_model.ts +192 -0
  262. package/src/scripts/_lib/lean_projection_mode.ts +44 -0
  263. package/src/scripts/_lib/mcp_bridge.ts +199 -0
  264. package/src/scripts/_lib/review_independence.ts +62 -10
  265. package/src/scripts/_lib/rule_injection.ts +239 -0
  266. package/src/scripts/_lib/run_checkpoint.ts +54 -1
  267. package/src/scripts/_lib/scoped_projection.ts +96 -0
  268. package/src/scripts/_lib/session_register.ts +44 -2
  269. package/src/scripts/_lib/skill_catalogue.ts +38 -2
  270. package/src/scripts/_lib/skill_estate.ts +115 -0
  271. package/src/scripts/_lib/transcript_reads.ts +207 -0
  272. package/src/scripts/_lib/ui_authority.ts +343 -0
  273. package/src/scripts/ai-video/adapters/fal.sh +8 -3
  274. package/src/scripts/ai-video/adapters/gemini-veo.sh +10 -0
  275. package/src/scripts/ai-video/adapters/higgsfield.sh +10 -2
  276. package/src/scripts/ai-video/adapters/kling.sh +10 -0
  277. package/src/scripts/ai-video/adapters/sora.sh +10 -0
  278. package/src/scripts/ai-video/lib/calibrate-cost.sh +145 -0
  279. package/src/scripts/ai-video/lib/model-capabilities/README.md +53 -7
  280. package/src/scripts/ai-video/lib/model-capabilities/comfyui.json +15 -3
  281. package/src/scripts/ai-video/lib/model-capabilities/fal.json +36 -6
  282. package/src/scripts/ai-video/lib/model-capabilities/gemini-veo.json +23 -0
  283. package/src/scripts/ai-video/lib/model-capabilities/higgsfield.json +23 -0
  284. package/src/scripts/ai-video/lib/model-capabilities/kling.json +23 -0
  285. package/src/scripts/ai-video/lib/model-capabilities/musetalk.json +8 -2
  286. package/src/scripts/ai-video/lib/model-capabilities/replicate.json +36 -6
  287. package/src/scripts/ai-video/lib/model-capabilities/sora.json +45 -0
  288. package/src/scripts/ai-video/lib/model-capabilities/syncso.json +8 -2
  289. package/src/scripts/ai-video/lib/parse-blueprint.sh +52 -5
  290. package/src/scripts/ai-video/lib/resume-scan.sh +92 -3
  291. package/src/scripts/ai-video/lib/seam-plan.sh +212 -0
  292. package/src/scripts/ai-video/smoke-trace.sh +450 -2
  293. package/src/scripts/ai-video/stitch.sh +191 -10
  294. package/src/scripts/ai-video/test-pipeline.sh +84 -6
  295. package/src/scripts/ai_council/argument_exhaustion.ts +130 -0
  296. package/src/scripts/ai_council/cli_agency_bounds.ts +139 -0
  297. package/src/scripts/ai_council/cli_least_agency_canary.ts +347 -0
  298. package/src/scripts/ai_council/clients.ts +3 -2
  299. package/src/scripts/ai_council/consensus.ts +63 -6
  300. package/src/scripts/ai_council/events_log.ts +46 -1
  301. package/src/scripts/ai_council/orchestrator.ts +103 -108
  302. package/src/scripts/ai_council/orchestrator_results.ts +166 -0
  303. package/src/scripts/ai_council/prompts.ts +12 -5
  304. package/src/scripts/ai_council/quorum.ts +82 -1
  305. package/src/scripts/ai_council/quorum_wiring.ts +82 -5
  306. package/src/scripts/ai_council/stance_tally.ts +22 -0
  307. package/src/scripts/bench_hook_latency.ts +62 -0
  308. package/src/scripts/build_proof.ts +12 -1
  309. package/src/scripts/capture_skill_catalogue.ts +21 -0
  310. package/src/scripts/check_always_budget.ts +2 -1
  311. package/src/scripts/check_augmentignore.ts +2 -1
  312. package/src/scripts/check_beta_review_markers.ts +2 -1
  313. package/src/scripts/check_bundle_path_leakage.ts +162 -7
  314. package/src/scripts/check_command_examples.ts +557 -0
  315. package/src/scripts/check_composite_arming.ts +364 -0
  316. package/src/scripts/check_corpus_staleness.ts +2 -1
  317. package/src/scripts/check_council_pin_staleness.ts +3 -1
  318. package/src/scripts/check_enforcement_coverage.ts +116 -3
  319. package/src/scripts/check_enforcement_denominator.ts +365 -0
  320. package/src/scripts/check_estate_count.ts +122 -3
  321. package/src/scripts/check_gate_coverage.ts +2 -1
  322. package/src/scripts/check_hook_bundle_freshness.ts +13 -1
  323. package/src/scripts/check_knowledge_cards.ts +2 -1
  324. package/src/scripts/check_knowledge_pages.ts +3 -2
  325. package/src/scripts/check_memory.ts +2 -1
  326. package/src/scripts/check_no_automerge_key.ts +287 -0
  327. package/src/scripts/check_pack_conformance_fixture.ts +565 -0
  328. package/src/scripts/check_preamble_payload_budget.ts +30 -3
  329. package/src/scripts/check_proposal.ts +2 -1
  330. package/src/scripts/check_reach_staleness.ts +2 -1
  331. package/src/scripts/check_release_adjacent_health.ts +2 -1
  332. package/src/scripts/check_release_pr_shape.ts +5 -0
  333. package/src/scripts/check_review_schema.ts +34 -1
  334. package/src/scripts/check_roadmap_trackable.ts +48 -3
  335. package/src/scripts/check_routing_coverage.ts +352 -0
  336. package/src/scripts/check_score_contract.ts +505 -0
  337. package/src/scripts/check_skill_admissions.ts +514 -0
  338. package/src/scripts/check_source_size_budget.ts +2 -1
  339. package/src/scripts/check_standing_payload_delta.ts +505 -0
  340. package/src/scripts/check_trigger_evals.ts +2 -1
  341. package/src/scripts/check_web_launch_readiness.ts +705 -0
  342. package/src/scripts/classify_change_risk.ts +281 -0
  343. package/src/scripts/compute_skill_tiers.ts +186 -0
  344. package/src/scripts/condense.ts +8 -13
  345. package/src/scripts/council_attendance_metrics.ts +183 -0
  346. package/src/scripts/council_cli.ts +10 -8
  347. package/src/scripts/council_parse_rate.ts +116 -0
  348. package/src/scripts/derive_playbooks.ts +406 -0
  349. package/src/scripts/description_route_check.ts +494 -0
  350. package/src/scripts/design_slop_rules.ts +56 -2
  351. package/src/scripts/dispatch_r2_reviewer.ts +16 -0
  352. package/src/scripts/frontend_corpus_hash.ts +116 -0
  353. package/src/scripts/grade_target_readiness.ts +478 -0
  354. package/src/scripts/hook_manifest.json +1 -1
  355. package/src/scripts/hook_manifest.yaml +124 -16
  356. package/src/scripts/hooks/concern_registry.ts +6 -0
  357. package/src/scripts/hooks/design_pass_hook.ts +356 -0
  358. package/src/scripts/hooks/rtk_wrap_hook.ts +30 -7
  359. package/src/scripts/hooks/rule_inject_hook.ts +318 -0
  360. package/src/scripts/hooks/suggestion_capture_hook.ts +368 -0
  361. package/src/scripts/hot_context_hook.ts +74 -7
  362. package/src/scripts/install.ts +40 -89
  363. package/src/scripts/lint_adapter_tier.ts +663 -0
  364. package/src/scripts/lint_archived_skills.ts +93 -0
  365. package/src/scripts/lint_budget_ownership.ts +56 -5
  366. package/src/scripts/lint_deterministic_time.ts +470 -0
  367. package/src/scripts/lint_framework_leakage.ts +5 -0
  368. package/src/scripts/lint_handoffs.ts +525 -1
  369. package/src/scripts/lint_judge_prompt_expectation.ts +155 -0
  370. package/src/scripts/lint_marketplace.ts +88 -0
  371. package/src/scripts/lint_media_policy_linkage.ts +140 -1
  372. package/src/scripts/lint_one_off_age.ts +6 -1
  373. package/src/scripts/lint_override_kernel_guard.ts +87 -5
  374. package/src/scripts/lint_roadmap_complexity.ts +56 -0
  375. package/src/scripts/lint_rule_enforcement_declaration.ts +24 -7
  376. package/src/scripts/lint_rule_norm_pin.ts +321 -0
  377. package/src/scripts/lint_skill_trigger_corpus.ts +349 -0
  378. package/src/scripts/lint_spawn_payload.ts +42 -5
  379. package/src/scripts/lint_symptom_intake.ts +2 -1
  380. package/src/scripts/mcp_parity_smoke.ts +30 -4
  381. package/src/scripts/mcp_render.ts +66 -1
  382. package/src/scripts/mcp_tool_fingerprint.ts +241 -0
  383. package/src/scripts/measure_risk_class_drift.ts +140 -0
  384. package/src/scripts/measure_skill_ranker_baseline.ts +212 -0
  385. package/src/scripts/media/lib/adapter-common.sh +211 -1
  386. package/src/scripts/media/lib/adapter-contract.md +74 -6
  387. package/src/scripts/model_rule_injection.ts +907 -0
  388. package/src/scripts/pack_install_smoke.ts +363 -0
  389. package/src/scripts/pr_conflict_census.ts +187 -0
  390. package/src/scripts/project_thin_rules.ts +45 -2
  391. package/src/scripts/release.ts +66 -860
  392. package/src/scripts/release_drill.ts +59 -3
  393. package/src/scripts/release_env.ts +298 -0
  394. package/src/scripts/release_publication.ts +720 -0
  395. package/src/scripts/report_pack_delta.ts +204 -0
  396. package/src/scripts/roadmap_context.ts +778 -0
  397. package/src/scripts/schemas/fidelity-measurement-sheet.schema.json +169 -0
  398. package/src/scripts/schemas/rule.schema.json +24 -2
  399. package/src/scripts/schemas/skill.schema.json +39 -0
  400. package/src/scripts/schemas/ui-authority.schema.json +114 -0
  401. package/src/scripts/select_analysis_mode.ts +112 -0
  402. package/src/scripts/session_register_hook.ts +29 -3
  403. package/src/scripts/sessions_cli.ts +67 -3
  404. package/src/scripts/skill_tools/score_skill_relevance.ts +36 -53
  405. package/src/scripts/sync_pr_branch.ts +40 -1
  406. package/src/scripts/token_sink_report.ts +239 -0
  407. package/src/scripts/trigger_coverage.ts +122 -3
  408. package/src/scripts/update_counts.ts +7 -3
  409. package/src/scripts/validate_frontmatter.ts +66 -0
  410. package/src/server/schemas/settings.ts +10 -0
  411. package/src/shared/skillRanking.ts +183 -0
  412. package/dist/agent-src/skills/accessibility-auditor/evals/evals.json +0 -15
  413. package/dist/agent-src/skills/agent-security-review/evals/triggers.json +0 -52
  414. package/dist/agent-src/skills/ai-code-blindspots/evals/triggers.json +0 -52
  415. package/dist/agent-src/skills/analysis-skill-router/evals/evals.json +0 -13
  416. package/dist/agent-src/skills/brand/evals/triggers.json +0 -17
  417. package/dist/agent-src/skills/brand-asset-generation/evals/triggers.json +0 -17
  418. package/dist/agent-src/skills/brand-audit/evals/triggers.json +0 -17
  419. package/dist/agent-src/skills/brand-identity/evals/triggers.json +0 -17
  420. package/dist/agent-src/skills/brand-strategy/evals/triggers.json +0 -17
  421. package/dist/agent-src/skills/brand-to-tokens/evals/triggers.json +0 -17
  422. package/dist/agent-src/skills/bug-analyzer/evals/evals.json +0 -13
  423. package/dist/agent-src/skills/canvas-design/evals/triggers.json +0 -17
  424. package/dist/agent-src/skills/character-consistency/evals/evals.json +0 -16
  425. package/dist/agent-src/skills/code-intelligence/evals/triggers.json +0 -52
  426. package/dist/agent-src/skills/code-review/evals/evals.json +0 -100
  427. package/dist/agent-src/skills/command-routing/evals/evals.json +0 -14
  428. package/dist/agent-src/skills/complexity-first-planning/evals/triggers.json +0 -17
  429. package/dist/agent-src/skills/contract-review/evals/triggers.json +0 -17
  430. package/dist/agent-src/skills/conventional-commits-writing/evals/evals.json +0 -15
  431. package/dist/agent-src/skills/corpus-grounding/evals/triggers.json +0 -17
  432. package/dist/agent-src/skills/dashboard-design/evals/evals.json +0 -16
  433. package/dist/agent-src/skills/dcf-modeling/evals/domain-truth.json +0 -29
  434. package/dist/agent-src/skills/dcf-modeling/evals/evals.json +0 -20
  435. package/dist/agent-src/skills/decision-record/evals/evals.json +0 -20
  436. package/dist/agent-src/skills/decision-record/evals/triggers.json +0 -87
  437. package/dist/agent-src/skills/design-intelligence/evals/evals.json +0 -14
  438. package/dist/agent-src/skills/design-intelligence/evals/triggers.json +0 -17
  439. package/dist/agent-src/skills/design-system-capture/evals/evals.json +0 -15
  440. package/dist/agent-src/skills/design-tokens/evals/triggers.json +0 -17
  441. package/dist/agent-src/skills/design-variations/evals/triggers.json +0 -17
  442. package/dist/agent-src/skills/developer-like-execution/evals/evals.json +0 -16
  443. package/dist/agent-src/skills/doc-coauthoring/evals/evals.json +0 -16
  444. package/dist/agent-src/skills/doc-coauthoring/evals/triggers.json +0 -17
  445. package/dist/agent-src/skills/docx-authoring/evals/triggers.json +0 -52
  446. package/dist/agent-src/skills/dpa-review/evals/triggers.json +0 -17
  447. package/dist/agent-src/skills/editorial-calendar/evals/domain-truth.json +0 -16
  448. package/dist/agent-src/skills/editorial-calendar/evals/evals.json +0 -16
  449. package/dist/agent-src/skills/eloquent/evals/triggers.json +0 -17
  450. package/dist/agent-src/skills/estimate-ticket/evals/evals.json +0 -16
  451. package/dist/agent-src/skills/estimate-ticket/evals/output-schema.yml +0 -20
  452. package/dist/agent-src/skills/estimate-ticket/evals/triggers.json +0 -19
  453. package/dist/agent-src/skills/evaluate-llm-feature/evals/triggers.json +0 -52
  454. package/dist/agent-src/skills/existing-ui-audit/evals/triggers.json +0 -47
  455. package/dist/agent-src/skills/experiment-loop/evals/output-schema.yml +0 -27
  456. package/dist/agent-src/skills/experiment-loop/evals/triggers.json +0 -17
  457. package/dist/agent-src/skills/fe-design/evals/triggers.json +0 -55
  458. package/dist/agent-src/skills/forecasting/evals/domain-truth.json +0 -29
  459. package/dist/agent-src/skills/forecasting/evals/evals.json +0 -20
  460. package/dist/agent-src/skills/forensics-report/evals/triggers.json +0 -17
  461. package/dist/agent-src/skills/frontend-render-security/evals/triggers.json +0 -52
  462. package/dist/agent-src/skills/fundraising-narrative/evals/domain-truth.json +0 -16
  463. package/dist/agent-src/skills/fundraising-narrative/evals/evals.json +0 -16
  464. package/dist/agent-src/skills/gated-reach/evals/triggers.json +0 -72
  465. package/dist/agent-src/skills/github-ci/evals/evals.json +0 -25
  466. package/dist/agent-src/skills/history-design/evals/triggers.json +0 -17
  467. package/dist/agent-src/skills/html-deck/evals/triggers.json +0 -17
  468. package/dist/agent-src/skills/humanizer/evals/strip_fixtures.json +0 -57
  469. package/dist/agent-src/skills/humanizer/evals/triggers.json +0 -17
  470. package/dist/agent-src/skills/iconography/evals/triggers.json +0 -17
  471. package/dist/agent-src/skills/image-analyser/evals/triggers.json +0 -17
  472. package/dist/agent-src/skills/image-creator/evals/triggers.json +0 -17
  473. package/dist/agent-src/skills/image-editing/evals/triggers.json +0 -17
  474. package/dist/agent-src/skills/image-generation/evals/triggers.json +0 -17
  475. package/dist/agent-src/skills/image-provider-routing/evals/triggers.json +0 -17
  476. package/dist/agent-src/skills/incident-commander/evals/domain-truth.json +0 -16
  477. package/dist/agent-src/skills/incident-commander/evals/evals.json +0 -20
  478. package/dist/agent-src/skills/judge-artifact-completeness/evals/triggers.json +0 -17
  479. package/dist/agent-src/skills/judge-injection-defense/evals/triggers.json +0 -17
  480. package/dist/agent-src/skills/judge-synthesis/evals/triggers.json +0 -17
  481. package/dist/agent-src/skills/launch-readiness/evals/evals.json +0 -21
  482. package/dist/agent-src/skills/learning-tutor/evals/triggers.json +0 -52
  483. package/dist/agent-src/skills/legal-intake-triage/evals/triggers.json +0 -17
  484. package/dist/agent-src/skills/legal-practice-profile/evals/triggers.json +0 -17
  485. package/dist/agent-src/skills/license-compliance-audit/evals/triggers.json +0 -52
  486. package/dist/agent-src/skills/license-compliance-borrow-check/evals/triggers.json +0 -52
  487. package/dist/agent-src/skills/license-compliance-credits/evals/triggers.json +0 -52
  488. package/dist/agent-src/skills/llm-provider-knowledge/evals/triggers.json +0 -20
  489. package/dist/agent-src/skills/logging-monitoring/evals/evals.json +0 -16
  490. package/dist/agent-src/skills/logo-generation/evals/triggers.json +0 -17
  491. package/dist/agent-src/skills/messaging-architecture/evals/domain-truth.json +0 -16
  492. package/dist/agent-src/skills/messaging-architecture/evals/evals.json +0 -16
  493. package/dist/agent-src/skills/nda-triage/evals/triggers.json +0 -17
  494. package/dist/agent-src/skills/pdf-tools/evals/triggers.json +0 -52
  495. package/dist/agent-src/skills/perf-feedback-craft/evals/evals.json +0 -16
  496. package/dist/agent-src/skills/persona-improvement/evals/triggers.json +0 -52
  497. package/dist/agent-src/skills/php-coder/evals/triggers.json +0 -17
  498. package/dist/agent-src/skills/prediction-pool-optimizer/evals/triggers.json +0 -21
  499. package/dist/agent-src/skills/prompt-engineering-image/evals/triggers.json +0 -17
  500. package/dist/agent-src/skills/prompt-engineering-patterns/evals/evals.json +0 -16
  501. package/dist/agent-src/skills/prompt-validator/evals/triggers.json +0 -17
  502. package/dist/agent-src/skills/quality-tools/evals/evals.json +0 -15
  503. package/dist/agent-src/skills/reasoning-orchestrator/evals/triggers.json +0 -17
  504. package/dist/agent-src/skills/refine-prompt/evals/evals.json +0 -16
  505. package/dist/agent-src/skills/refine-ticket/evals/evals.json +0 -16
  506. package/dist/agent-src/skills/refine-ticket/evals/output-schema.yml +0 -16
  507. package/dist/agent-src/skills/refine-ticket/evals/triggers.json +0 -17
  508. package/dist/agent-src/skills/release-comms/evals/evals.json +0 -16
  509. package/dist/agent-src/skills/rice-prioritization/evals/evals.json +0 -20
  510. package/dist/agent-src/skills/runway-cognition/evals/domain-truth.json +0 -29
  511. package/dist/agent-src/skills/runway-cognition/evals/evals.json +0 -20
  512. package/dist/agent-src/skills/scenario-modeling/evals/domain-truth.json +0 -29
  513. package/dist/agent-src/skills/scenario-modeling/evals/evals.json +0 -20
  514. package/dist/agent-src/skills/schema-review/evals/triggers.json +0 -17
  515. package/dist/agent-src/skills/screenshot-hygiene/evals/triggers.json +0 -52
  516. package/dist/agent-src/skills/security-maturity-assessment/evals/triggers.json +0 -52
  517. package/dist/agent-src/skills/skill-writing/evals/triggers.json +0 -17
  518. package/dist/agent-src/skills/spreadsheet-authoring/evals/triggers.json +0 -47
  519. package/dist/agent-src/skills/subagent-orchestration/evals/evals.json +0 -60
  520. package/dist/agent-src/skills/supply-chain-intake/evals/triggers.json +0 -52
  521. package/dist/agent-src/skills/systematic-debugging/evals/evals.json +0 -20
  522. package/dist/agent-src/skills/test-case-discovery/evals/triggers.json +0 -52
  523. package/dist/agent-src/skills/test-driven-development/evals/evals.json +0 -16
  524. package/dist/agent-src/skills/threat-modeling/evals/evals.json +0 -21
  525. package/dist/agent-src/skills/typography-system/evals/evals.json +0 -14
  526. package/dist/agent-src/skills/typography-system/evals/triggers.json +0 -17
  527. package/dist/agent-src/skills/unit-economics-modeling/evals/domain-truth.json +0 -40
  528. package/dist/agent-src/skills/unit-economics-modeling/evals/evals.json +0 -24
  529. package/dist/agent-src/skills/verify-completion-evidence/evals/evals.json +0 -16
  530. package/dist/agent-src/skills/verify-repair-loop/evals/output-schema.yml +0 -20
  531. package/dist/agent-src/skills/verify-repair-loop/evals/triggers.json +0 -17
  532. package/dist/agent-src/skills/vision-articulation/evals/evals.json +0 -16
  533. package/dist/agent-src/skills/voice-and-tone-design/evals/evals.json +0 -16
  534. package/dist/agent-src/skills/wireframe/evals/triggers.json +0 -17
  535. package/dist/agent-src/skills/worktree-lifecycle/evals/evals.json +0 -38
  536. package/dist/agent-src/skills/worktree-lifecycle/evals/triggers.json +0 -52
  537. package/dist/cli/agent-config.js.map +0 -1
  538. package/dist/cli/bash/runBash.js.map +0 -1
  539. package/dist/cli/commands/commands.js.map +0 -1
  540. package/dist/cli/commands/config.js.map +0 -1
  541. package/dist/cli/commands/doctorShell.js.map +0 -1
  542. package/dist/cli/commands/mcpServer.js.map +0 -1
  543. package/dist/cli/commands/packs.js.map +0 -1
  544. package/dist/cli/commands/profiles.js.map +0 -1
  545. package/dist/cli/commands/recordTriggerEval.js.map +0 -1
  546. package/dist/cli/commands/rtkDetect.js.map +0 -1
  547. package/dist/cli/commands/settings.js.map +0 -1
  548. package/dist/cli/commands/uiServe.js.map +0 -1
  549. package/dist/cli/commands/versions.js.map +0 -1
  550. package/dist/cli/commands/workspaces.js.map +0 -1
  551. package/dist/cli/configRoot.js.map +0 -1
  552. package/dist/cli/discovery/loadManifest.js.map +0 -1
  553. package/dist/cli/firstRunNotice.js.map +0 -1
  554. package/dist/cli/help.js.map +0 -1
  555. package/dist/cli/initRouting.js.map +0 -1
  556. package/dist/cli/log/logger.js.map +0 -1
  557. package/dist/cli/main.js.map +0 -1
  558. package/dist/cli/mcp/content.js.map +0 -1
  559. package/dist/cli/mcp/dispatch.js.map +0 -1
  560. package/dist/cli/mcp/stdio.js.map +0 -1
  561. package/dist/cli/paths.js.map +0 -1
  562. package/dist/cli/python/knowledge_ingest.js.map +0 -1
  563. package/dist/cli/python/workspace_analytics.js.map +0 -1
  564. package/dist/cli/python/workspace_crypto.js.map +0 -1
  565. package/dist/cli/python/workspace_documents.js.map +0 -1
  566. package/dist/cli/python/workspace_drive.js.map +0 -1
  567. package/dist/cli/python/workspace_drive_health.js.map +0 -1
  568. package/dist/cli/python/workspace_explain.js.map +0 -1
  569. package/dist/cli/python/workspace_hosts.js.map +0 -1
  570. package/dist/cli/python/workspace_inbox.js.map +0 -1
  571. package/dist/cli/python/workspace_render.js.map +0 -1
  572. package/dist/cli/python/workspace_roles.js.map +0 -1
  573. package/dist/cli/python/workspace_secrets.js.map +0 -1
  574. package/dist/cli/python/workspace_sessions.js.map +0 -1
  575. package/dist/cli/python/workspace_skills.js.map +0 -1
  576. package/dist/cli/registry.js.map +0 -1
  577. package/dist/install/agentSwitchDetection.js.map +0 -1
  578. package/dist/install/agentSwitchProfile.js.map +0 -1
  579. package/dist/install/atomic.js.map +0 -1
  580. package/dist/install/claudePathsPlan.js.map +0 -1
  581. package/dist/install/conflict.js.map +0 -1
  582. package/dist/install/detect.js.map +0 -1
  583. package/dist/install/emit_host_rules_cli.js.map +0 -1
  584. package/dist/install/globalRuleLayers.js.map +0 -1
  585. package/dist/install/hostLayerFingerprint.js.map +0 -1
  586. package/dist/install/partitionEligibility.js.map +0 -1
  587. package/dist/install/paths.js.map +0 -1
  588. package/dist/install/plan.js.map +0 -1
  589. package/dist/install/preflight.js.map +0 -1
  590. package/dist/install/rtkDetection.js.map +0 -1
  591. package/dist/install/ruleInScope.js.map +0 -1
  592. package/dist/install/ruleLayerPartition.js.map +0 -1
  593. package/dist/install/rule_scope.js.map +0 -1
  594. package/dist/install/rule_scope_cli.js.map +0 -1
  595. package/dist/install/selectedTools.js.map +0 -1
  596. package/dist/install/toolDetection.js.map +0 -1
  597. package/dist/install/txlog.js.map +0 -1
  598. package/dist/install/types.js.map +0 -1
  599. package/dist/install/wizard-plan.js.map +0 -1
  600. package/dist/install/wizardDismissals.js.map +0 -1
  601. package/dist/scripts/_lib/agent_settings.js.map +0 -1
  602. package/dist/scripts/_lib/agent_src.js.map +0 -1
  603. package/dist/scripts/_lib/claude_builtin_names.js.map +0 -1
  604. package/dist/scripts/_lib/claude_plugin.js.map +0 -1
  605. package/dist/scripts/_lib/claude_settings_hooks.js.map +0 -1
  606. package/dist/scripts/_lib/compile_time_toggles.js.map +0 -1
  607. package/dist/scripts/_lib/environment_detector.js.map +0 -1
  608. package/dist/scripts/_lib/host_launch.js.map +0 -1
  609. package/dist/scripts/_lib/install_layout.js.map +0 -1
  610. package/dist/scripts/_lib/installed_lock.js.map +0 -1
  611. package/dist/scripts/_lib/model_tier.js.map +0 -1
  612. package/dist/scripts/_lib/prune_empty_dirs.js.map +0 -1
  613. package/dist/scripts/_lib/scoped_projection.js.map +0 -1
  614. package/dist/scripts/_lib/script_output.js.map +0 -1
  615. package/dist/scripts/_lib/spawn_env.js.map +0 -1
  616. package/dist/scripts/_lib/surface_tiers.js.map +0 -1
  617. package/dist/scripts/_lib/token_count.js.map +0 -1
  618. package/dist/scripts/_lib/trigger_eval_floors.js.map +0 -1
  619. package/dist/scripts/_lib/user_global_paths.js.map +0 -1
  620. package/dist/scripts/ai_council/modes.js.map +0 -1
  621. package/dist/scripts/ai_council/transport_resolver.js.map +0 -1
  622. package/dist/scripts/condense.js.map +0 -1
  623. package/dist/scripts/project_thin_rules.js.map +0 -1
  624. package/dist/server/app.js.map +0 -1
  625. package/dist/server/io/atomicMultiWrite.js.map +0 -1
  626. package/dist/server/io/atomicWrite.js.map +0 -1
  627. package/dist/server/io/sharedWriteCheck.js.map +0 -1
  628. package/dist/server/io/substituteTemplate.js.map +0 -1
  629. package/dist/server/io/yamlIO.js.map +0 -1
  630. package/dist/server/nicknameResolver.js.map +0 -1
  631. package/dist/server/port.js.map +0 -1
  632. package/dist/server/routes/discovery.js.map +0 -1
  633. package/dist/server/routes/install.js.map +0 -1
  634. package/dist/server/routes/ping.js.map +0 -1
  635. package/dist/server/routes/schema.js.map +0 -1
  636. package/dist/server/routes/settings.js.map +0 -1
  637. package/dist/server/routes/settingsChanges.js.map +0 -1
  638. package/dist/server/routes/userMd.js.map +0 -1
  639. package/dist/server/routes/wizard.js.map +0 -1
  640. package/dist/server/routes/workspace.js.map +0 -1
  641. package/dist/server/schemas/settings.js.map +0 -1
  642. package/dist/server/serverInfo.js.map +0 -1
  643. package/dist/server/token.js.map +0 -1
  644. package/dist/server/writeRoot.js.map +0 -1
  645. package/dist/shared/capabilities.js.map +0 -1
  646. package/dist/shared/interactiveContext.js.map +0 -1
  647. package/dist/shared/nicknamePrefill.js.map +0 -1
  648. package/dist/shared/settingsAsks.js.map +0 -1
  649. package/dist/shared/settingsCarveOut.js.map +0 -1
  650. package/dist/shared/settingsClasses.js.map +0 -1
  651. package/dist/shared/settingsConsent.js.map +0 -1
  652. package/dist/shared/settingsSurface.js.map +0 -1
  653. package/dist/shared/userMd/formAdapter.js.map +0 -1
  654. package/dist/shared/userMd/schema.js.map +0 -1
  655. package/dist/shared/userMd/utils.js.map +0 -1
  656. package/dist/ui/assets/index-Cxgy63kz.js.map +0 -1
  657. package/src/scripts/_lib/adr_frontmatter.test.ts +0 -365
  658. package/src/scripts/_lib/adversarial_council_gate.test.ts +0 -112
  659. package/src/scripts/_lib/adversarial_reconcile.test.ts +0 -197
  660. package/src/scripts/_lib/auto_dispatch.corpus.test.ts +0 -150
  661. package/src/scripts/_lib/secret_detector.test.ts +0 -108
  662. package/src/scripts/_lib/secret_detector_adversarial.test.ts +0 -116
  663. package/src/scripts/_lib/untrusted_content.test.ts +0 -175
  664. package/src/scripts/check_secret_leak.test.ts +0 -90
  665. package/src/scripts/design_slop_rules.test.ts +0 -239
  666. package/src/scripts/self_review_gate.test.ts +0 -296
  667. package/src/shared/capabilities.test.ts +0 -43
@@ -0,0 +1,720 @@
1
+ /**
2
+ * Publication orchestration extracted from `release.ts`.
3
+ *
4
+ * Step 1.1 of `road-to-release-publication-integrity`. The first refused
5
+ * implementation attempt died on `check_source_size_budget`: `release.ts` is
6
+ * 2,818 lines against a 1,500-line ceiling, so ANY net growth in it is refused —
7
+ * including a four-line version of the guard. This is the unit that makes room.
8
+ *
9
+ * The unit is chosen by dependency shape rather than by tidiness: the process and
10
+ * `gh` primitives plus everything that reaches GitHub — `die`, `run`, `git`,
11
+ * `gh`, the check-watch loop, the branch/tag/PR/release existence probes, the
12
+ * pushes and the merge. Taking the orchestration WITHOUT the primitives would
13
+ * make `release.ts` import them back and close a cycle.
14
+ *
15
+ * `release.ts` re-exports every public name that moved, so no caller and no test
16
+ * import path changes.
17
+ */
18
+ import { spawnSync } from 'node:child_process';
19
+ import * as fs from 'node:fs';
20
+ import process from 'node:process';
21
+
22
+ import { gh_argv_label, gh_retry } from './_lib/gh_transient.js';
23
+ import {
24
+ extract_changelog_section,
25
+ pr_body_from_section,
26
+ } from './_lib/release_material.js';
27
+
28
+ import {
29
+ CHANGELOG,
30
+ CalledProcessError,
31
+ GH_PR_BODY_LIMIT,
32
+ MAIN_BRANCH,
33
+ REMOTE,
34
+ REPO_ROOT,
35
+ SystemExitError,
36
+ _cap_body,
37
+ } from './release_env.js';
38
+
39
+ function die(msg: string, code = 2): never {
40
+ process.stderr.write(`error: ${msg}\n`);
41
+ throw new SystemExitError(code);
42
+ }
43
+
44
+ export interface RunResult {
45
+ returncode: number;
46
+ stdout: string;
47
+ stderr: string;
48
+ }
49
+
50
+ /**
51
+ * Thin subprocess wrapper with sane defaults.
52
+ *
53
+ * When `check` and `capture` are both True and the command fails, Python's
54
+ * default behaviour swallows stderr — callers only see a CalledProcessError
55
+ * with no hint of what went wrong. We catch that path and die with the actual
56
+ * stderr so release preflight failures are diagnosable without re-running with
57
+ * a debugger.
58
+ */
59
+ /**
60
+ * Drill/test seam — when set, every external command run() would spawn is
61
+ * answered by this function instead. The check/die/CalledProcessError
62
+ * semantics of run() still apply to the simulated result, so the drill
63
+ * exercises the REAL error paths of the orchestration (release_drill.ts).
64
+ */
65
+ type ExecOverride = (args: readonly string[]) => {
66
+ status: number;
67
+ stdout: string;
68
+ stderr: string;
69
+ };
70
+ let _exec_override: ExecOverride | null = null;
71
+ function _set_exec_override(fn: ExecOverride | null): void {
72
+ _exec_override = fn;
73
+ }
74
+
75
+ function run(
76
+ args: readonly string[],
77
+ opts: { check?: boolean; capture?: boolean; cwd?: string | null } = {},
78
+ ): RunResult {
79
+ const check = opts.check ?? true;
80
+ const capture = opts.capture ?? false;
81
+ const cwd = opts.cwd ?? REPO_ROOT;
82
+
83
+ const [cmd, ...rest] = args;
84
+ const res = _exec_override
85
+ ? { ..._exec_override(args), error: undefined as Error | undefined }
86
+ : spawnSync(cmd as string, rest, {
87
+ cwd,
88
+ encoding: 'utf-8',
89
+ // capture_output=True → pipe; else inherit so child writes straight to
90
+ // this process's stdout/stderr (text mode, matching subprocess text=True).
91
+ stdio: capture ? ['ignore', 'pipe', 'pipe'] : ['inherit', 'inherit', 'inherit'],
92
+ });
93
+
94
+ if (res.error) {
95
+ // FileNotFoundError analogue (ENOENT) and other spawn failures — Python
96
+ // would raise here; only the explicit catchers (have / _count_tests_current)
97
+ // handle it. Surface as a thrown error.
98
+ throw res.error;
99
+ }
100
+
101
+ const returncode = res.status ?? 0;
102
+ const stdout = capture ? res.stdout ?? '' : '';
103
+ const stderr = capture ? res.stderr ?? '' : '';
104
+
105
+ if (check && returncode !== 0) {
106
+ if (capture) {
107
+ const cmdStr = args.join(' ');
108
+ const out = (stderr || stdout || '').trim();
109
+ die(`command failed (${returncode}): ${cmdStr}\n${out}`);
110
+ }
111
+ // check && !capture → Python re-raises CalledProcessError; replicate.
112
+ throw new CalledProcessError(returncode, args);
113
+ }
114
+
115
+ return { returncode, stdout, stderr };
116
+ }
117
+
118
+ function git(args: readonly string[], opts: { capture?: boolean } = {}): string {
119
+ const capture = opts.capture ?? false;
120
+ const r = run(['git', ...args], { capture });
121
+ return capture ? r.stdout.trim() : '';
122
+ }
123
+
124
+ function _sleep_ms(ms: number): void {
125
+ Atomics.wait(new Int32Array(new SharedArrayBuffer(4)), 0, 0, ms);
126
+ }
127
+
128
+ /**
129
+ * `gh` with transient-failure retry and a readable death. Always captures, so
130
+ * the classifier can see stderr; `check: false` keeps the caller's fallback.
131
+ */
132
+ function gh(args: readonly string[], opts: { check?: boolean } = {}): RunResult {
133
+ const check = opts.check ?? true;
134
+ const r = gh_retry(args, (argv) => run(argv, { check: false, capture: true }), {
135
+ sleep: (ms) => (_exec_override ? undefined : _sleep_ms(ms)),
136
+ notify: (m) => process.stdout.write(`${m}\n`),
137
+ });
138
+ if (check && r.returncode !== 0) {
139
+ die(`${gh_argv_label(args)} failed (${r.returncode}):\n${(r.stderr || r.stdout).trim()}`);
140
+ }
141
+ // Mutating calls used to inherit stdio — echo, or the PR / release URL
142
+ // vanishes. Probes (`check: false`) stay quiet; their stdout is JSON.
143
+ if (check && r.stdout.trim()) {
144
+ process.stdout.write(`${r.stdout.trim()}\n`);
145
+ }
146
+ return r;
147
+ }
148
+
149
+ /**
150
+ * One name per failing check, from `gh pr checks --json name,bucket` output.
151
+ *
152
+ * Pure over the JSON text so the shape is testable without gh. Returns []
153
+ * when the payload is unparseable or nothing sits in the `fail` bucket —
154
+ * the caller then falls back to the raw watch output alone.
155
+ */
156
+ export function _failed_check_names(jsonText: string): string[] {
157
+ let parsed: unknown;
158
+ try {
159
+ parsed = JSON.parse(jsonText);
160
+ } catch {
161
+ return [];
162
+ }
163
+ if (!Array.isArray(parsed)) {
164
+ return [];
165
+ }
166
+ const names: string[] = [];
167
+ for (const entry of parsed) {
168
+ if (typeof entry !== 'object' || entry === null) {
169
+ continue;
170
+ }
171
+ const e = entry as Record<string, unknown>;
172
+ if (e['bucket'] === 'fail' && typeof e['name'] === 'string') {
173
+ names.push(e['name']);
174
+ }
175
+ }
176
+ return names;
177
+ }
178
+
179
+ /**
180
+ * Remediation lines for a set of failing check names.
181
+ *
182
+ * The watch table scrolls failures out of view on a busy PR, so the operator
183
+ * repeatedly saw only `pass`/`skipping` rows plus "PR checks failed" — the
184
+ * 9.14.0 failure mode, twice. Name the red checks explicitly and, for the
185
+ * shape detector, say where the fix belongs (main, never the release branch).
186
+ */
187
+ export function _failed_checks_report(names: readonly string[]): string {
188
+ if (names.length === 0) {
189
+ return '';
190
+ }
191
+ const lines: string[] = ['', 'Failing check(s):'];
192
+ for (const name of names) {
193
+ lines.push(` ❌ ${name}`);
194
+ }
195
+ if (names.includes('Release-PR shape detector')) {
196
+ lines.push(
197
+ '',
198
+ 'Release-PR shape: a release PR may only contain the version-bump',
199
+ 'allowlist. Land the out-of-shape files on main via their own PR, then',
200
+ 'merge main into the release branch — their release-PR diff becomes',
201
+ 'empty (docs/contracts/release-pr-gating.md § Mid-release fixes).',
202
+ );
203
+ }
204
+ if (names.includes('PR body equals CHANGELOG entry')) {
205
+ lines.push(
206
+ '',
207
+ 'Surface equality: the PR body drifted from the CHANGELOG entry. A',
208
+ 'resume run refreshes it from the branch head (release-truth Phase 1);',
209
+ 'never hand-edit the PR body away from the changelog section.',
210
+ );
211
+ }
212
+ if (names.includes('Curated highlights plausible against the span')) {
213
+ lines.push(
214
+ '',
215
+ 'Highlights: a curated `_none_` field contradicts the release span.',
216
+ 'Fill the curated head in CHANGELOG.md on the release branch — the',
217
+ 'gate output lists the deriving commits (release-truth Phase 2).',
218
+ );
219
+ }
220
+ if (names.includes('Blocking review findings dispositioned')) {
221
+ lines.push(
222
+ '',
223
+ 'Dispositions: a blocking/high self-review finding has no committed',
224
+ 'disposition. Ingest + adjudicate it in',
225
+ 'agents/evidence/release-findings/<version>.json (release-truth Phase 3):',
226
+ ' ./scripts-run src/scripts/check_finding_dispositions --ingest <findings.json>',
227
+ );
228
+ }
229
+ lines.push('', 'After fixing, resume with: task release -- --resume --yes', '');
230
+ return lines.join('\n');
231
+ }
232
+
233
+ /** Rounds of re-watching before an absent required check is called absent. */
234
+ const _NO_CHECKS_ROUNDS = 10;
235
+ /** Delay between those rounds — 10 × 60 s ≈ 10 minutes of tolerance. */
236
+ const _NO_CHECKS_DELAY_MS = 60_000;
237
+
238
+ /**
239
+ * Required status-check contexts for a branch, parsed from
240
+ * `gh api repos/{owner}/{repo}/rules/branches/{branch}`.
241
+ *
242
+ * That endpoint is the one that answers the question here: this repo protects
243
+ * `main` with a RULESET, and the classic `/branches/main/protection` API
244
+ * answers "Branch not protected" for it — so a check built on the classic
245
+ * endpoint would conclude "no required checks" and wave everything through.
246
+ *
247
+ * Any parse or shape surprise yields [] — the caller then behaves exactly as
248
+ * it did before this function existed.
249
+ */
250
+ export function _required_contexts_from_rules(json: string): string[] {
251
+ let parsed: unknown;
252
+ try {
253
+ parsed = JSON.parse(json);
254
+ } catch {
255
+ return [];
256
+ }
257
+ if (!Array.isArray(parsed)) return [];
258
+ const out: string[] = [];
259
+ for (const rule of parsed) {
260
+ const r = rule as { type?: unknown; parameters?: { required_status_checks?: unknown } };
261
+ if (r.type !== 'required_status_checks') continue;
262
+ const checks = r.parameters?.required_status_checks;
263
+ if (!Array.isArray(checks)) continue;
264
+ for (const c of checks) {
265
+ const ctx = (c as { context?: unknown }).context;
266
+ if (typeof ctx === 'string' && ctx !== '') out.push(ctx);
267
+ }
268
+ }
269
+ return out;
270
+ }
271
+
272
+ export type NoChecksAction = 'retry' | 'accept' | 'die';
273
+
274
+ /**
275
+ * What to do when `gh pr checks` reports no checks at all.
276
+ *
277
+ * The old code had one answer — accept — for two situations it could not tell
278
+ * apart: a repo that configures no required checks (nothing will ever arrive,
279
+ * accepting is correct) and a repo whose checks have simply not been
280
+ * dispatched yet (accepting merges, tags and publishes unvalidated).
281
+ *
282
+ * The branch's own protection rules separate them. Required contexts declared
283
+ * ⇒ something IS expected, so absence means not-yet, and the answer is to wait
284
+ * and finally to refuse. None declared ⇒ the pre-existing tolerance stands.
285
+ */
286
+ export function _no_checks_action(
287
+ required: readonly string[],
288
+ round: number,
289
+ maxRounds: number = _NO_CHECKS_ROUNDS,
290
+ ): NoChecksAction {
291
+ if (required.length === 0) return 'accept';
292
+ return round < maxRounds ? 'retry' : 'die';
293
+ }
294
+
295
+ /**
296
+ * Watch PR checks and tolerate the 'no checks' case ONLY where it is tolerable.
297
+ *
298
+ * `gh pr checks --watch` exits 1 both on real failures and when no checks are
299
+ * reported at all. Real failures still die.
300
+ *
301
+ * Measured 2026-08-06/07: during a critical GitHub Actions incident
302
+ * (15:22–02:04 UTC, webhook triggers throttled from 20:34) `pull_request`
303
+ * events were delivered 15–30 minutes late. The five-second grace period below
304
+ * expires long before that, so the old unconditional accept would have tagged
305
+ * `main` and published to npm without a single check having run. It did not
306
+ * only because `main` happened to be independently green.
307
+ *
308
+ * So the tolerance is now conditional on the branch declaring no required
309
+ * checks. Where it declares some, absence is treated as latency: re-watch, and
310
+ * refuse rather than release blind.
311
+ *
312
+ * A short grace period gives GitHub time to register workflow runs on a
313
+ * freshly-pushed branch.
314
+ */
315
+ function watch_pr_checks(branch: string): void {
316
+ if (_exec_override === null) {
317
+ // time.sleep(5) — blocking grace period for GitHub to register runs
318
+ // on a freshly-pushed branch. Skipped under the drill seam: there is
319
+ // no GitHub to wait for, and 5s per simulated wait adds up.
320
+ const until = Date.now() + 5000;
321
+ while (Date.now() < until) {
322
+ // busy-wait stand-in for time.sleep(5) without an event-loop yield.
323
+ }
324
+ }
325
+ // Rounds exist only for the no-checks-yet case below; every other outcome
326
+ // returns or dies on the first pass, exactly as before.
327
+ for (let round = 0; ; round++) {
328
+ // The branch is passed explicitly — `gh` inferring the PR from HEAD
329
+ // resolved to `main` mid-run once (2026-08-03, 9.16.0 resume) and the
330
+ // whole release died on "no pull requests found for branch main".
331
+ const proc = run(['gh', 'pr', 'checks', branch, '--watch'], {
332
+ check: false,
333
+ capture: true,
334
+ });
335
+ const output = ((proc.stdout || '') + (proc.stderr || '')).trim();
336
+ const returncode = proc.returncode;
337
+ if (returncode === 0) {
338
+ if (output) {
339
+ process.stdout.write(output + '\n');
340
+ }
341
+ return;
342
+ }
343
+ if (output.toLowerCase().includes('no checks reported')) {
344
+ const rules = run(
345
+ ['gh', 'api', `repos/{owner}/{repo}/rules/branches/${MAIN_BRANCH}`],
346
+ { check: false, capture: true },
347
+ );
348
+ const required = _required_contexts_from_rules(rules.stdout ?? '');
349
+ const action = _no_checks_action(required, round, _NO_CHECKS_ROUNDS);
350
+
351
+ if (action === 'accept') {
352
+ process.stdout.write(`⚠️ ${output}\n`);
353
+ process.stdout.write(
354
+ ' Continuing without check validation — configure required ' +
355
+ 'checks in branch protection to enforce this gate.\n',
356
+ );
357
+ return;
358
+ }
359
+ if (action === 'retry') {
360
+ process.stdout.write(
361
+ `⏳ no checks reported yet, but ${MAIN_BRANCH} requires ` +
362
+ `${String(required.length)} (${required.join(', ')}) — ` +
363
+ `waiting (${String(round + 1)}/${String(_NO_CHECKS_ROUNDS)})\n`,
364
+ );
365
+ if (_exec_override === null) {
366
+ const until = Date.now() + _NO_CHECKS_DELAY_MS;
367
+ while (Date.now() < until) {
368
+ // blocking wait, same shape as the grace period above
369
+ }
370
+ }
371
+ continue;
372
+ }
373
+ die(
374
+ `no checks reported for ${branch} after ` +
375
+ `${String(_NO_CHECKS_ROUNDS)} rounds, but ${MAIN_BRANCH} requires ` +
376
+ `${required.join(', ')}. Refusing to merge, tag and publish ` +
377
+ 'unvalidated — GitHub may be delaying event delivery (check ' +
378
+ 'githubstatus.com). Re-run with `task release -- --resume --yes` ' +
379
+ 'once the checks appear.',
380
+ );
381
+ }
382
+ if (output) {
383
+ process.stderr.write(output + '\n');
384
+ }
385
+ const summary = run(['gh', 'pr', 'checks', branch, '--json', 'name,bucket'], {
386
+ check: false,
387
+ capture: true,
388
+ });
389
+ const report = _failed_checks_report(_failed_check_names(summary.stdout ?? ''));
390
+ if (report) {
391
+ process.stderr.write(report + '\n');
392
+ }
393
+ die(`PR checks failed (exit ${returncode})`);
394
+ }
395
+ }
396
+
397
+ /**
398
+ * Push the release branch, integrating a remote that moved under us.
399
+ *
400
+ * A GitHub-side "Update branch" click (or a concurrent resume run) advances
401
+ * `origin/<branch>` while the local ref stays behind; a bare `git push` is
402
+ * then rejected with "fetch first" and the whole release run dies (measured
403
+ * 2026-08-03, 9.15.0). Same-branch commits are never ours to drop, so the
404
+ * recovery is merge-and-retry, never force-push.
405
+ */
406
+ /**
407
+ * True when git rejected the push because the remote ref moved ahead — the
408
+ * ONLY failure the merge-and-retry recovery below can repair.
409
+ *
410
+ * git's wording for this is stable across versions: the hint is `fetch first`
411
+ * / `Updates were rejected`, and the ref line carries `[rejected]` with
412
+ * `non-fast-forward` or `fetch first`. A stale lease is a SECOND wording —
413
+ * `[remote rejected]` + `cannot lock ref … but expected`; pinned in the tests.
414
+ */
415
+ export function _is_non_fast_forward(stderr: string, stdout: string): boolean {
416
+ const text = `${stderr}\n${stdout}`;
417
+ if (!/\[(?:remote )?rejected\]/i.test(text)) return false;
418
+ if (/cannot lock ref[^\n]*but expected/i.test(text)) return true;
419
+ return /(non-fast-forward|fetch first|behind its remote counterpart)/i.test(text);
420
+ }
421
+
422
+ function push_release_branch(branch: string): void {
423
+ const first = run(['git', 'push', '-u', REMOTE, branch], { check: false, capture: true });
424
+ if (first.returncode === 0) {
425
+ process.stdout.write(first.stdout);
426
+ process.stderr.write(first.stderr);
427
+ return;
428
+ }
429
+
430
+ // A push can fail for many reasons — a pre-push hook refusing the commit,
431
+ // no credentials, a protected branch. Only ONE of them is repaired by
432
+ // fetch+merge+retry, and the recovery's first step (`git fetch <branch>`)
433
+ // exits 128 for a branch that was never pushed. Taking that path
434
+ // unconditionally replaced every real error with
435
+ // `couldn't find remote ref <branch>` — measured 2026-08-06 on 9.26.0,
436
+ // where a pre-push gate rejection surfaced as a git-fetch crash and cost
437
+ // an hour of diagnosis pointed at the wrong layer.
438
+ if (!_is_non_fast_forward(first.stderr, first.stdout)) {
439
+ process.stdout.write(first.stdout);
440
+ process.stderr.write(first.stderr);
441
+ die(
442
+ `push of ${branch} failed (exit ${first.returncode}) and the remote ref did not move — ` +
443
+ 'this is not the fetch-and-retry case. The push output above is the real error ' +
444
+ '(a pre-push gate, credentials, or branch protection); fix that and re-run.',
445
+ );
446
+ }
447
+
448
+ process.stdout.write(`↻ ${REMOTE}/${branch} moved — integrating and retrying push\n`);
449
+ run(['git', 'fetch', REMOTE, branch]);
450
+ run(['git', 'merge', '--no-edit', `${REMOTE}/${branch}`]);
451
+ run(['git', 'push', '-u', REMOTE, branch]);
452
+ }
453
+
454
+ /** mergeStateStatus of the branch's PR ('' when the probe fails). */
455
+ function _pr_merge_state(branch: string): string {
456
+ const r = gh(['pr', 'view', branch, '--json', 'mergeStateStatus', '--jq', '.mergeStateStatus'], {
457
+ check: false,
458
+ });
459
+ return r.returncode === 0 ? r.stdout.trim() : '';
460
+ }
461
+
462
+ /**
463
+ * Bound on update-and-retry rounds in merge_release_pr. Three is deliberate:
464
+ * main receiving unrelated merges three times inside one checks-wait window
465
+ * means the queue is hot and a human should decide, not a loop.
466
+ */
467
+ const _MERGE_UPDATE_ROUNDS = 3;
468
+
469
+ /**
470
+ * Merge the release PR, absorbing a moving base branch.
471
+ *
472
+ * Branch protection requires the head to be up to date with `main`, and
473
+ * `main` moves constantly (dependabot, unrelated merges) — so between the
474
+ * checks-wait and the merge the PR routinely flips to BEHIND and a bare
475
+ * `gh pr merge` dies with "the head branch is not up to date with the base
476
+ * branch" (measured 2026-08-03, 9.16.0). Recovery is mechanical and safe by
477
+ * construction: merging `origin/main` into `release/X.Y.Z` makes the fix
478
+ * files identical on both sides, so the release-PR diff stays inside the
479
+ * version-bump allowlist (docs/contracts/release-pr-gating.md § Mid-release
480
+ * fixes) — do it here instead of aborting the run.
481
+ */
482
+ /**
483
+ * Re-derive the release-PR body from the CHANGELOG section at the current
484
+ * release-branch head and push it to the PR (release-truth Phase 1: one
485
+ * final source — late commits and maintainer edits on the branch must reach
486
+ * the PR body instead of leaving it frozen at plan time). Best-effort sync
487
+ * of the local branch first; a no-op when the derived body is unchanged.
488
+ */
489
+ function _target_from_branch(branch: string): string {
490
+ return branch.replace(/^release\//u, '');
491
+ }
492
+
493
+ function _refresh_pr_body_from_head(branch: string, target: string): void {
494
+ run(['git', 'pull', '--ff-only', REMOTE, branch], { check: false });
495
+ const changelog = fs.readFileSync(CHANGELOG, 'utf-8');
496
+ const section = extract_changelog_section(changelog, target);
497
+ if (!section) {
498
+ die(`CHANGELOG.md at ${branch} head carries no section for ${target} — cannot derive PR body`);
499
+ }
500
+ const capped = _cap_body(section!.body, GH_PR_BODY_LIMIT - 200, '`CHANGELOG.md` in this PR');
501
+ const body = pr_body_from_section(capped, target);
502
+ const live = gh(['pr', 'view', branch, '--json', 'body', '-q', '.body'], { check: false });
503
+ if (live.returncode === 0 && live.stdout.replace(/\r\n/gu, '\n').trim() === body.trim()) {
504
+ return;
505
+ }
506
+ gh(['pr', 'edit', branch, '--body', body]);
507
+ }
508
+
509
+ function merge_release_pr(branch: string, wait_for_checks: boolean): void {
510
+ if (git(['rev-parse', '--abbrev-ref', 'HEAD'], { capture: true }) !== branch) {
511
+ run(['git', 'checkout', branch]);
512
+ }
513
+ for (let round = 0; round <= _MERGE_UPDATE_ROUNDS; round++) {
514
+ // One final generation step at the final head: every merge attempt
515
+ // first re-derives the PR body from the branch-head CHANGELOG, so
516
+ // update rounds and maintainer edits can never desynchronize it.
517
+ _refresh_pr_body_from_head(branch, _target_from_branch(branch));
518
+ if (_pr_merge_state(branch) !== 'BEHIND') {
519
+ const merged = run(['gh', 'pr', 'merge', branch, '--merge', '--delete-branch'], {
520
+ check: false,
521
+ });
522
+ if (merged.returncode === 0) {
523
+ return;
524
+ }
525
+ if (_pr_merge_state(branch) !== 'BEHIND') {
526
+ // Not the moving-base failure — surface it unchanged.
527
+ throw new CalledProcessError(merged.returncode, [
528
+ 'gh',
529
+ 'pr',
530
+ 'merge',
531
+ branch,
532
+ '--merge',
533
+ '--delete-branch',
534
+ ]);
535
+ }
536
+ // BEHIND appeared between the probe and the merge — fall through
537
+ // to the update below.
538
+ }
539
+ if (round === _MERGE_UPDATE_ROUNDS) {
540
+ break;
541
+ }
542
+ process.stdout.write(
543
+ `↻ head behind ${MAIN_BRANCH} (update round ${round + 1}/${_MERGE_UPDATE_ROUNDS}) — ` +
544
+ `merging ${REMOTE}/${MAIN_BRANCH} into ${branch} and re-running checks\n`,
545
+ );
546
+ run(['git', 'fetch', REMOTE, MAIN_BRANCH]);
547
+ run(['git', 'merge', '--no-edit', `${REMOTE}/${MAIN_BRANCH}`]);
548
+ push_release_branch(branch);
549
+ if (wait_for_checks) {
550
+ watch_pr_checks(branch);
551
+ }
552
+ }
553
+ die(
554
+ `release PR is still behind ${MAIN_BRANCH} after ${_MERGE_UPDATE_ROUNDS} update round(s) — ` +
555
+ `${MAIN_BRANCH} is moving faster than the checks complete. ` +
556
+ 'Re-run when the queue quiets down: task release -- --resume --yes',
557
+ );
558
+ }
559
+
560
+ function have(bin: string): boolean {
561
+ const res = spawnSync('which', [bin], { encoding: 'utf-8', stdio: ['ignore', 'pipe', 'pipe'] });
562
+ if (res.error) {
563
+ // FileNotFoundError on `which` itself → treat as not found (returncode != 0).
564
+ return false;
565
+ }
566
+ return (res.status ?? 1) === 0;
567
+ }
568
+
569
+ // ─── resume-mode state probes ────────────────────────────────────────────────
570
+
571
+ function _branch_exists_local(branch: string): boolean {
572
+ const r = run(['git', 'rev-parse', '--verify', '--quiet', `refs/heads/${branch}`], {
573
+ check: false,
574
+ capture: true,
575
+ });
576
+ return r.returncode === 0;
577
+ }
578
+
579
+ function _branch_exists_remote(branch: string): boolean {
580
+ const r = run(['git', 'ls-remote', '--exit-code', '--heads', REMOTE, branch], {
581
+ check: false,
582
+ capture: true,
583
+ });
584
+ return r.returncode === 0;
585
+ }
586
+
587
+ function _tag_exists_local(tag: string): boolean {
588
+ return git(['tag', '-l', tag], { capture: true }).split('\n').includes(tag);
589
+ }
590
+
591
+ function _tag_exists_remote(tag: string): boolean {
592
+ const r = run(['git', 'ls-remote', '--exit-code', '--tags', REMOTE, tag], {
593
+ check: false,
594
+ capture: true,
595
+ });
596
+ return r.returncode === 0;
597
+ }
598
+
599
+ /**
600
+ * True when git rejected a tag push because the ref already exists on the
601
+ * remote. Wording pinned from the real failure (2026-08-09, 9.28.0 — two
602
+ * concurrent resume runs, the loser crashed):
603
+ *
604
+ * ! [remote rejected] 9.28.0 -> 9.28.0 (cannot lock ref 'refs/tags/9.28.0': reference already exists)
605
+ *
606
+ * plus the `[rejected] … (already exists)` variant git emits when the local
607
+ * and remote tag objects differ.
608
+ */
609
+ export function _is_tag_already_exists(stderr: string, stdout: string): boolean {
610
+ const text = `${stderr}\n${stdout}`;
611
+ return /\[(?:remote )?rejected\]/i.test(text) && /already exists/i.test(text);
612
+ }
613
+
614
+ /** Peeled commit the remote tag points at, or null when the tag is absent. */
615
+ function _remote_tag_commit(tag: string): string | null {
616
+ const r = run(['git', 'ls-remote', REMOTE, `refs/tags/${tag}`, `refs/tags/${tag}^{}`], {
617
+ check: false,
618
+ capture: true,
619
+ });
620
+ if (r.returncode !== 0) return null;
621
+ const lines = r.stdout.trim().split('\n').filter(Boolean);
622
+ if (lines.length === 0) return null;
623
+ // An annotated tag lists the tag object AND the peeled `^{}` commit — the
624
+ // peeled line wins so the comparison is commit-vs-commit regardless of
625
+ // whether the two runs minted distinct tag objects for the same commit.
626
+ const peeled = lines.find((l) => l.trimEnd().endsWith('^{}'));
627
+ return (peeled ?? (lines[0] as string)).split('\t')[0] ?? null;
628
+ }
629
+
630
+ /**
631
+ * Push a tag, tolerating exactly ONE failure: the concurrent-release race.
632
+ * `_tag_exists_remote` in step 8 is a live check, but between it and this
633
+ * push a parallel `task release` run can land the same tag (measured
634
+ * 2026-08-09, 9.28.0). When the remote tag already points at the same commit
635
+ * as the local one, the repository IS in the desired state — continue. Any
636
+ * other rejection, and a same-name tag on a DIFFERENT commit, stays fatal
637
+ * with the push output as the error.
638
+ */
639
+ function _push_tag(tag: string): void {
640
+ const first = run(['git', 'push', REMOTE, tag], { check: false, capture: true });
641
+ if (first.returncode === 0) {
642
+ process.stdout.write(first.stdout);
643
+ process.stderr.write(first.stderr);
644
+ return;
645
+ }
646
+ if (_is_tag_already_exists(first.stderr, first.stdout)) {
647
+ const remote = _remote_tag_commit(tag);
648
+ const local = git(['rev-list', '-n', '1', tag], { capture: true });
649
+ if (remote !== null && remote === local) {
650
+ process.stdout.write(
651
+ `↻ tag ${tag} already on ${REMOTE} at the same commit — a parallel run pushed it; continuing\n`,
652
+ );
653
+ return;
654
+ }
655
+ process.stdout.write(first.stdout);
656
+ process.stderr.write(first.stderr);
657
+ die(
658
+ `tag ${tag} exists on ${REMOTE} pointing at ${remote ?? '<unreadable>'} while the local tag ` +
659
+ `points at ${local} — refusing to overwrite a published tag; ` +
660
+ 'delete the wrong one deliberately and re-run',
661
+ );
662
+ }
663
+ process.stdout.write(first.stdout);
664
+ process.stderr.write(first.stderr);
665
+ die(
666
+ `push of tag ${tag} failed (exit ${first.returncode}) — ` +
667
+ 'the push output above is the real error (a pre-push gate, credentials, or protection)',
668
+ );
669
+ }
670
+
671
+ /** Most recent PR (any state) with `release/X.Y.Z` as head, or null. */
672
+ function _pr_for_branch(branch: string): Record<string, unknown> | null {
673
+ const argv = ['pr', 'list', '--head', branch, '--state', 'all', '--json', 'number,state,url'];
674
+ const r = gh([...argv, '--limit', '1'], { check: false });
675
+ if (r.returncode !== 0) {
676
+ return null;
677
+ }
678
+ let items: unknown;
679
+ try {
680
+ items = JSON.parse(r.stdout || '[]');
681
+ } catch {
682
+ return null;
683
+ }
684
+ return Array.isArray(items) && items.length > 0 ? (items[0] as Record<string, unknown>) : null;
685
+ }
686
+
687
+ function _release_exists(tag: string): boolean {
688
+ const r = run(['gh', 'release', 'view', tag], { check: false, capture: true });
689
+ return r.returncode === 0;
690
+ }
691
+
692
+
693
+ // ─── re-export surface ────────────────────────────────────────────────────────
694
+ // Named individually rather than by marking each declaration `export`, so the
695
+ // boundary this module presents is one readable list rather than a property of
696
+ // 30 scattered keywords.
697
+ export {
698
+ _MERGE_UPDATE_ROUNDS,
699
+ _branch_exists_local,
700
+ _branch_exists_remote,
701
+ _pr_for_branch,
702
+ _pr_merge_state,
703
+ _push_tag,
704
+ _refresh_pr_body_from_head,
705
+ _release_exists,
706
+ _remote_tag_commit,
707
+ _set_exec_override,
708
+ _sleep_ms,
709
+ _tag_exists_local,
710
+ _tag_exists_remote,
711
+ _target_from_branch,
712
+ die,
713
+ gh,
714
+ git,
715
+ have,
716
+ merge_release_pr,
717
+ push_release_branch,
718
+ run,
719
+ watch_pr_checks,
720
+ };