@bongos/core 1.21.175 → 1.21.177

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 (1719) hide show
  1. package/.bongos-core.json +3371 -1636
  2. package/.claude/skills/ask-for-help/SKILL.md +4 -4
  3. package/.claude/skills/backlog-review/SKILL.md +1 -1
  4. package/.claude/skills/blocker-review/SKILL.md +2 -2
  5. package/.claude/skills/blocker-solve/SKILL.md +4 -4
  6. package/.claude/skills/bongos-feedback/SKILL.md +1 -1
  7. package/.claude/skills/bug-triage/SKILL.md +8 -8
  8. package/.claude/skills/builder-backup/SKILL.md +3 -3
  9. package/.claude/skills/builder-claim/SKILL.md +5 -5
  10. package/.claude/skills/builder-cost/SKILL.md +5 -5
  11. package/.claude/skills/builder-end/SKILL.md +6 -6
  12. package/.claude/skills/builder-exit/SKILL.md +2 -2
  13. package/.claude/skills/builder-key/SKILL.md +6 -6
  14. package/.claude/skills/builder-reauth/SKILL.md +4 -4
  15. package/.claude/skills/builder-redteam/SKILL.md +3 -3
  16. package/.claude/skills/builder-release/SKILL.md +3 -3
  17. package/.claude/skills/builder-sequence/SKILL.md +8 -8
  18. package/.claude/skills/builder-setup/SKILL.md +4 -4
  19. package/.claude/skills/builder-ship/SKILL.md +7 -7
  20. package/.claude/skills/builder-stage/SKILL.md +8 -8
  21. package/.claude/skills/builder-start/SKILL.md +4 -4
  22. package/.claude/skills/collab-review/SKILL.md +5 -5
  23. package/.claude/skills/design/SKILL.md +6 -4
  24. package/.claude/skills/design-sync/SKILL.md +3 -3
  25. package/.claude/skills/figma-design-sync/SKILL.md +4 -4
  26. package/.claude/skills/fix-task/SKILL.md +8 -8
  27. package/.claude/skills/goal-close/SKILL.md +9 -9
  28. package/.claude/skills/goal-create/SKILL.md +18 -18
  29. package/.claude/skills/grade-recover/SKILL.md +8 -8
  30. package/.claude/skills/grade-sweep/SKILL.md +15 -15
  31. package/.claude/skills/idea-triage/SKILL.md +15 -15
  32. package/.claude/skills/merge-mode/SKILL.md +14 -14
  33. package/.claude/skills/new-project/SKILL.md +5 -5
  34. package/.claude/skills/owner-review/SKILL.md +1 -1
  35. package/.claude/skills/planning-session/SKILL.md +15 -15
  36. package/.claude/skills/priority-session/SKILL.md +6 -6
  37. package/.claude/skills/read-session-export/SKILL.md +3 -3
  38. package/.claude/skills/recall/SKILL.md +7 -7
  39. package/.claude/skills/scan-before-install/SKILL.md +3 -3
  40. package/.claude/skills/session-handoff/SKILL.md +1 -1
  41. package/.claude/skills/ship-check/SKILL.md +3 -3
  42. package/.claude/skills/status/SKILL.md +3 -3
  43. package/.claude/skills/strand-fix/SKILL.md +6 -6
  44. package/.claude/skills/worktree-clean/SKILL.md +4 -4
  45. package/.gitattributes +12 -32
  46. package/GOVERNMENT.md +1 -1
  47. package/README.md +8 -8
  48. package/bin/bongos.js +23 -23
  49. package/clients/bongos-client/README.md +2 -2
  50. package/clients/bongos-client/bongos-client.global.js +22 -4
  51. package/clients/bongos-client/index.cjs +22 -4
  52. package/clients/bongos-client/index.d.ts +33 -4
  53. package/clients/bongos-client/index.mjs +21 -3
  54. package/config/branding.neutral.json +1 -1
  55. package/config/design-tokens.schema.json +1 -1
  56. package/config/modules.neutral.json +1 -3
  57. package/config/scheduled-routines.json +3 -8
  58. package/docs/adr/0029-status-page-outage-resilience.md +6 -6
  59. package/docs/adr/0091-bounding-the-kernel-and-db-carve.md +1 -1
  60. package/docs/adr/0093-tranche-2-core-carve-sequence.md +1 -1
  61. package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
  62. package/docs/adr/0294-cli-sessions-do-not-expire.md +1 -1
  63. package/docs/adr/0383-sessions-end-after-ten-idle-days.md +35 -0
  64. package/docs/adr/0384-the-raise-page-is-a-hub-module-builders-edit-in-place.md +31 -0
  65. package/docs/adr/README.md +2 -0
  66. package/docs/api/openapi.json +606 -44
  67. package/docs/api-reference.md +25 -12
  68. package/docs/architecture.md +8 -7
  69. package/docs/canonical-permissions.md +4 -4
  70. package/docs/copy-inventory.md +1370 -1411
  71. package/docs/copy-registry.json +2136 -2536
  72. package/docs/design/demonolith-plan.md +6 -6
  73. package/docs/design/modular-architecture/00-research-report.md +1 -1
  74. package/docs/design/project-startup-direction.md +2 -2
  75. package/docs/design/projects-hub-direction-v2.md +1 -1
  76. package/docs/design/reviews/hall-v2/README.md +2 -2
  77. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  78. package/docs/file-map.md +92 -96
  79. package/docs/handoff-template.md +5 -5
  80. package/docs/module-api-changelog.md +7 -3
  81. package/docs/modules-contract.md +8 -7
  82. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +1 -1
  83. package/docs/onboarding/diagrams/02-rank-ladder.mmd +1 -1
  84. package/docs/onboarding/diagrams/03-drachmae-karma.mmd +1 -1
  85. package/docs/onboarding/diagrams/04-architecture.mmd +1 -1
  86. package/docs/onboarding/diagrams/05-versioning.mmd +1 -1
  87. package/docs/onboarding/diagrams/README.md +5 -9
  88. package/docs/onboarding/diagrams/assertions.json +3 -3
  89. package/docs/onboarding/slash-commands.md +2 -2
  90. package/docs/packs/artist.md +4 -4
  91. package/docs/packs/engineer.md +11 -10
  92. package/docs/packs/ideator.md +7 -7
  93. package/docs/page-inventory.json +20 -1
  94. package/docs/page-readings.json +4387 -4603
  95. package/docs/recipes/README.md +1 -1
  96. package/docs/recipes/audit-replay.md +4 -4
  97. package/docs/recipes/autobongos-windows-host.md +6 -6
  98. package/docs/recipes/bongos-cli-release.md +2 -2
  99. package/docs/recipes/claude-design-loop.md +7 -7
  100. package/docs/recipes/core-release-pipeline.md +19 -19
  101. package/docs/recipes/failed-ship-recovery-proof.md +2 -2
  102. package/docs/recipes/figma-design-loop.md +6 -6
  103. package/docs/recipes/gds-db-backup.md +9 -9
  104. package/docs/recipes/instance-deploy.md +3 -3
  105. package/docs/recipes/instance-first-run.md +1 -1
  106. package/docs/recipes/multi-builder-merge.md +2 -2
  107. package/docs/recipes/ops-gotchas.md +13 -10
  108. package/docs/recipes/packaging-the-core.md +6 -6
  109. package/docs/recipes/parallel-goal-waves.md +4 -4
  110. package/docs/recipes/private-npm-distribution.md +9 -9
  111. package/docs/recipes/redteam-patrol.md +5 -5
  112. package/docs/recipes/render-pilot.md +2 -2
  113. package/docs/recipes/reranking-a-goals-board.md +2 -2
  114. package/docs/recipes/search-index-ingestion.md +5 -5
  115. package/docs/recipes/self-host.md +1 -1
  116. package/docs/recipes/ship-and-regrade.md +4 -4
  117. package/docs/recipes/staging-environment.md +1 -1
  118. package/docs/recipes/standalone-live-docs.md +1 -1
  119. package/docs/recipes/ui-look-before-you-ship.md +2 -2
  120. package/docs/recipes/upgrading-the-core.md +11 -11
  121. package/docs/recipes/windows-builders.md +18 -18
  122. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +6 -6
  123. package/docs/research/task-network-map-readability.md +3 -3
  124. package/migrations/core_278_builder_tester_tag.sql +18 -0
  125. package/migrations/core_279_bongos_shipper_new_scripts_path.sql +13 -0
  126. package/modules/agents/lib/answer-hold.js +1 -1
  127. package/modules/agents/lib/gate.js +1 -1
  128. package/modules/agents/lib/validate.js +1 -1
  129. package/modules/autonomy/db.js +9 -0
  130. package/modules/autonomy/gauge.js +1 -1
  131. package/modules/autonomy/governor-docket.js +2 -2
  132. package/modules/autonomy/module.json +2 -2
  133. package/modules/autonomy/pollers/daily-checks.js +262 -0
  134. package/modules/autonomy/pollers/routine-timers.js +9 -7
  135. package/modules/autonomy/rank-roles.js +64 -0
  136. package/modules/autonomy/routes/autonomy.js +3 -3
  137. package/modules/autonomy/server-schedule.js +37 -0
  138. package/modules/builder-settings/interaction-prefs.js +1 -1
  139. package/modules/builder-settings/render-prefs.js +1 -1
  140. package/modules/builder-settings/routes/settings.js +1 -1
  141. package/modules/builder-settings/skill-prefs.js +2 -2
  142. package/modules/builder-settings/wandering-prefs.js +2 -2
  143. package/modules/copy-desk/module.json +2 -2
  144. package/modules/copy-desk/page-data.js +5 -5
  145. package/modules/copy-desk/page-decisions.js +13 -1
  146. package/modules/copy-desk/proposals.js +4 -4
  147. package/modules/copy-desk/registry.js +2 -2
  148. package/modules/copy-desk/routes/copy-desk-release.js +119 -0
  149. package/modules/copy-desk/routes/copy-desk.js +3 -12
  150. package/modules/copy-desk/skills/tweak/SKILL.md +12 -12
  151. package/modules/copy-desk/tests/copy_flags.mjs +1 -1
  152. package/modules/copy-desk/tests/copy_no_cms.mjs +7 -3
  153. package/modules/copy-desk/tests/copy_proposals.mjs +2 -2
  154. package/modules/copy-desk/tests/copy_queue.mjs +1 -1
  155. package/modules/design-styles/skills/README.md +4 -4
  156. package/modules/design-styles/skills/imagegen-frontend-mobile/SKILL.md +1 -1
  157. package/modules/design-styles/skills/imagegen-frontend-web/SKILL.md +1 -1
  158. package/modules/discord/bug-attachments.js +1 -1
  159. package/modules/discord/ship-broadcast.js +1 -1
  160. package/modules/economy/achievements.js +49 -7
  161. package/modules/economy/cost-classify.js +6 -6
  162. package/modules/economy/cost-report.js +1 -1
  163. package/modules/economy/cost.js +1 -1
  164. package/modules/economy/credits.js +2 -1
  165. package/modules/economy/idea-size.js +2 -2
  166. package/modules/economy/reward.js +2 -0
  167. package/modules/economy/routes/cost.js +1 -1
  168. package/modules/economy/streak.js +43 -4
  169. package/modules/government/asks.js +1 -1
  170. package/modules/government/board.js +19 -2
  171. package/modules/government/catalog.js +3 -0
  172. package/modules/government/migrations/government_033_idea_vote.sql +46 -0
  173. package/modules/government/protected-surfaces.json +48 -47
  174. package/modules/government/recommendations.js +6 -2
  175. package/modules/government/routes/government.js +1 -1
  176. package/modules/grading/generated-provenance.js +13 -5
  177. package/modules/grading/grade-engine.js +1 -1
  178. package/modules/grading/grader-rubric.json +1 -1
  179. package/modules/grading/grader-score.js +1 -1
  180. package/modules/grading/grader-workers/index.js +1 -1
  181. package/modules/grading/grader.js +1 -1
  182. package/modules/grading/routes/grade.js +1 -1
  183. package/modules/hall-ui/public/atlas.html +5 -7
  184. package/modules/hall-ui/public/atlas.js +1 -1
  185. package/modules/hall-ui/public/atlas.states.json +1 -1
  186. package/modules/hall-ui/public/blockers.css +9 -0
  187. package/modules/hall-ui/public/blockers.html +4 -4
  188. package/modules/hall-ui/public/blockers.js +29 -30
  189. package/modules/hall-ui/public/board-room.css +5 -17
  190. package/modules/hall-ui/public/board-room.html +5 -6
  191. package/modules/hall-ui/public/board-room.js +41 -23
  192. package/modules/hall-ui/public/board-room.states.json +1 -1
  193. package/modules/hall-ui/public/brand-apply.js +1 -1
  194. package/modules/hall-ui/public/brand-holes.js +1 -1
  195. package/modules/hall-ui/public/builders.js +40 -86
  196. package/modules/hall-ui/public/city-decide.js +18 -4
  197. package/modules/hall-ui/public/city.html +1 -1
  198. package/modules/hall-ui/public/collab.html +1 -1
  199. package/modules/hall-ui/public/commands.html +6 -9
  200. package/modules/hall-ui/public/copy-desk.html +1 -1
  201. package/modules/hall-ui/public/copy-desk.js +2 -2
  202. package/modules/hall-ui/public/craft-mode.js +4 -0
  203. package/modules/hall-ui/public/deploy.html +6 -2
  204. package/modules/hall-ui/public/deploy.js +21 -13
  205. package/modules/hall-ui/public/diagrams.css +1 -1
  206. package/modules/hall-ui/public/diagrams.html +5 -8
  207. package/modules/hall-ui/public/diagrams.states.json +1 -1
  208. package/modules/hall-ui/public/drachmae.html +3 -7
  209. package/modules/hall-ui/public/fleet.html +3 -2
  210. package/modules/hall-ui/public/fleet.js +0 -4
  211. package/modules/hall-ui/public/gate.html +7 -7
  212. package/modules/hall-ui/public/gate.js +58 -77
  213. package/modules/hall-ui/public/goal-map.html +1 -1
  214. package/modules/hall-ui/public/goals-page.js +5 -5
  215. package/modules/hall-ui/public/goals-render.js +10 -11
  216. package/modules/hall-ui/public/goals.css +10 -0
  217. package/modules/hall-ui/public/goals.html +14 -7
  218. package/modules/hall-ui/public/government.html +3 -5
  219. package/modules/hall-ui/public/government.js +1 -5
  220. package/modules/hall-ui/public/hall-render.js +117 -57
  221. package/modules/hall-ui/public/hall-widgets.js +11 -11
  222. package/modules/hall-ui/public/idea.html +1 -1
  223. package/modules/hall-ui/public/ideas.html +3 -1
  224. package/modules/hall-ui/public/ideas.js +1 -0
  225. package/modules/hall-ui/public/index.html +12 -6
  226. package/modules/hall-ui/public/index.states.json +1 -1
  227. package/modules/hall-ui/public/mine-lens.js +1 -1
  228. package/modules/hall-ui/public/modules.html +7 -10
  229. package/modules/hall-ui/public/modules.js +0 -2
  230. package/modules/hall-ui/public/my-agents.html +1 -1
  231. package/modules/hall-ui/public/palette.js +5 -5
  232. package/modules/hall-ui/public/primer.html +4 -9
  233. package/modules/hall-ui/public/profile-connections.js +10 -2
  234. package/modules/hall-ui/public/profile-roles.js +3 -10
  235. package/modules/hall-ui/public/profile.html +12 -10
  236. package/modules/hall-ui/public/profile.js +13 -17
  237. package/modules/hall-ui/public/project-settings.html +3 -4
  238. package/modules/hall-ui/public/project-settings.js +0 -3
  239. package/modules/hall-ui/public/ranks.html +5 -11
  240. package/modules/hall-ui/public/ranks.js +6 -8
  241. package/modules/hall-ui/public/roadmap.css +0 -2
  242. package/modules/hall-ui/public/roadmap.html +1 -1
  243. package/modules/hall-ui/public/roadmap.js +16 -51
  244. package/modules/hall-ui/public/roster.html +1 -1
  245. package/modules/hall-ui/public/sessions.html +6 -8
  246. package/modules/hall-ui/public/sessions.js +7 -7
  247. package/modules/hall-ui/public/settings.html +1 -1
  248. package/modules/hall-ui/public/shell-trail.js +1 -1
  249. package/modules/hall-ui/public/shell.js +17 -17
  250. package/modules/hall-ui/public/street-deck.css +2 -1
  251. package/modules/hall-ui/public/street-deck.js +10 -2
  252. package/modules/hall-ui/public/street-desk.js +16 -5
  253. package/modules/hall-ui/public/street.html +1 -1
  254. package/modules/hall-ui/public/studio-lib.js +4 -0
  255. package/modules/hall-ui/public/studio.css +2 -0
  256. package/modules/hall-ui/public/studio.html +1 -1
  257. package/modules/hall-ui/public/studio.js +27 -1
  258. package/modules/hall-ui/public/style.css +43 -26
  259. package/modules/hall-ui/public/task-detail.js +10 -7
  260. package/modules/hall-ui/public/task.css +2 -0
  261. package/modules/hall-ui/public/task.html +3 -1
  262. package/modules/hall-ui/public/task.js +23 -7
  263. package/modules/hall-ui/public/thinking.html +1 -1
  264. package/modules/hall-ui/public/tweak-editor.html +1 -1
  265. package/modules/hall-ui/public/vote-control.js +208 -0
  266. package/modules/hall-ui/public/watch.html +3 -5
  267. package/modules/hall-ui/public/watch.js +5 -4
  268. package/modules/hall-ui/public/welcome-boot.css +130 -0
  269. package/modules/hall-ui/public/welcome-boot.js +334 -0
  270. package/modules/hall-ui/public/welcome-day.webp +0 -0
  271. package/modules/hall-ui/public/welcome-night.webp +0 -0
  272. package/modules/hall-ui/public/work-summary.js +1 -1
  273. package/modules/hall-ui/public/work.css +1 -0
  274. package/modules/hall-ui/public/work.html +3 -1
  275. package/modules/hall-ui/public/work.js +2 -1
  276. package/modules/hall-ui/records/accomplishments.md +16 -0
  277. package/modules/hall-ui/records/hall-ask-card.md +9 -0
  278. package/modules/hall-ui/records/karma-vote-control.md +13 -0
  279. package/modules/hall-ui/records/oversight-family.md +1 -1
  280. package/modules/hall-ui/records/profile-connections.md +2 -0
  281. package/modules/hall-ui/records/profile-roles.md +1 -1
  282. package/modules/hall-ui/records/reading-rooms.md +1 -1
  283. package/modules/hall-ui/records/welcome-tower.md +50 -0
  284. package/modules/ideas/migrations/ideas_011_idea_votes.sql +31 -0
  285. package/modules/ideas/projection.js +1 -1
  286. package/modules/ideas/routes/blockers.js +3 -3
  287. package/modules/ideas/routes/inbox.js +29 -1
  288. package/modules/ideas/routes/ratify-goal.js +1 -1
  289. package/modules/ideas/routing.js +1 -1
  290. package/modules/ideas/templates.js +1 -1
  291. package/modules/ideas/trail-descent.js +1 -1
  292. package/modules/ideas/trail-size.js +1 -1
  293. package/modules/ideas/votes.js +93 -0
  294. package/modules/lifecycle/abandon-leftovers.js +1 -1
  295. package/modules/lifecycle/cascade.js +1 -1
  296. package/modules/lifecycle/conflict-resolve.js +13 -21
  297. package/modules/lifecycle/criterion-ref.js +1 -1
  298. package/modules/lifecycle/db-analytics.js +57 -4
  299. package/modules/lifecycle/db-deps-criteria.js +1 -1
  300. package/modules/lifecycle/db-ship.js +2 -2
  301. package/modules/lifecycle/db-tasks.js +2 -2
  302. package/modules/lifecycle/db-versions.js +1 -1
  303. package/modules/lifecycle/db.js +2 -0
  304. package/modules/lifecycle/dead-deps.js +3 -3
  305. package/modules/lifecycle/dependency-advisory.js +3 -3
  306. package/modules/lifecycle/goal-category.js +1 -1
  307. package/modules/lifecycle/goal-forest.js +1 -1
  308. package/modules/lifecycle/goal-task-relevance-advisory.js +1 -1
  309. package/modules/lifecycle/kickoff-checklist.js +1 -1
  310. package/modules/lifecycle/kickoff-seed.js +1 -1
  311. package/modules/lifecycle/lifecycle.js +2 -0
  312. package/modules/lifecycle/merge-reach.js +29 -15
  313. package/modules/lifecycle/missing-dep-classify.js +3 -3
  314. package/modules/lifecycle/module.json +2 -1
  315. package/modules/lifecycle/page-tweak-approve.js +85 -1
  316. package/modules/lifecycle/page-tweak-hold.js +1 -1
  317. package/modules/lifecycle/publish-reconciler.js +1 -2
  318. package/modules/lifecycle/rot.js +1 -1
  319. package/modules/lifecycle/routes/artist-gate.js +1 -1
  320. package/modules/lifecycle/routes/gate-approvals.js +22 -1
  321. package/modules/lifecycle/routes/goals.js +1 -1
  322. package/modules/lifecycle/routes/task-route-helpers.js +1 -1
  323. package/modules/lifecycle/routes/task-votes.js +54 -0
  324. package/modules/lifecycle/routes/task-write-routes.js +1 -1
  325. package/modules/lifecycle/routes/tasks.js +2 -2
  326. package/modules/lifecycle/routes/versions.js +2 -2
  327. package/modules/lifecycle/ship-card.js +4 -4
  328. package/modules/lifecycle/ship-preflight.js +1 -1
  329. package/modules/lifecycle/task-classifier.js +1 -1
  330. package/modules/lifecycle/task-status.js +1 -1
  331. package/modules/lifecycle/task-visual-db.js +1 -1
  332. package/modules/memory/learnings.js +1 -1
  333. package/modules/memory/pollers/search-index.js +2 -2
  334. package/modules/memory/routes/learnings.js +1 -1
  335. package/modules/memory/routes/memory.js +1 -1
  336. package/modules/memory/search.js +2 -2
  337. package/modules/npm-release/release.js +1 -1
  338. package/modules/onboarding/howto-moments.js +1 -1
  339. package/modules/onboarding/newcomer-restock.js +3 -3
  340. package/modules/onboarding/onboarding.js +1 -1
  341. package/modules/pixel-art/skills/otb-tile-generate/SKILL.md +1 -1
  342. package/modules/platform-identity/origin-containment.js +1 -1
  343. package/modules/platform-identity/publish-gate.js +1 -1
  344. package/modules/platform-identity/tests/platform-identity.mjs +1 -1
  345. package/modules/provisioning/capacity.js +1 -1
  346. package/modules/provisioning/core-upgrade.js +15 -9
  347. package/modules/provisioning/credential-preflight.js +3 -3
  348. package/modules/provisioning/disconnect.js +1 -1
  349. package/modules/provisioning/dns-resolves.js +1 -1
  350. package/modules/provisioning/module.json +1 -1
  351. package/modules/provisioning/onboard-plan.js +1 -1
  352. package/modules/provisioning/paid-shape-gate.js +2 -2
  353. package/modules/provisioning/planet-physics.js +11 -2
  354. package/modules/provisioning/pollers/liveness-sweep.js +1 -1
  355. package/modules/provisioning/pollers/runner-drift-notify.js +5 -5
  356. package/modules/provisioning/provisioning.js +2 -2
  357. package/modules/provisioning/render-lookup.js +1 -1
  358. package/modules/provisioning/render-standup.js +3 -3
  359. package/modules/provisioning/repo-private.js +1 -1
  360. package/modules/provisioning/routes/callback-page.js +1 -1
  361. package/modules/provisioning/routes/core-upgrade.js +23 -3
  362. package/modules/provisioning/routes/provisioning.js +2 -2
  363. package/modules/provisioning/routes/render-standup.js +1 -1
  364. package/modules/provisioning/routes/repo-private.js +1 -1
  365. package/modules/provisioning/soft-limits.js +1 -1
  366. package/modules/provisioning/starter-bundles.js +4 -2
  367. package/modules/provisioning/tests/provisioning.mjs +1 -1
  368. package/modules/public-landing/public/account.html +4 -6
  369. package/modules/public-landing/public/assets/cosmos.css +13 -6
  370. package/modules/public-landing/public/connections.html +4 -6
  371. package/modules/public-landing/public/contact.html +4 -6
  372. package/modules/public-landing/public/guild.html +4 -6
  373. package/modules/public-landing/public/index.html +11 -9
  374. package/modules/public-landing/public/invitations.html +4 -6
  375. package/modules/public-landing/public/privacy.html +4 -6
  376. package/modules/public-landing/public/projects.html +168 -46
  377. package/modules/public-landing/public/terms.html +4 -6
  378. package/modules/raise/content/copy.json +40 -0
  379. package/modules/raise/content/nda.html +39 -0
  380. package/modules/raise/content/settings.json +49 -0
  381. package/modules/raise/db.js +95 -0
  382. package/modules/raise/migrations/raise_001_tables.sql +71 -0
  383. package/modules/raise/module.json +28 -0
  384. package/modules/raise/page.js +194 -0
  385. package/modules/raise/public/edit.js +152 -0
  386. package/modules/raise/public/favicon.svg +1 -0
  387. package/modules/raise/public/logo-ink.svg +1 -0
  388. package/modules/raise/public/logo-night.svg +1 -0
  389. package/modules/raise/public/mode.js +8 -0
  390. package/modules/raise/public/raise.css +234 -0
  391. package/modules/raise/public/raise.js +91 -0
  392. package/modules/raise/raise.js +174 -0
  393. package/modules/raise/routes/raise.js +152 -0
  394. package/modules/raise/views/gate.html +39 -0
  395. package/modules/raise/views/nda.html +21 -0
  396. package/modules/raise/views/page.html +133 -0
  397. package/modules/raise/web.js +72 -0
  398. package/modules/render-deploy/deploys.js +1 -1
  399. package/modules/render-deploy/render.js +2 -2
  400. package/modules/security/secret-scrub.js +3 -3
  401. package/modules/security/security.js +1 -1
  402. package/modules/security/tests/artifact_scan.mjs +1 -1
  403. package/modules/security/tests/mirror.mjs +1 -1
  404. package/modules/security/tests/scan_store.mjs +1 -1
  405. package/modules/sessions/db.js +2 -2
  406. package/modules/sessions/pulse.js +2 -2
  407. package/modules/sessions/routes/sessions.js +1 -1
  408. package/modules/specialities/specialities.js +1 -1
  409. package/modules/status-ui/public/README.md +3 -4
  410. package/modules/status-ui/public/index.html +5 -31
  411. package/modules/status-ui/public/status.js +6 -174
  412. package/modules/status-ui/public/style.css +4 -133
  413. package/modules/ui-design/docs/design-contract.md +3 -3
  414. package/modules/ui-design/kit/README.md +1 -1
  415. package/modules/ui-design/kit/serve.js +13 -4
  416. package/modules/ui-design/scripts/design-sync.js +1 -1
  417. package/modules/ui-design/scripts/figma-design-sync.js +1 -1
  418. package/modules/ui-design/scripts/validate-design.js +1 -1
  419. package/package-lock.json +27 -11
  420. package/package.json +2 -3
  421. package/release-notes.json +186 -0
  422. package/scripts/bongos/CLAUDE.md +15 -0
  423. package/scripts/bongos/abandon.js +137 -0
  424. package/scripts/bongos/accessibility-replay.js +195 -0
  425. package/scripts/bongos/address-park-sweep.sh +91 -0
  426. package/scripts/bongos/adopt-detect.js +123 -0
  427. package/scripts/bongos/adopt-import.js +111 -0
  428. package/scripts/bongos/adopt-preflight.js +187 -0
  429. package/scripts/bongos/adr-namespace.js +273 -0
  430. package/scripts/bongos/agent-invoke.js +689 -0
  431. package/scripts/bongos/agents-sync.js +502 -0
  432. package/scripts/bongos/api-alias-caller-scan.js +256 -0
  433. package/scripts/bongos/api-artifacts.js +91 -0
  434. package/scripts/bongos/api.js +86 -0
  435. package/scripts/bongos/api.ps1 +26 -0
  436. package/scripts/bongos/architect-audit.js +294 -0
  437. package/scripts/bongos/artifact-audit.js +326 -0
  438. package/scripts/bongos/artifact-format.js +203 -0
  439. package/scripts/bongos/ask.js +231 -0
  440. package/scripts/bongos/audit-authorship.sh +324 -0
  441. package/scripts/bongos/audit-deps.js +189 -0
  442. package/scripts/bongos/audit-gate.js +121 -0
  443. package/scripts/bongos/audit-rank-roles.js +131 -0
  444. package/scripts/bongos/audit-replay.sh +205 -0
  445. package/scripts/bongos/autobongos-digest.js +123 -0
  446. package/scripts/bongos/autobongos-grade-cap.js +187 -0
  447. package/scripts/bongos/autobongos-loop.js +210 -0
  448. package/scripts/bongos/autobongos-run.js +1361 -0
  449. package/scripts/bongos/autobongos-service.cmd +50 -0
  450. package/scripts/bongos/autobongos-service.ps1 +270 -0
  451. package/scripts/bongos/autobongos-tweak-lane.js +262 -0
  452. package/scripts/bongos/autobongos-verify.js +618 -0
  453. package/scripts/bongos/autonomy-gate.js +135 -0
  454. package/scripts/bongos/autonomy-gauge-statusline.js +124 -0
  455. package/scripts/bongos/autonomy-gauge.js +84 -0
  456. package/scripts/bongos/backfill-cost.js +176 -0
  457. package/scripts/bongos/backfill-disciplines.js +144 -0
  458. package/scripts/bongos/backfill-session-earnings.js +123 -0
  459. package/scripts/bongos/backfill-session-types.js +87 -0
  460. package/scripts/bongos/backfill-sessions.js +411 -0
  461. package/scripts/bongos/backfill-subagent-rewards.js +485 -0
  462. package/scripts/bongos/backfill-task-rewards.js +413 -0
  463. package/scripts/bongos/backlog-review.js +399 -0
  464. package/scripts/bongos/backup-dropin-sweep.sh +95 -0
  465. package/scripts/bongos/backup.js +116 -0
  466. package/scripts/bongos/baseline-staleness.js +217 -0
  467. package/scripts/bongos/bfg-principal-token.js +65 -0
  468. package/scripts/bongos/bug-attachment-audit.js +149 -0
  469. package/scripts/bongos/bug-attachment-recover.js +198 -0
  470. package/scripts/bongos/bug-triage.js +292 -0
  471. package/scripts/bongos/build-bongos.js +94 -0
  472. package/scripts/bongos/bump-version.js +221 -0
  473. package/scripts/bongos/capture.js +481 -0
  474. package/scripts/bongos/category-advisory-guard.js +206 -0
  475. package/scripts/bongos/ci-grade.js +82 -0
  476. package/scripts/bongos/claim-recall.js +112 -0
  477. package/scripts/bongos/claim.js +789 -0
  478. package/scripts/bongos/claude-materialize.js +1200 -0
  479. package/scripts/bongos/claude-md-template.js +142 -0
  480. package/scripts/bongos/cleanup-orphans.js +74 -0
  481. package/scripts/bongos/cli-lib.js +1226 -0
  482. package/scripts/bongos/client-baseurl-guard.js +116 -0
  483. package/scripts/bongos/codemod-rename-scripts-gds.js +380 -0
  484. package/scripts/bongos/conductor-dispatch.js +535 -0
  485. package/scripts/bongos/context-pack.js +326 -0
  486. package/scripts/bongos/control-manifest.js +199 -0
  487. package/scripts/bongos/copy-apply.js +758 -0
  488. package/scripts/bongos/copy-inventory.js +571 -0
  489. package/scripts/bongos/core-origin-follow.js +185 -0
  490. package/scripts/bongos/core-pin-sync.js +260 -0
  491. package/scripts/bongos/cost-report.js +63 -0
  492. package/scripts/bongos/cost.js +47 -0
  493. package/scripts/bongos/credential-presence.js +296 -0
  494. package/scripts/bongos/cutover-codemod.js +240 -0
  495. package/scripts/bongos/db-backup-nightly.sh +232 -0
  496. package/scripts/bongos/db-backup-offsite.sh +267 -0
  497. package/scripts/bongos/demote.js +45 -0
  498. package/scripts/bongos/deploy-divergence.js +454 -0
  499. package/scripts/bongos/deploy-main-audit-gate.sh +97 -0
  500. package/scripts/bongos/design-sync.js +12 -0
  501. package/scripts/bongos/dev-box-guard.js +166 -0
  502. package/scripts/bongos/dev-lib.js +722 -0
  503. package/scripts/bongos/dev.js +645 -0
  504. package/scripts/bongos/device-flow-help.js +72 -0
  505. package/scripts/bongos/diagnose-achievements.js +118 -0
  506. package/scripts/bongos/diagram-facts.js +355 -0
  507. package/scripts/bongos/discord-channels.js +77 -0
  508. package/scripts/bongos/do-api.js +109 -0
  509. package/scripts/bongos/doc-cli-guard.js +274 -0
  510. package/scripts/bongos/doc-comment-coverage.js +139 -0
  511. package/scripts/bongos/doc-control-claims.js +170 -0
  512. package/scripts/bongos/docs-entropy.js +453 -0
  513. package/scripts/bongos/doctor.js +493 -0
  514. package/scripts/bongos/enroll-control-plane.js +101 -0
  515. package/scripts/bongos/exec-path-guard.js +564 -0
  516. package/scripts/bongos/feedback-send.js +249 -0
  517. package/scripts/bongos/fetch-art-key.js +106 -0
  518. package/scripts/bongos/fetch-sound-prefs.js +126 -0
  519. package/scripts/bongos/figma-design-sync.js +11 -0
  520. package/scripts/bongos/find-untested.js +371 -0
  521. package/scripts/bongos/fitness-checks-error-envelope.js +134 -0
  522. package/scripts/bongos/fitness-checks-identity.js +332 -0
  523. package/scripts/bongos/fitness-checks-packaging.js +132 -0
  524. package/scripts/bongos/fitness-checks-route-pins.js +76 -0
  525. package/scripts/bongos/fitness-checks-vocabulary.js +392 -0
  526. package/scripts/bongos/fitness-checks-write-validation.js +157 -0
  527. package/scripts/bongos/fitness-lib.js +127 -0
  528. package/scripts/bongos/fitness-migration-contraction.js +50 -0
  529. package/scripts/bongos/fitness-ratchets.js +594 -0
  530. package/scripts/bongos/fitness.js +1498 -0
  531. package/scripts/bongos/forwarder.js +80 -0
  532. package/scripts/bongos/gate-review.js +330 -0
  533. package/scripts/bongos/gating.js +348 -0
  534. package/scripts/{gds → bongos}/gds-db-backup.service +6 -6
  535. package/scripts/{gds → bongos}/gds-db-backup.timer +4 -4
  536. package/scripts/{gds → bongos}/gds-db-offsite.service +4 -4
  537. package/scripts/{gds → bongos}/gds-db-offsite.timer +4 -4
  538. package/scripts/bongos/gds-literal-scan.js +196 -0
  539. package/scripts/bongos/gen-api-client.js +576 -0
  540. package/scripts/bongos/gen-api-docs.js +1111 -0
  541. package/scripts/bongos/gen-atlas.js +366 -0
  542. package/scripts/bongos/gen-diagrams.js +608 -0
  543. package/scripts/bongos/gen-file-map.js +337 -0
  544. package/scripts/bongos/gen-freshness.js +32 -0
  545. package/scripts/bongos/gen-interaction-posture.js +122 -0
  546. package/scripts/bongos/gen-repo-map.js +540 -0
  547. package/scripts/bongos/gen-role-responsibilities.js +134 -0
  548. package/scripts/bongos/gen-session-index.js +243 -0
  549. package/scripts/bongos/gen-sounds.js +176 -0
  550. package/scripts/bongos/git-merge-regen.js +254 -0
  551. package/scripts/bongos/go-live.js +1071 -0
  552. package/scripts/bongos/goal.js +272 -0
  553. package/scripts/bongos/government-walk.js +1477 -0
  554. package/scripts/bongos/grade-correlation-audit.js +310 -0
  555. package/scripts/bongos/grade-replay.js +237 -0
  556. package/scripts/bongos/grade-smoke.js +205 -0
  557. package/scripts/bongos/home-isolation-guard.js +126 -0
  558. package/scripts/bongos/hooks/pre-push.js +211 -0
  559. package/scripts/bongos/howto.js +145 -0
  560. package/scripts/bongos/http-api-client.js +81 -0
  561. package/scripts/bongos/identity-strip.js +75 -0
  562. package/scripts/bongos/init.js +1159 -0
  563. package/scripts/bongos/install-git-hooks.js +200 -0
  564. package/scripts/bongos/instance-apex.js +38 -0
  565. package/scripts/bongos/intent-retry.js +52 -0
  566. package/scripts/bongos/key-card.js +222 -0
  567. package/scripts/bongos/key-status.js +126 -0
  568. package/scripts/bongos/land-watch.js +201 -0
  569. package/scripts/bongos/leak-scan-allowlist.js +293 -0
  570. package/scripts/bongos/learning-capture.js +145 -0
  571. package/scripts/bongos/lib.sh +74 -0
  572. package/scripts/bongos/linkify-refs.js +655 -0
  573. package/scripts/bongos/lint-infra-exec.js +70 -0
  574. package/scripts/bongos/lint-migrations.js +102 -0
  575. package/scripts/bongos/lint-workflow-exec.js +63 -0
  576. package/scripts/bongos/local-preview-lib.js +128 -0
  577. package/scripts/bongos/local-preview.js +82 -0
  578. package/scripts/bongos/login.js +360 -0
  579. package/scripts/bongos/main-audit.js +625 -0
  580. package/scripts/bongos/me.js +97 -0
  581. package/scripts/bongos/memory-map.js +176 -0
  582. package/scripts/bongos/merge-lock.js +71 -0
  583. package/scripts/bongos/migration-namespace.js +313 -0
  584. package/scripts/bongos/mirror-lineage-check.js +343 -0
  585. package/scripts/bongos/mirror-redact.js +350 -0
  586. package/scripts/bongos/module-artifact.js +289 -0
  587. package/scripts/bongos/module-assess-docs.js +238 -0
  588. package/scripts/bongos/module-assess-installs.js +228 -0
  589. package/scripts/bongos/module-assess-score.js +111 -0
  590. package/scripts/bongos/module-assess-security.js +252 -0
  591. package/scripts/bongos/module-assess-tests.js +278 -0
  592. package/scripts/bongos/module-assess-version.js +92 -0
  593. package/scripts/bongos/module-error-report.js +148 -0
  594. package/scripts/{gds → bongos}/module-test-runner/README.md +3 -3
  595. package/scripts/{gds → bongos}/module-test-runner/module-tests.yml +2 -2
  596. package/scripts/bongos/module-test-runner.js +414 -0
  597. package/scripts/bongos/module.js +1376 -0
  598. package/scripts/bongos/move-escalation.js +141 -0
  599. package/scripts/{gds → bongos}/newcomer-floor.config.json +1 -1
  600. package/scripts/bongos/newcomer-floor.js +421 -0
  601. package/scripts/{gds → bongos}/newcomer-floor.templates.json +13 -13
  602. package/scripts/bongos/newcomer-floor.test.js +235 -0
  603. package/scripts/bongos/next-number.js +163 -0
  604. package/scripts/bongos/oauth-secret.js +202 -0
  605. package/scripts/bongos/onboard.js +267 -0
  606. package/scripts/bongos/onboarding-analyze.js +226 -0
  607. package/scripts/bongos/onboarding-config.js +179 -0
  608. package/scripts/bongos/onboarding-ship.js +92 -0
  609. package/scripts/bongos/pack-env-prefix.js +73 -0
  610. package/scripts/bongos/package-core.js +1200 -0
  611. package/scripts/bongos/page-inventory.js +348 -0
  612. package/scripts/bongos/page-reader.js +722 -0
  613. package/scripts/bongos/paste-token.js +212 -0
  614. package/scripts/bongos/plain-cards.js +351 -0
  615. package/scripts/bongos/portability-smoke-art.sh +85 -0
  616. package/scripts/bongos/portability-smoke-memory.sh +176 -0
  617. package/scripts/bongos/preflight.js +214 -0
  618. package/scripts/bongos/probe-cache.js +246 -0
  619. package/scripts/bongos/prove-strict-versioning.js +284 -0
  620. package/scripts/bongos/provision-auto-upgrade.js +162 -0
  621. package/scripts/bongos/provision-byo-host.js +68 -0
  622. package/scripts/bongos/provision-capacity.js +79 -0
  623. package/scripts/bongos/provision-caps.js +63 -0
  624. package/scripts/bongos/provision-config.js +233 -0
  625. package/scripts/bongos/provision-core-upgrade.js +1166 -0
  626. package/scripts/bongos/provision-disconnect.js +88 -0
  627. package/scripts/bongos/provision-github-setup.js +168 -0
  628. package/scripts/bongos/provision-net.js +357 -0
  629. package/scripts/bongos/provision-pin-key.js +176 -0
  630. package/scripts/bongos/provision-pin-replay.js +126 -0
  631. package/scripts/bongos/provision-process.js +170 -0
  632. package/scripts/bongos/provision-render.js +201 -0
  633. package/scripts/bongos/provision-repo-auth.js +164 -0
  634. package/scripts/bongos/provision-repo-private.js +98 -0
  635. package/scripts/bongos/provision-repo.js +1337 -0
  636. package/scripts/bongos/provision-teardown.js +106 -0
  637. package/scripts/bongos/provision-units.js +469 -0
  638. package/scripts/bongos/provision.js +1479 -0
  639. package/scripts/bongos/publish-credential-check.js +66 -0
  640. package/scripts/bongos/publish-integration-gate.js +142 -0
  641. package/scripts/bongos/publish-manifest.js +440 -0
  642. package/scripts/bongos/publish-watch.js +268 -0
  643. package/scripts/bongos/pulse.js +338 -0
  644. package/scripts/bongos/push-main.js +56 -0
  645. package/scripts/bongos/push-path-brief.js +100 -0
  646. package/scripts/bongos/read-session-export.js +359 -0
  647. package/scripts/bongos/reauth.js +155 -0
  648. package/scripts/bongos/recall.js +183 -0
  649. package/scripts/bongos/redteam-patrol.js +437 -0
  650. package/scripts/bongos/regen-instance-docs.js +47 -0
  651. package/scripts/bongos/release-core.js +80 -0
  652. package/scripts/bongos/release-notes.js +271 -0
  653. package/scripts/bongos/release.js +139 -0
  654. package/scripts/bongos/rename-history-check.js +369 -0
  655. package/scripts/bongos/rename-ledger-prose.js +482 -0
  656. package/scripts/bongos/render-api.js +197 -0
  657. package/scripts/bongos/render-check.js +206 -0
  658. package/scripts/bongos/render-ideas.js +226 -0
  659. package/scripts/bongos/render-payload.js +85 -0
  660. package/scripts/bongos/repo-metrics.js +363 -0
  661. package/scripts/bongos/review-sheet.js +108 -0
  662. package/scripts/bongos/role-pack-guard.js +142 -0
  663. package/scripts/bongos/route-shadow-guard.js +175 -0
  664. package/scripts/bongos/routine-schedule.js +318 -0
  665. package/scripts/bongos/run-routine.js +257 -0
  666. package/scripts/bongos/run-unit-tests.js +654 -0
  667. package/scripts/bongos/runner-drift.js +151 -0
  668. package/scripts/bongos/sandbox-stage.js +459 -0
  669. package/scripts/bongos/scope-map-guard.js +300 -0
  670. package/scripts/bongos/scope-roster-guard.js +118 -0
  671. package/scripts/bongos/seam-wiring-guard.js +275 -0
  672. package/scripts/bongos/search-ingest-db.js +288 -0
  673. package/scripts/bongos/search-ingest-md.js +269 -0
  674. package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +152 -0
  675. package/scripts/bongos/seed-bv1-profiles-tasks.js +135 -0
  676. package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +390 -0
  677. package/scripts/bongos/seed-staging.sh +117 -0
  678. package/scripts/bongos/seed-verify-criteria.js +124 -0
  679. package/scripts/bongos/sequence.js +597 -0
  680. package/scripts/bongos/session-cost.js +430 -0
  681. package/scripts/bongos/session-digest-build.js +293 -0
  682. package/scripts/bongos/session-digest.js +200 -0
  683. package/scripts/bongos/session-eval.js +631 -0
  684. package/scripts/bongos/session-transcript-build.js +155 -0
  685. package/scripts/bongos/session-transcript-upload.js +29 -0
  686. package/scripts/bongos/session.js +404 -0
  687. package/scripts/bongos/setup.js +646 -0
  688. package/scripts/bongos/ship-check.js +89 -0
  689. package/scripts/bongos/ship-deploy-target.js +393 -0
  690. package/scripts/bongos/ship-escalation.js +167 -0
  691. package/scripts/bongos/ship-finish.js +420 -0
  692. package/scripts/bongos/ship-flow.js +1217 -0
  693. package/scripts/bongos/ship-git.js +100 -0
  694. package/scripts/bongos/ship-grade-steps.js +547 -0
  695. package/scripts/bongos/ship-grade.js +426 -0
  696. package/scripts/bongos/ship-honesty.js +314 -0
  697. package/scripts/bongos/ship-io.js +139 -0
  698. package/scripts/bongos/ship-land.js +1130 -0
  699. package/scripts/bongos/ship-memory-sync.js +249 -0
  700. package/scripts/bongos/ship-merge-gate.js +225 -0
  701. package/scripts/bongos/ship-merge.js +466 -0
  702. package/scripts/bongos/ship-mode-ask.js +138 -0
  703. package/scripts/bongos/ship-mode-manual.js +54 -0
  704. package/scripts/bongos/ship-preflight-steps.js +399 -0
  705. package/scripts/bongos/ship-regen.js +291 -0
  706. package/scripts/bongos/ship-resume.js +201 -0
  707. package/scripts/bongos/ship-session-upload.js +313 -0
  708. package/scripts/bongos/ship-state.js +110 -0
  709. package/scripts/bongos/ship-surprise.js +84 -0
  710. package/scripts/bongos/ship-visual.js +75 -0
  711. package/scripts/bongos/ship.js +382 -0
  712. package/scripts/bongos/shipping-mode.js +71 -0
  713. package/scripts/bongos/skill-lint.js +250 -0
  714. package/scripts/bongos/skill-preflight.js +361 -0
  715. package/scripts/bongos/smoke-batch-claim.sh +238 -0
  716. package/scripts/bongos/smoke-batch-release.sh +316 -0
  717. package/scripts/bongos/smoke-claim-consistency.sh +222 -0
  718. package/scripts/bongos/smoke-dependencies.sh +143 -0
  719. package/scripts/bongos/smoke-gds.js +256 -0
  720. package/scripts/bongos/smoke-write.sh +275 -0
  721. package/scripts/bongos/source-text-test-scan.js +106 -0
  722. package/scripts/bongos/spark.js +294 -0
  723. package/scripts/bongos/stale-worktrees.js +212 -0
  724. package/scripts/bongos/start-goals.js +102 -0
  725. package/scripts/bongos/start.js +1090 -0
  726. package/scripts/bongos/status.js +545 -0
  727. package/scripts/bongos/strand-watch.js +315 -0
  728. package/scripts/bongos/stranded-rows.js +200 -0
  729. package/scripts/bongos/stray-unit-sweep.sh +71 -0
  730. package/scripts/bongos/surface.js +101 -0
  731. package/scripts/bongos/task.js +273 -0
  732. package/scripts/bongos/test-path-guard.js +99 -0
  733. package/scripts/bongos/triage.js +742 -0
  734. package/scripts/bongos/turn-end-sound.js +74 -0
  735. package/scripts/bongos/tweak-halt.js +70 -0
  736. package/scripts/bongos/tweak-renders.js +200 -0
  737. package/scripts/bongos/uat.js +120 -0
  738. package/scripts/bongos/ui-kit-transform.js +43 -0
  739. package/scripts/bongos/update-channel.js +512 -0
  740. package/scripts/bongos/update-sweep.js +829 -0
  741. package/scripts/bongos/upgrade-artist-gate.js +46 -0
  742. package/scripts/bongos/upgrade-commit-identity.js +32 -0
  743. package/scripts/bongos/upgrade-migrate.js +224 -0
  744. package/scripts/bongos/upgrade-operator.js +73 -0
  745. package/scripts/bongos/upgrade-outcome.js +174 -0
  746. package/scripts/bongos/upgrade.js +1499 -0
  747. package/scripts/bongos/validate-design.js +12 -0
  748. package/scripts/bongos/version-close.js +621 -0
  749. package/scripts/bongos/version-literal-guard.js +140 -0
  750. package/scripts/bongos/version-select.js +79 -0
  751. package/scripts/bongos/visual-review-nudge.js +39 -0
  752. package/scripts/bongos/wedge-remedy.js +174 -0
  753. package/scripts/bongos/worktree-claim-guard.js +130 -0
  754. package/scripts/bongos/worktree.js +449 -0
  755. package/scripts/discord/post.js +1 -1
  756. package/scripts/gds/README.md +9 -0
  757. package/scripts/gds/abandon.js +6 -136
  758. package/scripts/gds/accessibility-replay.js +5 -194
  759. package/scripts/gds/address-park-sweep.sh +7 -90
  760. package/scripts/gds/adopt-detect.js +5 -121
  761. package/scripts/gds/adopt-import.js +5 -109
  762. package/scripts/gds/adopt-preflight.js +5 -185
  763. package/scripts/gds/adr-namespace.js +5 -271
  764. package/scripts/gds/agent-invoke.js +5 -687
  765. package/scripts/gds/agents-sync.js +5 -500
  766. package/scripts/gds/api-alias-caller-scan.js +5 -255
  767. package/scripts/gds/api-artifacts.js +6 -0
  768. package/scripts/gds/api.js +6 -85
  769. package/scripts/gds/api.ps1 +8 -26
  770. package/scripts/gds/architect-audit.js +6 -293
  771. package/scripts/gds/artifact-audit.js +5 -324
  772. package/scripts/gds/artifact-format.js +6 -203
  773. package/scripts/gds/ask.js +5 -229
  774. package/scripts/gds/audit-authorship.sh +7 -328
  775. package/scripts/gds/audit-deps.js +6 -188
  776. package/scripts/gds/audit-gate.js +5 -119
  777. package/scripts/gds/audit-rank-roles.js +6 -171
  778. package/scripts/gds/audit-replay.sh +7 -204
  779. package/scripts/gds/autobongos-digest.js +5 -121
  780. package/scripts/gds/autobongos-grade-cap.js +5 -186
  781. package/scripts/gds/autobongos-loop.js +5 -208
  782. package/scripts/gds/autobongos-run.js +5 -1359
  783. package/scripts/gds/autobongos-service.cmd +8 -49
  784. package/scripts/gds/autobongos-service.ps1 +8 -270
  785. package/scripts/gds/autobongos-tweak-lane.js +5 -261
  786. package/scripts/gds/autobongos-verify.js +5 -616
  787. package/scripts/gds/autonomy-gate.js +5 -133
  788. package/scripts/gds/autonomy-gauge-statusline.js +5 -122
  789. package/scripts/gds/autonomy-gauge.js +5 -82
  790. package/scripts/gds/backfill-cost.js +6 -175
  791. package/scripts/gds/backfill-disciplines.js +5 -142
  792. package/scripts/gds/backfill-session-earnings.js +5 -121
  793. package/scripts/gds/backfill-session-types.js +5 -85
  794. package/scripts/gds/backfill-sessions.js +5 -409
  795. package/scripts/gds/backfill-subagent-rewards.js +5 -483
  796. package/scripts/gds/backfill-task-rewards.js +5 -411
  797. package/scripts/gds/backlog-review.js +6 -398
  798. package/scripts/gds/backup-dropin-sweep.sh +7 -94
  799. package/scripts/gds/backup.js +6 -115
  800. package/scripts/gds/baseline-staleness.js +5 -215
  801. package/scripts/gds/bfg-principal-token.js +6 -64
  802. package/scripts/gds/bug-attachment-audit.js +5 -147
  803. package/scripts/gds/bug-attachment-recover.js +5 -196
  804. package/scripts/gds/bug-triage.js +6 -291
  805. package/scripts/gds/build-bongos.js +5 -92
  806. package/scripts/gds/bump-version.js +5 -219
  807. package/scripts/gds/capture.js +6 -480
  808. package/scripts/gds/category-advisory-guard.js +5 -205
  809. package/scripts/gds/ci-grade.js +6 -81
  810. package/scripts/gds/claim-recall.js +6 -111
  811. package/scripts/gds/claim.js +6 -788
  812. package/scripts/gds/claude-materialize.js +5 -1198
  813. package/scripts/gds/claude-md-template.js +5 -140
  814. package/scripts/gds/cleanup-orphans.js +6 -73
  815. package/scripts/gds/cli-lib.js +6 -1204
  816. package/scripts/gds/client-baseurl-guard.js +5 -114
  817. package/scripts/gds/conductor-dispatch.js +6 -534
  818. package/scripts/gds/context-pack.js +6 -325
  819. package/scripts/gds/control-manifest.js +5 -197
  820. package/scripts/gds/copy-apply.js +5 -756
  821. package/scripts/gds/copy-inventory.js +5 -569
  822. package/scripts/gds/core-origin-follow.js +5 -184
  823. package/scripts/gds/core-pin-sync.js +5 -258
  824. package/scripts/gds/cost-report.js +6 -62
  825. package/scripts/gds/cost.js +6 -46
  826. package/scripts/gds/credential-presence.js +5 -294
  827. package/scripts/gds/cutover-codemod.js +5 -239
  828. package/scripts/gds/db-backup-nightly.sh +7 -231
  829. package/scripts/gds/db-backup-offsite.sh +7 -266
  830. package/scripts/gds/demote.js +6 -44
  831. package/scripts/gds/deploy-divergence.js +6 -445
  832. package/scripts/gds/deploy-main-audit-gate.sh +7 -96
  833. package/scripts/gds/design-sync.js +5 -10
  834. package/scripts/gds/dev-box-guard.js +5 -164
  835. package/scripts/gds/dev-lib.js +5 -721
  836. package/scripts/gds/dev.js +5 -643
  837. package/scripts/gds/device-flow-help.js +5 -70
  838. package/scripts/gds/diagnose-achievements.js +5 -116
  839. package/scripts/gds/diagram-facts.js +6 -355
  840. package/scripts/gds/discord-channels.js +5 -75
  841. package/scripts/gds/do-api.js +6 -109
  842. package/scripts/gds/doc-cli-guard.js +5 -266
  843. package/scripts/gds/doc-comment-coverage.js +5 -137
  844. package/scripts/gds/doc-control-claims.js +5 -166
  845. package/scripts/gds/docs-entropy.js +5 -443
  846. package/scripts/gds/doctor.js +6 -492
  847. package/scripts/gds/enroll-control-plane.js +5 -99
  848. package/scripts/gds/exec-path-guard.js +5 -562
  849. package/scripts/gds/feedback-send.js +5 -247
  850. package/scripts/gds/fetch-art-key.js +5 -104
  851. package/scripts/gds/fetch-sound-prefs.js +5 -124
  852. package/scripts/gds/figma-design-sync.js +5 -9
  853. package/scripts/gds/find-untested.js +5 -369
  854. package/scripts/gds/fitness-checks-error-envelope.js +5 -133
  855. package/scripts/gds/fitness-checks-identity.js +5 -342
  856. package/scripts/gds/fitness-checks-packaging.js +5 -131
  857. package/scripts/gds/fitness-checks-route-pins.js +5 -75
  858. package/scripts/gds/fitness-checks-vocabulary.js +5 -391
  859. package/scripts/gds/fitness-checks-write-validation.js +5 -156
  860. package/scripts/gds/fitness-lib.js +5 -126
  861. package/scripts/gds/fitness-migration-contraction.js +5 -49
  862. package/scripts/gds/fitness-ratchets.js +5 -563
  863. package/scripts/gds/fitness.js +5 -1493
  864. package/scripts/gds/gate-review.js +5 -328
  865. package/scripts/gds/gating.js +5 -346
  866. package/scripts/gds/gds-literal-scan.js +5 -194
  867. package/scripts/gds/gen-api-client.js +5 -555
  868. package/scripts/gds/gen-api-docs.js +5 -1100
  869. package/scripts/gds/gen-atlas.js +5 -364
  870. package/scripts/gds/gen-diagrams.js +6 -607
  871. package/scripts/gds/gen-file-map.js +5 -335
  872. package/scripts/gds/gen-freshness.js +5 -31
  873. package/scripts/gds/gen-interaction-posture.js +5 -120
  874. package/scripts/gds/gen-repo-map.js +5 -538
  875. package/scripts/gds/gen-role-responsibilities.js +5 -133
  876. package/scripts/gds/gen-session-index.js +5 -241
  877. package/scripts/gds/gen-sounds.js +5 -174
  878. package/scripts/gds/git-merge-regen.js +6 -291
  879. package/scripts/gds/go-live.js +5 -1069
  880. package/scripts/gds/goal.js +6 -271
  881. package/scripts/gds/government-walk.js +5 -1475
  882. package/scripts/gds/grade-correlation-audit.js +5 -308
  883. package/scripts/gds/grade-replay.js +5 -235
  884. package/scripts/gds/grade-smoke.js +6 -204
  885. package/scripts/gds/home-isolation-guard.js +5 -125
  886. package/scripts/gds/hooks/pre-push.js +5 -209
  887. package/scripts/gds/howto.js +5 -143
  888. package/scripts/gds/http-api-client.js +6 -81
  889. package/scripts/gds/identity-strip.js +5 -74
  890. package/scripts/gds/init.js +5 -1157
  891. package/scripts/gds/install-git-hooks.js +5 -198
  892. package/scripts/gds/instance-apex.js +5 -37
  893. package/scripts/gds/intent-retry.js +5 -51
  894. package/scripts/gds/key-card.js +6 -221
  895. package/scripts/gds/key-status.js +5 -124
  896. package/scripts/gds/land-watch.js +5 -199
  897. package/scripts/gds/leak-scan-allowlist.js +5 -291
  898. package/scripts/gds/learning-capture.js +6 -144
  899. package/scripts/gds/lib.sh +7 -73
  900. package/scripts/gds/linkify-refs.js +6 -654
  901. package/scripts/gds/lint-infra-exec.js +5 -68
  902. package/scripts/gds/lint-migrations.js +5 -100
  903. package/scripts/gds/lint-workflow-exec.js +5 -61
  904. package/scripts/gds/local-preview-lib.js +6 -128
  905. package/scripts/gds/local-preview.js +6 -81
  906. package/scripts/gds/login.js +5 -358
  907. package/scripts/gds/main-audit.js +5 -623
  908. package/scripts/gds/me.js +6 -96
  909. package/scripts/gds/memory-map.js +5 -174
  910. package/scripts/gds/merge-lock.js +6 -70
  911. package/scripts/gds/migration-namespace.js +5 -311
  912. package/scripts/gds/mirror-lineage-check.js +5 -341
  913. package/scripts/gds/mirror-redact.js +5 -348
  914. package/scripts/gds/module-artifact.js +6 -289
  915. package/scripts/gds/module-assess-docs.js +6 -237
  916. package/scripts/gds/module-assess-installs.js +6 -227
  917. package/scripts/gds/module-assess-score.js +6 -110
  918. package/scripts/gds/module-assess-security.js +6 -251
  919. package/scripts/gds/module-assess-tests.js +6 -277
  920. package/scripts/gds/module-assess-version.js +6 -91
  921. package/scripts/gds/module-error-report.js +5 -146
  922. package/scripts/gds/module-test-runner.js +6 -413
  923. package/scripts/gds/module.js +5 -1374
  924. package/scripts/gds/move-escalation.js +5 -140
  925. package/scripts/gds/newcomer-floor.js +6 -420
  926. package/scripts/gds/newcomer-floor.test.js +6 -234
  927. package/scripts/gds/next-number.js +6 -162
  928. package/scripts/gds/oauth-secret.js +5 -200
  929. package/scripts/gds/onboard.js +5 -265
  930. package/scripts/gds/onboarding-analyze.js +6 -225
  931. package/scripts/gds/onboarding-config.js +6 -179
  932. package/scripts/gds/onboarding-ship.js +6 -91
  933. package/scripts/gds/pack-env-prefix.js +5 -72
  934. package/scripts/gds/package-core.js +5 -1102
  935. package/scripts/gds/page-inventory.js +5 -346
  936. package/scripts/gds/page-reader.js +5 -720
  937. package/scripts/gds/paste-token.js +6 -211
  938. package/scripts/gds/plain-cards.js +5 -350
  939. package/scripts/gds/portability-smoke-art.sh +7 -84
  940. package/scripts/gds/portability-smoke-memory.sh +7 -175
  941. package/scripts/gds/preflight.js +5 -212
  942. package/scripts/gds/probe-cache.js +5 -244
  943. package/scripts/gds/prove-strict-versioning.js +6 -283
  944. package/scripts/gds/provision-auto-upgrade.js +5 -161
  945. package/scripts/gds/provision-byo-host.js +5 -67
  946. package/scripts/gds/provision-capacity.js +5 -78
  947. package/scripts/gds/provision-caps.js +5 -62
  948. package/scripts/gds/provision-config.js +5 -232
  949. package/scripts/gds/provision-core-upgrade.js +5 -1165
  950. package/scripts/gds/provision-disconnect.js +5 -87
  951. package/scripts/gds/provision-github-setup.js +5 -167
  952. package/scripts/gds/provision-net.js +5 -356
  953. package/scripts/gds/provision-pin-key.js +5 -175
  954. package/scripts/gds/provision-pin-replay.js +5 -125
  955. package/scripts/gds/provision-process.js +5 -169
  956. package/scripts/gds/provision-render.js +5 -200
  957. package/scripts/gds/provision-repo-auth.js +5 -163
  958. package/scripts/gds/provision-repo-private.js +5 -97
  959. package/scripts/gds/provision-repo.js +5 -1336
  960. package/scripts/gds/provision-teardown.js +5 -105
  961. package/scripts/gds/provision-units.js +5 -468
  962. package/scripts/gds/provision.js +5 -1477
  963. package/scripts/gds/publish-credential-check.js +6 -65
  964. package/scripts/gds/publish-integration-gate.js +5 -140
  965. package/scripts/gds/publish-manifest.js +5 -437
  966. package/scripts/gds/publish-watch.js +5 -266
  967. package/scripts/gds/pulse.js +6 -335
  968. package/scripts/gds/push-main.js +5 -54
  969. package/scripts/gds/push-path-brief.js +5 -98
  970. package/scripts/gds/read-session-export.js +5 -357
  971. package/scripts/gds/reauth.js +6 -154
  972. package/scripts/gds/recall.js +6 -182
  973. package/scripts/gds/redteam-patrol.js +5 -435
  974. package/scripts/gds/regen-instance-docs.js +5 -45
  975. package/scripts/gds/release-core.js +5 -78
  976. package/scripts/gds/release-notes.js +5 -270
  977. package/scripts/gds/release.js +6 -138
  978. package/scripts/gds/rename-history-check.js +5 -367
  979. package/scripts/gds/rename-ledger-prose.js +5 -480
  980. package/scripts/gds/render-api.js +5 -196
  981. package/scripts/gds/render-check.js +5 -204
  982. package/scripts/gds/render-ideas.js +6 -225
  983. package/scripts/gds/render-payload.js +5 -84
  984. package/scripts/gds/repo-metrics.js +6 -362
  985. package/scripts/gds/review-sheet.js +5 -106
  986. package/scripts/gds/role-pack-guard.js +5 -141
  987. package/scripts/gds/route-shadow-guard.js +5 -173
  988. package/scripts/gds/routine-schedule.js +5 -281
  989. package/scripts/gds/run-routine.js +5 -255
  990. package/scripts/gds/run-unit-tests.js +6 -659
  991. package/scripts/gds/runner-drift.js +5 -149
  992. package/scripts/gds/sandbox-stage.js +6 -458
  993. package/scripts/gds/scope-map-guard.js +5 -299
  994. package/scripts/gds/scope-roster-guard.js +5 -117
  995. package/scripts/gds/seam-wiring-guard.js +5 -274
  996. package/scripts/gds/search-ingest-db.js +6 -287
  997. package/scripts/gds/search-ingest-md.js +6 -268
  998. package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +6 -152
  999. package/scripts/gds/seed-bv1-profiles-tasks.js +6 -135
  1000. package/scripts/gds/seed-bv2-ideator-surface-tasks.js +6 -390
  1001. package/scripts/gds/seed-staging.sh +7 -116
  1002. package/scripts/gds/seed-verify-criteria.js +6 -124
  1003. package/scripts/gds/sequence.js +6 -596
  1004. package/scripts/gds/session-cost.js +6 -429
  1005. package/scripts/gds/session-digest-build.js +6 -293
  1006. package/scripts/gds/session-digest.js +6 -199
  1007. package/scripts/gds/session-eval.js +6 -630
  1008. package/scripts/gds/session-transcript-build.js +6 -155
  1009. package/scripts/gds/session-transcript-upload.js +6 -29
  1010. package/scripts/gds/session.js +6 -403
  1011. package/scripts/gds/setup.js +6 -645
  1012. package/scripts/gds/ship-check.js +5 -85
  1013. package/scripts/gds/ship-deploy-target.js +5 -392
  1014. package/scripts/gds/ship-escalation.js +5 -166
  1015. package/scripts/gds/ship-finish.js +5 -419
  1016. package/scripts/gds/ship-flow.js +5 -1216
  1017. package/scripts/gds/ship-git.js +5 -99
  1018. package/scripts/gds/ship-grade-steps.js +5 -546
  1019. package/scripts/gds/ship-grade.js +5 -425
  1020. package/scripts/gds/ship-honesty.js +5 -312
  1021. package/scripts/gds/ship-io.js +5 -138
  1022. package/scripts/gds/ship-land.js +5 -1129
  1023. package/scripts/gds/ship-memory-sync.js +5 -248
  1024. package/scripts/gds/ship-merge-gate.js +5 -224
  1025. package/scripts/gds/ship-merge.js +5 -465
  1026. package/scripts/gds/ship-mode-ask.js +5 -137
  1027. package/scripts/gds/ship-mode-manual.js +5 -53
  1028. package/scripts/gds/ship-preflight-steps.js +5 -398
  1029. package/scripts/gds/ship-regen.js +5 -313
  1030. package/scripts/gds/ship-resume.js +5 -200
  1031. package/scripts/gds/ship-session-upload.js +5 -312
  1032. package/scripts/gds/ship-state.js +5 -109
  1033. package/scripts/gds/ship-surprise.js +5 -83
  1034. package/scripts/gds/ship-visual.js +5 -74
  1035. package/scripts/gds/ship.js +5 -380
  1036. package/scripts/gds/shipping-mode.js +5 -69
  1037. package/scripts/gds/skill-lint.js +5 -248
  1038. package/scripts/gds/skill-preflight.js +5 -359
  1039. package/scripts/gds/smoke-batch-claim.sh +7 -237
  1040. package/scripts/gds/smoke-batch-release.sh +7 -315
  1041. package/scripts/gds/smoke-claim-consistency.sh +7 -221
  1042. package/scripts/gds/smoke-dependencies.sh +7 -142
  1043. package/scripts/gds/smoke-gds.js +6 -255
  1044. package/scripts/gds/smoke-write.sh +7 -274
  1045. package/scripts/gds/source-text-test-scan.js +7 -0
  1046. package/scripts/gds/spark.js +6 -293
  1047. package/scripts/gds/stale-worktrees.js +5 -210
  1048. package/scripts/gds/start-goals.js +5 -101
  1049. package/scripts/gds/start.js +6 -1089
  1050. package/scripts/gds/status.js +6 -544
  1051. package/scripts/gds/strand-watch.js +5 -313
  1052. package/scripts/gds/stranded-rows.js +5 -198
  1053. package/scripts/gds/stray-unit-sweep.sh +7 -70
  1054. package/scripts/gds/surface.js +5 -100
  1055. package/scripts/gds/task.js +6 -272
  1056. package/scripts/gds/test-path-guard.js +5 -97
  1057. package/scripts/gds/triage.js +6 -741
  1058. package/scripts/gds/turn-end-sound.js +5 -72
  1059. package/scripts/gds/tweak-halt.js +5 -68
  1060. package/scripts/gds/tweak-renders.js +5 -198
  1061. package/scripts/gds/uat.js +6 -119
  1062. package/scripts/gds/ui-kit-transform.js +5 -41
  1063. package/scripts/gds/update-channel.js +5 -510
  1064. package/scripts/gds/update-sweep.js +5 -827
  1065. package/scripts/gds/upgrade-artist-gate.js +5 -45
  1066. package/scripts/gds/upgrade-commit-identity.js +5 -31
  1067. package/scripts/gds/upgrade-migrate.js +5 -223
  1068. package/scripts/gds/upgrade-operator.js +6 -73
  1069. package/scripts/gds/upgrade-outcome.js +5 -173
  1070. package/scripts/gds/upgrade.js +5 -1497
  1071. package/scripts/gds/validate-design.js +5 -10
  1072. package/scripts/gds/version-close.js +6 -620
  1073. package/scripts/gds/version-literal-guard.js +5 -138
  1074. package/scripts/gds/version-select.js +5 -77
  1075. package/scripts/gds/visual-review-nudge.js +5 -38
  1076. package/scripts/gds/wedge-remedy.js +5 -173
  1077. package/scripts/gds/worktree-claim-guard.js +5 -129
  1078. package/scripts/gds/worktree.js +6 -448
  1079. package/scripts/hall-preview/refresh-fixtures.js +1 -1
  1080. package/scripts/hall-preview/server.js +2 -2
  1081. package/scripts/migrate.sh +3 -3
  1082. package/scripts/public-mirror-export.js +3 -3
  1083. package/scripts/security/dep-audit.js +50 -124
  1084. package/scripts/setup-builder.js +7 -7
  1085. package/src/bongos/api-errors.js +1 -0
  1086. package/src/bongos/api-prefix.js +1 -1
  1087. package/src/bongos/auth-github.js +19 -3
  1088. package/src/bongos/auth-idp.js +7 -0
  1089. package/src/bongos/claim-attribution.js +2 -2
  1090. package/src/bongos/core-moves.js +1 -1
  1091. package/src/bongos/core-update.js +3 -3
  1092. package/src/bongos/craft-mode.js +2 -2
  1093. package/src/bongos/db-kernel.js +15 -3
  1094. package/src/bongos/db.js +30 -4
  1095. package/src/bongos/github-repos.js +1 -1
  1096. package/src/bongos/llm-cache.js +1 -1
  1097. package/src/bongos/llm-pricing.js +1 -1
  1098. package/src/bongos/metrics.js +1 -1
  1099. package/src/bongos/middleware/rate-limit.js +2 -2
  1100. package/src/bongos/module-listing.js +93 -1
  1101. package/src/bongos/module-scope-map.js +90 -85
  1102. package/src/bongos/module-store.js +1 -1
  1103. package/src/bongos/module-submissions.js +1 -1
  1104. package/src/bongos/optimizer.js +1 -1
  1105. package/src/bongos/package-registry.js +1 -1
  1106. package/src/bongos/path-match.js +1 -1
  1107. package/src/bongos/permission-path-check.js +3 -3
  1108. package/src/bongos/platform-visibility-gate.js +3 -5
  1109. package/src/bongos/prelaunch-gate.js +7 -6
  1110. package/src/bongos/route-rank-check.js +2 -2
  1111. package/src/bongos/routes/auth.js +15 -2
  1112. package/src/bongos/routes/backup.js +1 -1
  1113. package/src/bongos/routes/builders.js +29 -1
  1114. package/src/bongos/routes/me.js +49 -18
  1115. package/src/bongos/routes/modules.js +29 -9
  1116. package/src/bongos/routes/public.js +3 -72
  1117. package/src/bongos/schema-lag.js +1 -1
  1118. package/src/bongos/sensitive-surfaces.js +1 -1
  1119. package/src/bongos/serve-internal.js +65 -16
  1120. package/src/bongos/software-update.js +2 -2
  1121. package/src/bongos/upgrade-hold.js +3 -3
  1122. package/src/hall-look.js +6 -5
  1123. package/src/module-api.js +3 -3
  1124. package/src/module-loader/catalog.js +1 -1
  1125. package/src/module-loader/error-tally.js +3 -3
  1126. package/src/module-loader/manifest-schema.js +3 -3
  1127. package/src/platform-server.js +10 -0
  1128. package/src/role-responsibilities.js +1 -1
  1129. package/src/stale-timer.js +2 -2
  1130. package/tests/accessibility_replay.mjs +1 -1
  1131. package/tests/activity_rollup_order_db.mjs +1 -1
  1132. package/tests/activity_snapshots_db.mjs +1 -1
  1133. package/tests/adopt_detect.mjs +1 -1
  1134. package/tests/adopt_import.mjs +1 -1
  1135. package/tests/adopt_preflight.mjs +1 -1
  1136. package/tests/adr_0089_scope.mjs +10 -7
  1137. package/tests/adr_0162_citation.mjs +1 -1
  1138. package/tests/adr_0162_gate_citation.mjs +1 -1
  1139. package/tests/agent_invoke.mjs +1 -1
  1140. package/tests/agent_invoke_live.mjs +3 -3
  1141. package/tests/agents_cron_trigger.mjs +2 -2
  1142. package/tests/agents_roster.mjs +1 -1
  1143. package/tests/agents_sync.mjs +4 -4
  1144. package/tests/allow_rule_guard.mjs +20 -20
  1145. package/tests/api_alias_caller_ratchet.mjs +9 -10
  1146. package/tests/api_alias_exceptions.mjs +7 -6
  1147. package/tests/api_artifacts.mjs +214 -0
  1148. package/tests/api_cli_flags.mjs +3 -3
  1149. package/tests/api_client.mjs +56 -54
  1150. package/tests/api_docs.mjs +30 -9
  1151. package/tests/api_error_envelope_buildcheck.mjs +1 -1
  1152. package/tests/api_msys_path_repair.mjs +2 -2
  1153. package/tests/architect.mjs +1 -1
  1154. package/tests/art_stage.mjs +2 -2
  1155. package/tests/artifact_audit.mjs +2 -2
  1156. package/tests/atlas.mjs +1 -1
  1157. package/tests/audit_deps.mjs +1 -1
  1158. package/tests/audit_gate.mjs +1 -1
  1159. package/tests/auth_flow_slice1.mjs +3 -3
  1160. package/tests/auth_inactive_builder.mjs +43 -5
  1161. package/tests/auth_session_expiry_db.mjs +16 -4
  1162. package/tests/auth_session_ttl.mjs +23 -0
  1163. package/tests/authorship_audit.mjs +2 -2
  1164. package/tests/autobongos_cadence.mjs +1 -1
  1165. package/tests/autobongos_fence.mjs +1 -1
  1166. package/tests/autobongos_grade_cap.mjs +2 -2
  1167. package/tests/autobongos_heartbeat_head.mjs +1 -1
  1168. package/tests/autobongos_host_access.mjs +3 -3
  1169. package/tests/autobongos_loop.mjs +17 -17
  1170. package/tests/autobongos_service_ps1.mjs +3 -3
  1171. package/tests/autobongos_tweak_lane.mjs +2 -2
  1172. package/tests/autobongos_verify.mjs +2 -2
  1173. package/tests/autonomous_fit_protected_paths.mjs +3 -3
  1174. package/tests/autonomy_config_idle.mjs +1 -1
  1175. package/tests/autonomy_daily_checks.mjs +201 -0
  1176. package/tests/autonomy_digest.mjs +1 -1
  1177. package/tests/autonomy_gate.mjs +1 -1
  1178. package/tests/autonomy_gauge.mjs +2 -2
  1179. package/tests/autonomy_runner_identity.mjs +1 -1
  1180. package/tests/backfill_sessions.mjs +8 -8
  1181. package/tests/backfill_subagent_rewards.mjs +1 -1
  1182. package/tests/backfill_task_rewards.mjs +2 -2
  1183. package/tests/backlog_review.mjs +3 -3
  1184. package/tests/baseline_staleness.mjs +2 -2
  1185. package/tests/bfg.mjs +11 -5
  1186. package/tests/bfg_write.mjs +20 -11
  1187. package/tests/blockers_hall.mjs +14 -4
  1188. package/tests/blockers_page_ui.mjs +56 -12
  1189. package/tests/bongos_dispatch.mjs +5 -5
  1190. package/tests/bongos_login.mjs +2 -2
  1191. package/tests/bug_attachment_audit.mjs +1 -1
  1192. package/tests/bug_attachment_recover.mjs +2 -2
  1193. package/tests/bug_triage.mjs +3 -3
  1194. package/tests/build_info.mjs +1 -1
  1195. package/tests/builder_tester_tag.mjs +184 -0
  1196. package/tests/bump_version.mjs +3 -3
  1197. package/tests/canonical_profile_url.mjs +1 -1
  1198. package/tests/capture_error_format.mjs +1 -1
  1199. package/tests/capture_goal_routing.mjs +2 -2
  1200. package/tests/category_advisory_guard.mjs +3 -3
  1201. package/tests/claim_error_surface.mjs +2 -2
  1202. package/tests/claim_from_task_and_home.mjs +1 -1
  1203. package/tests/claim_gate_open_blocker.mjs +7 -4
  1204. package/tests/claim_gate_rebase.mjs +12 -8
  1205. package/tests/claim_recall.mjs +4 -4
  1206. package/tests/claim_resolve_worktree_lock.mjs +1 -1
  1207. package/tests/claude_materialize.mjs +68 -68
  1208. package/tests/clawback_confirmed_backlog.mjs +8 -5
  1209. package/tests/cli_allowlist_permissions.mjs +11 -11
  1210. package/tests/cli_dispatcher.mjs +2 -2
  1211. package/tests/cli_err_code.mjs +6 -6
  1212. package/tests/cli_exit_no_abort.mjs +7 -7
  1213. package/tests/cli_lib_formatters.mjs +2 -2
  1214. package/tests/cli_sessions.mjs +5 -5
  1215. package/tests/cli_surface.mjs +15 -15
  1216. package/tests/cli_token_reissue.mjs +2 -2
  1217. package/tests/client_baseurl_guard.mjs +1 -1
  1218. package/tests/client_bundle_route.mjs +35 -4
  1219. package/tests/cloud_bongos_pack.mjs +1 -1
  1220. package/tests/community_leaderboard_db.mjs +1 -1
  1221. package/tests/conductor.mjs +18 -18
  1222. package/tests/conflict_resolve.mjs +14 -16
  1223. package/tests/consumer_layout_boot.mjs +12 -12
  1224. package/tests/context_pack.mjs +6 -6
  1225. package/tests/control_manifest.mjs +4 -4
  1226. package/tests/copy_desk_page_reads.mjs +1 -1
  1227. package/tests/copy_desk_page_release.mjs +192 -0
  1228. package/tests/copy_inventory.mjs +2 -2
  1229. package/tests/core_auto_upgrade.mjs +1 -1
  1230. package/tests/core_move_notice.mjs +2 -2
  1231. package/tests/core_origin_follow.mjs +7 -7
  1232. package/tests/core_pin_sync.mjs +3 -3
  1233. package/tests/core_upgrade_door.mjs +2 -2
  1234. package/tests/core_upgrade_owner_door.mjs +34 -1
  1235. package/tests/core_upgrade_runner.mjs +19 -19
  1236. package/tests/credential_presence.mjs +2 -2
  1237. package/tests/credit_grant.mjs +3 -3
  1238. package/tests/credit_log_single_writer.mjs +5 -5
  1239. package/tests/criterion_ref_status.mjs +2 -2
  1240. package/tests/cross_discipline_priority_direction.mjs +3 -3
  1241. package/tests/cutover_codemod.mjs +2 -4
  1242. package/tests/db_backup_nightly.mjs +1 -1
  1243. package/tests/db_backup_offsite.mjs +1 -1
  1244. package/tests/db_ownership_handover.mjs +2 -2
  1245. package/tests/dead_deps.mjs +3 -3
  1246. package/tests/dependency_advisory.mjs +1 -1
  1247. package/tests/deploy_audit_gate.mjs +4 -4
  1248. package/tests/deploy_divergence_line.mjs +36 -16
  1249. package/tests/deploy_page_projects.mjs +35 -4
  1250. package/tests/dev_lib.mjs +2 -2
  1251. package/tests/dev_windows.mjs +2 -2
  1252. package/tests/diagram_facts_offset.mjs +1 -1
  1253. package/tests/diagram_repo_slug.mjs +1 -1
  1254. package/tests/diff_derived_signals.mjs +2 -2
  1255. package/tests/dns_preflight.mjs +2 -2
  1256. package/tests/do_api.mjs +3 -3
  1257. package/tests/doc_cli_guard.mjs +28 -28
  1258. package/tests/doc_comment_coverage.mjs +1 -1
  1259. package/tests/doc_control_claims.mjs +11 -11
  1260. package/tests/docs_entropy.mjs +2 -2
  1261. package/tests/docs_openapi_route.mjs +8 -6
  1262. package/tests/doctor_hooks.mjs +1 -1
  1263. package/tests/edit_hints.mjs +3 -2
  1264. package/tests/effective_visibility_predicate.mjs +1 -19
  1265. package/tests/env_knobs_neutral_prefix.mjs +13 -13
  1266. package/tests/exec_path_guard.mjs +4 -4
  1267. package/tests/executed_closure.mjs +18 -12
  1268. package/tests/file_map.mjs +1 -1
  1269. package/tests/find_untested.mjs +13 -13
  1270. package/tests/first_admin_bootstrap.mjs +1 -1
  1271. package/tests/fitness.mjs +16 -16
  1272. package/tests/fitness_gds_ratchet.mjs +2 -2
  1273. package/tests/fitness_installed_core.mjs +3 -3
  1274. package/tests/fitness_no_raw_nul.mjs +1 -1
  1275. package/tests/fitness_ratchets.mjs +3 -3
  1276. package/tests/fitness_scope_roster.mjs +2 -2
  1277. package/tests/fitness_two_root.mjs +8 -8
  1278. package/tests/fixtures/accessibility-replay.json +5 -5
  1279. package/tests/fixtures/grade-replay/recorded-panel-grades.json +1 -1
  1280. package/tests/fixtures/ideator-prefold/README.md +1 -1
  1281. package/tests/fixtures/page-ledger.mjs +22 -0
  1282. package/tests/fixtures/session-506-digest.json +5 -5
  1283. package/tests/gate_approvals.mjs +50 -0
  1284. package/tests/gate_review.mjs +8 -8
  1285. package/tests/gating_review_retired.mjs +2 -2
  1286. package/tests/gen_freshness.mjs +3 -3
  1287. package/tests/git_guard.mjs +3 -3
  1288. package/tests/git_merge_regen.mjs +41 -65
  1289. package/tests/github_one_trip.mjs +4 -4
  1290. package/tests/github_pick_up.mjs +2 -2
  1291. package/tests/github_push_merge_driver.mjs +1 -1
  1292. package/tests/go_live.mjs +3 -2
  1293. package/tests/goal_category.mjs +1 -1
  1294. package/tests/goal_cli.mjs +2 -2
  1295. package/tests/goal_create_spec_entry.mjs +1 -1
  1296. package/tests/goal_invite_consent.mjs +3 -1
  1297. package/tests/goal_move.mjs +1 -1
  1298. package/tests/goal_working_area.mjs +1 -1
  1299. package/tests/government_agent_asks.mjs +7 -7
  1300. package/tests/government_board_room_copy.mjs +6 -1
  1301. package/tests/government_board_view.mjs +39 -0
  1302. package/tests/government_board_vote_ui.mjs +39 -1
  1303. package/tests/government_config.mjs +2 -2
  1304. package/tests/government_live_proof_shape.mjs +1 -1
  1305. package/tests/government_protected_surfaces.mjs +54 -53
  1306. package/tests/government_require_permission.mjs +9 -1
  1307. package/tests/government_vanilla_boot.mjs +1 -1
  1308. package/tests/government_vocabulary.mjs +2 -2
  1309. package/tests/government_walk.mjs +2 -2
  1310. package/tests/grade_body_limit.mjs +6 -4
  1311. package/tests/grade_correlation_audit.mjs +3 -3
  1312. package/tests/grade_diff_hash.mjs +1 -1
  1313. package/tests/grade_engine_replay.mjs +2 -2
  1314. package/tests/grade_server_authoritative.mjs +1 -1
  1315. package/tests/grade_unavailable_display.mjs +1 -1
  1316. package/tests/grader.mjs +8 -24
  1317. package/tests/grader_generated_provenance.mjs +14 -14
  1318. package/tests/grader_no_artifact.mjs +1 -1
  1319. package/tests/grader_prompt_fencing.mjs +1 -1
  1320. package/tests/grader_quality_window_overflow.mjs +1 -1
  1321. package/tests/grader_reader_lens.mjs +3 -3
  1322. package/tests/grader_regrade_delta.mjs +1 -1
  1323. package/tests/grader_unbacked_score.mjs +2 -2
  1324. package/tests/hall_acclaim_vote_control.mjs +113 -0
  1325. package/tests/hall_asset_cache.mjs +127 -0
  1326. package/tests/hall_audit.mjs +63 -0
  1327. package/tests/hall_board_world.mjs +20 -0
  1328. package/tests/hall_city_card_words.mjs +61 -0
  1329. package/tests/hall_client_request_shape.mjs +5 -1
  1330. package/tests/hall_home_ships_bounded.mjs +160 -0
  1331. package/tests/hall_landing_boot.mjs +15 -2
  1332. package/tests/hall_nav.mjs +33 -0
  1333. package/tests/hall_onboarding_bongos_setup.mjs +1 -1
  1334. package/tests/hall_oversight_world.mjs +44 -4
  1335. package/tests/hall_palette.mjs +12 -9
  1336. package/tests/hall_preview_security.mjs +1 -1
  1337. package/tests/hall_profile_world.mjs +17 -0
  1338. package/tests/hall_reading_world.mjs +16 -1
  1339. package/tests/hall_roster_world.mjs +2 -1
  1340. package/tests/hall_studio_world.mjs +4 -1
  1341. package/tests/hall_work_history_id.mjs +39 -0
  1342. package/tests/held_tweak_reporting.mjs +4 -4
  1343. package/tests/helpers.mjs +3 -3
  1344. package/tests/home_bounded_reads.mjs +1 -1
  1345. package/tests/home_isolation_guard.mjs +1 -1
  1346. package/tests/hook_core_resolve.mjs +7 -7
  1347. package/tests/hook_user_agents.mjs +1 -1
  1348. package/tests/hooks_drain.mjs +2 -2
  1349. package/tests/host_topology_skips.mjs +1 -1
  1350. package/tests/howto_guide.mjs +1 -1
  1351. package/tests/howto_moments.mjs +3 -3
  1352. package/tests/hub_account_page.mjs +1 -1
  1353. package/tests/idea_capture_grades.mjs +2 -2
  1354. package/tests/idea_develop_spark.mjs +1 -1
  1355. package/tests/idea_filed_via.mjs +2 -2
  1356. package/tests/idea_ideate_full.mjs +1 -1
  1357. package/tests/idea_spark_mark.mjs +1 -1
  1358. package/tests/idea_spark_queue.mjs +1 -1
  1359. package/tests/idea_triage.mjs +1 -1
  1360. package/tests/idea_triage_grade.mjs +3 -3
  1361. package/tests/idea_vote_permission.mjs +113 -0
  1362. package/tests/idea_votes_fold_db.mjs +123 -0
  1363. package/tests/infra_exec_paths.mjs +12 -12
  1364. package/tests/init.mjs +2 -2
  1365. package/tests/instance_db_migrated_on_code_move.mjs +5 -5
  1366. package/tests/instance_feedback.mjs +9 -9
  1367. package/tests/instance_mismatch_guard.mjs +2 -2
  1368. package/tests/integration_parked_ratchet.mjs +24 -2
  1369. package/tests/intent_retry.mjs +1 -1
  1370. package/tests/interaction_posture.mjs +3 -3
  1371. package/tests/invite_expiry_db.mjs +1 -1
  1372. package/tests/joinability_invite_only.mjs +1 -1
  1373. package/tests/karma_vote_lists.mjs +270 -0
  1374. package/tests/key-card.mjs +2 -2
  1375. package/tests/key-status.mjs +2 -2
  1376. package/tests/knip_ratchet_ambient.mjs +2 -2
  1377. package/tests/known_failing_ratchet.mjs +1 -1
  1378. package/tests/land_watch.mjs +2 -2
  1379. package/tests/landing_legal_pages.mjs +1 -1
  1380. package/tests/landing_page.mjs +2 -2
  1381. package/tests/leaderboard_roles.mjs +4 -1
  1382. package/tests/leak_scan_allowlist.mjs +8 -8
  1383. package/tests/leak_scan_fail_closed.mjs +1 -1
  1384. package/tests/lib_sh_resolution.mjs +9 -9
  1385. package/tests/lifecycle-card.mjs +7 -7
  1386. package/tests/linkify_check.mjs +2 -2
  1387. package/tests/linkify_refs.mjs +1 -1
  1388. package/tests/llm-cache-route.mjs +1 -1
  1389. package/tests/local_preview.mjs +2 -2
  1390. package/tests/main_audit.mjs +3 -3
  1391. package/tests/main_audit_attestation.mjs +1 -1
  1392. package/tests/main_audit_db_roster.mjs +2 -2
  1393. package/tests/main_worktree_busy_reason.mjs +3 -3
  1394. package/tests/markdown_line_endings.mjs +2 -2
  1395. package/tests/me_streak_leaderboard_queries.mjs +193 -0
  1396. package/tests/membership_kind_lockstep.mjs +1 -1
  1397. package/tests/memory_isolation.mjs +16 -8
  1398. package/tests/memory_map.mjs +2 -2
  1399. package/tests/memory_pull.mjs +33 -25
  1400. package/tests/merge_driver_register.mjs +3 -3
  1401. package/tests/migration_allocation.mjs +2 -2
  1402. package/tests/migration_namespace.mjs +1 -1
  1403. package/tests/migrations_forward_safe.mjs +1 -1
  1404. package/tests/mingle.mjs +1 -1
  1405. package/tests/mirror_lineage_fulltree.mjs +3 -3
  1406. package/tests/mirror_lineage_proof.mjs +2 -2
  1407. package/tests/mirror_redact.mjs +4 -4
  1408. package/tests/missing_dep_classify.mjs +3 -3
  1409. package/tests/module-scope-map.mjs +22 -22
  1410. package/tests/module_api_lazy.mjs +1 -1
  1411. package/tests/module_assess_docs.mjs +2 -2
  1412. package/tests/module_assess_installs.mjs +3 -3
  1413. package/tests/module_assess_price_parity.mjs +5 -5
  1414. package/tests/module_assess_score.mjs +5 -5
  1415. package/tests/module_assess_security.mjs +4 -4
  1416. package/tests/module_assess_tests.mjs +3 -3
  1417. package/tests/module_assessments_migration.mjs +1 -1
  1418. package/tests/module_catalog.mjs +2 -2
  1419. package/tests/module_cli.mjs +3 -3
  1420. package/tests/module_entitlements.mjs +1 -1
  1421. package/tests/module_error_counts.mjs +1 -1
  1422. package/tests/module_install.mjs +4 -4
  1423. package/tests/module_loader.mjs +3 -1
  1424. package/tests/module_owned_tests.mjs +1 -1
  1425. package/tests/module_release_channels.mjs +1 -1
  1426. package/tests/module_store_howto.mjs +3 -3
  1427. package/tests/module_store_listing.mjs +139 -2
  1428. package/tests/module_store_publish.mjs +4 -4
  1429. package/tests/module_store_publish_route.mjs +1 -1
  1430. package/tests/module_store_reassess.mjs +1 -1
  1431. package/tests/module_store_registry_migration.mjs +1 -1
  1432. package/tests/module_test_runner.mjs +3 -3
  1433. package/tests/module_update.mjs +4 -4
  1434. package/tests/module_upgrade_updates.mjs +1 -1
  1435. package/tests/move_escalation.mjs +2 -2
  1436. package/tests/nav_permission_atoms.mjs +3 -2
  1437. package/tests/needs_rebase.mjs +7 -3
  1438. package/tests/newcomer_floor.mjs +1 -1
  1439. package/tests/next_number.mjs +1 -1
  1440. package/tests/no_artifact_escalation.mjs +3 -3
  1441. package/tests/npm_release_where.mjs +1 -1
  1442. package/tests/oauth_secret.mjs +2 -2
  1443. package/tests/onboard.mjs +6 -6
  1444. package/tests/onboarding_gate.mjs +2 -2
  1445. package/tests/opt_in_skill_modules.mjs +3 -3
  1446. package/tests/own_scope_guard.mjs +1 -1
  1447. package/tests/own_session_revoke.mjs +4 -1
  1448. package/tests/package_core.mjs +10 -11
  1449. package/tests/page_inventory.mjs +5 -5
  1450. package/tests/page_reader.mjs +7 -7
  1451. package/tests/page_tweak_hold.mjs +6 -6
  1452. package/tests/parallel-load.mjs +1 -1
  1453. package/tests/paste_token_api_base.mjs +1 -1
  1454. package/tests/paste_token_session_store.mjs +2 -2
  1455. package/tests/pending_invite_purge_db.mjs +1 -1
  1456. package/tests/permission_path.mjs +1 -1
  1457. package/tests/pin_replay.mjs +1 -1
  1458. package/tests/pin_write_key.mjs +7 -7
  1459. package/tests/plain_cards.mjs +15 -15
  1460. package/tests/pr_assign.mjs +1 -1
  1461. package/tests/pre_push_hook.mjs +3 -3
  1462. package/tests/preflight_checks.mjs +2 -2
  1463. package/tests/prelaunch_gate.mjs +1 -1
  1464. package/tests/privacy_matrix.mjs +1 -1
  1465. package/tests/probe_cache.mjs +6 -6
  1466. package/tests/profile_connections_ui.mjs +4 -3
  1467. package/tests/profile_fields.mjs +11 -1
  1468. package/tests/profile_privacy_owner_view.mjs +1 -1
  1469. package/tests/profile_role_headline.mjs +10 -9
  1470. package/tests/project_admin_console_model.mjs +1 -1
  1471. package/tests/projects_hub.mjs +1 -1
  1472. package/tests/projects_hub_cloud_hop.mjs +1 -1
  1473. package/tests/promote_goal_id.mjs +6 -6
  1474. package/tests/promotion_sweep.mjs +1 -1
  1475. package/tests/provision.mjs +24 -24
  1476. package/tests/provision_account_identity.mjs +2 -2
  1477. package/tests/provision_byo_host.mjs +1 -1
  1478. package/tests/provision_caddy_wiring.mjs +2 -2
  1479. package/tests/provision_disconnect.mjs +2 -2
  1480. package/tests/provision_dns_first.mjs +1 -1
  1481. package/tests/provision_render.mjs +9 -9
  1482. package/tests/provision_repo_private.mjs +3 -3
  1483. package/tests/provision_resource_caps.mjs +5 -5
  1484. package/tests/provision_restart.mjs +3 -3
  1485. package/tests/provision_settings_apply.mjs +7 -7
  1486. package/tests/provision_teardown_address.mjs +2 -2
  1487. package/tests/provisioning_capacity.mjs +5 -5
  1488. package/tests/provisioning_credential_preflight.mjs +1 -1
  1489. package/tests/provisioning_disconnect.mjs +1 -1
  1490. package/tests/provisioning_error_note_scope.mjs +4 -4
  1491. package/tests/provisioning_paid_shape_gate.mjs +2 -2
  1492. package/tests/provisioning_planet_physics.mjs +16 -0
  1493. package/tests/provisioning_runner_drift_notice.mjs +2 -2
  1494. package/tests/provisioning_settings_env.mjs +1 -1
  1495. package/tests/pruned_lockfile_integrity.mjs +1 -1
  1496. package/tests/public_mirror_export.mjs +1 -1
  1497. package/tests/publish_integration_gate.mjs +2 -2
  1498. package/tests/publish_manifest.mjs +6 -6
  1499. package/tests/publish_watch.mjs +1 -1
  1500. package/tests/push_path_brief.mjs +2 -2
  1501. package/tests/raise.mjs +248 -0
  1502. package/tests/rank_roles_audit.mjs +1 -1
  1503. package/tests/rank_tier_single_source.mjs +2 -2
  1504. package/tests/rate_limit_public.mjs +1 -1
  1505. package/tests/read_default_meter.mjs +2 -2
  1506. package/tests/read_session_export.mjs +1 -1
  1507. package/tests/rebase_gate_set_aside.mjs +1 -1
  1508. package/tests/recall_cli.mjs +1 -1
  1509. package/tests/recall_corpus_health.mjs +3 -2
  1510. package/tests/recall_hints.mjs +1 -1
  1511. package/tests/recruiter_sliver_boundary.mjs +1 -1
  1512. package/tests/redteam_patrol.mjs +2 -2
  1513. package/tests/regrade_actual_minutes.mjs +2 -2
  1514. package/tests/regrade_eligibility.mjs +2 -2
  1515. package/tests/release_core.mjs +2 -2
  1516. package/tests/release_notes.mjs +4 -4
  1517. package/tests/rename_history_restraint.mjs +3 -3
  1518. package/tests/rename_ledger_prose.mjs +6 -6
  1519. package/tests/render_api.mjs +1 -1
  1520. package/tests/render_check.mjs +4 -4
  1521. package/tests/render_deploy.mjs +1 -1
  1522. package/tests/repo_info_binding.mjs +1 -1
  1523. package/tests/repo_map.mjs +5 -5
  1524. package/tests/reward_mode_cost_plus_only.mjs +7 -3
  1525. package/tests/reward_mode_surfacing.mjs +1 -1
  1526. package/tests/role_responsibilities.mjs +1 -1
  1527. package/tests/route_permission_check.mjs +1 -1
  1528. package/tests/route_shadow_guard.mjs +1 -1
  1529. package/tests/route_validation.mjs +1 -1
  1530. package/tests/routine_capture_kind.mjs +24 -13
  1531. package/tests/routine_schedule.mjs +51 -9
  1532. package/tests/run_routine.mjs +5 -5
  1533. package/tests/run_routine_two_root.mjs +5 -5
  1534. package/tests/runner_drift.mjs +17 -17
  1535. package/tests/sandbox_stage.mjs +5 -5
  1536. package/tests/scope_map_guard.mjs +7 -7
  1537. package/tests/scouting_owner_access_and_reach.mjs +1 -1
  1538. package/tests/scripts_gds_forwarders.mjs +224 -0
  1539. package/tests/scrubber_corpus.mjs +2 -2
  1540. package/tests/seam_wiring_guard.mjs +1 -1
  1541. package/tests/search_ingest.mjs +2 -2
  1542. package/tests/search_ingest_db.mjs +1 -1
  1543. package/tests/search_ingest_nul.mjs +6 -6
  1544. package/tests/seed_verify_criteria.mjs +3 -3
  1545. package/tests/sequence.mjs +3 -3
  1546. package/tests/served_paths_shipped.mjs +3 -3
  1547. package/tests/session_506_regression.mjs +1 -1
  1548. package/tests/session_accessibility.mjs +1 -1
  1549. package/tests/session_caps.mjs +1 -1
  1550. package/tests/session_cost.mjs +1 -1
  1551. package/tests/session_digest.mjs +2 -2
  1552. package/tests/session_eval.mjs +6 -6
  1553. package/tests/session_index.mjs +1 -1
  1554. package/tests/session_records.mjs +4 -4
  1555. package/tests/session_rename_fallback.mjs +2 -2
  1556. package/tests/session_reward_on_land.mjs +7 -149
  1557. package/tests/session_reward_on_land_db.mjs +191 -0
  1558. package/tests/session_reward_reconcile.mjs +6 -88
  1559. package/tests/session_reward_reconcile_db.mjs +132 -0
  1560. package/tests/session_transcript.mjs +1 -1
  1561. package/tests/sessions_kit_pager.mjs +2 -1
  1562. package/tests/setup_device_flow_fallback.mjs +2 -2
  1563. package/tests/setup_smoke.mjs +12 -5
  1564. package/tests/setup_status_facts.mjs +54 -12
  1565. package/tests/ship_autolinkify.mjs +2 -2
  1566. package/tests/ship_automerge_injection.mjs +1 -1
  1567. package/tests/ship_base_flag.mjs +1 -1
  1568. package/tests/ship_broadcast_routing.mjs +1 -1
  1569. package/tests/ship_broadcast_server.mjs +2 -2
  1570. package/tests/ship_builder_model.mjs +1 -1
  1571. package/tests/ship_cannot_lie.mjs +9 -9
  1572. package/tests/ship_card.mjs +2 -2
  1573. package/tests/ship_ci_deploy.mjs +7 -7
  1574. package/tests/ship_error_shape.mjs +1 -1
  1575. package/tests/ship_land_ci_not_started.mjs +3 -3
  1576. package/tests/ship_land_conflict.mjs +3 -3
  1577. package/tests/ship_land_proof.mjs +3 -3
  1578. package/tests/ship_land_red_pr.mjs +5 -5
  1579. package/tests/ship_merge_gate.mjs +14 -14
  1580. package/tests/ship_mode.mjs +1 -1
  1581. package/tests/ship_mode_first_ship.mjs +4 -4
  1582. package/tests/ship_mode_hands_off.mjs +8 -8
  1583. package/tests/ship_post_land_verify.mjs +1 -1
  1584. package/tests/ship_preflight.mjs +19 -19
  1585. package/tests/ship_premerge.mjs +1 -1
  1586. package/tests/ship_publish_error.mjs +2 -2
  1587. package/tests/ship_push_diagnosis.mjs +1 -1
  1588. package/tests/ship_regen_copy_inventory.mjs +3 -3
  1589. package/tests/ship_resume.mjs +4 -4
  1590. package/tests/ship_smoke_gate.mjs +1 -1
  1591. package/tests/ship_upload_skip.mjs +1 -1
  1592. package/tests/ship_upstream_deletion.mjs +1 -1
  1593. package/tests/ship_vendored_instance.mjs +8 -8
  1594. package/tests/ship_visual_regrade.mjs +3 -3
  1595. package/tests/ship_zero_commit.mjs +1 -1
  1596. package/tests/skill_docs_unavailable_regrade.mjs +3 -3
  1597. package/tests/skill_friction_kind.mjs +1 -1
  1598. package/tests/skill_grade_recover.mjs +1 -1
  1599. package/tests/skill_grader_health.mjs +1 -1
  1600. package/tests/skill_lint.mjs +1 -1
  1601. package/tests/skill_menu_ruling.mjs +1 -1
  1602. package/tests/skill_preflight.mjs +7 -7
  1603. package/tests/skip_is_not_pass.mjs +22 -1
  1604. package/tests/smoke_dependencies_witness.mjs +2 -2
  1605. package/tests/smoke_preflight.mjs +1 -1
  1606. package/tests/smoke_target.mjs +2 -2
  1607. package/tests/smoke_write_contract.mjs +2 -2
  1608. package/tests/sound_player.mjs +8 -8
  1609. package/tests/source_text_test_ratchet.mjs +97 -0
  1610. package/tests/speciality_corpus_scope.mjs +1 -1
  1611. package/tests/speciality_session_skills.mjs +1 -1
  1612. package/tests/sso_checkin_legacy_field_gone.mjs +4 -2
  1613. package/tests/stale_timer.mjs +3 -3
  1614. package/tests/stale_worktrees.mjs +1 -1
  1615. package/tests/start_env_guard.mjs +1 -1
  1616. package/tests/start_goal_first.mjs +3 -3
  1617. package/tests/start_inbox_count.mjs +1 -1
  1618. package/tests/start_rebase_warning.mjs +1 -1
  1619. package/tests/status_default_version.mjs +3 -3
  1620. package/tests/status_mirror_sync.mjs +1 -1
  1621. package/tests/status_page_no_dead_uptime.mjs +80 -0
  1622. package/tests/stop_refcheck.mjs +1 -1
  1623. package/tests/strand_watch.mjs +1 -1
  1624. package/tests/stranded_rows.mjs +1 -1
  1625. package/tests/stuck_detector.mjs +14 -14
  1626. package/tests/sweep_app_account.mjs +3 -3
  1627. package/tests/task_cli.mjs +2 -2
  1628. package/tests/task_detail_ui.mjs +11 -1
  1629. package/tests/task_discipline_required.mjs +2 -2
  1630. package/tests/task_list_paging.mjs +1 -1
  1631. package/tests/task_visual_slots.mjs +2 -2
  1632. package/tests/terms_acceptance.mjs +1 -1
  1633. package/tests/terms_grandfather_db.mjs +1 -1
  1634. package/tests/test_path_guard.mjs +1 -1
  1635. package/tests/triage_development.mjs +1 -1
  1636. package/tests/tweak_batch_apply.mjs +2 -2
  1637. package/tests/tweak_land_heal.mjs +3 -3
  1638. package/tests/tweak_unattended.mjs +3 -3
  1639. package/tests/ui_design_skills.mjs +2 -2
  1640. package/tests/unit_report_status.mjs +2 -2
  1641. package/tests/unit_runner_serial.mjs +2 -2
  1642. package/tests/unit_runner_teardown_abort.mjs +1 -1
  1643. package/tests/update_channel.mjs +2 -2
  1644. package/tests/update_channel_db.mjs +4 -4
  1645. package/tests/update_subscription_engine.mjs +26 -26
  1646. package/tests/update_sweep_home.mjs +14 -14
  1647. package/tests/upgrade.mjs +11 -11
  1648. package/tests/upgrade_artist_gate.mjs +4 -4
  1649. package/tests/upgrade_commit_identity.mjs +2 -2
  1650. package/tests/upgrade_migrate.mjs +7 -7
  1651. package/tests/upgrade_operator.mjs +2 -2
  1652. package/tests/upgrade_outcome.mjs +2 -2
  1653. package/tests/upgrade_persist_pin.mjs +5 -5
  1654. package/tests/upkeep_home.mjs +1 -1
  1655. package/tests/version_close.mjs +2 -2
  1656. package/tests/version_close_cli.mjs +2 -2
  1657. package/tests/version_close_route.mjs +1 -1
  1658. package/tests/version_literals.mjs +23 -23
  1659. package/tests/visual_review.mjs +5 -5
  1660. package/tests/wedge_remedy.mjs +5 -5
  1661. package/tests/welcome_boot.mjs +116 -0
  1662. package/tests/welcome_boot_browser.mjs +271 -0
  1663. package/tests/wizard_born_first_board.mjs +3 -3
  1664. package/tests/wizard_demo.mjs +1 -1
  1665. package/tests/wizard_one_page.mjs +4 -3
  1666. package/tests/wizard_physics.mjs +3 -1
  1667. package/tests/wizard_physics_more.mjs +42 -3
  1668. package/tests/work_title_wrap.mjs +1 -1
  1669. package/tests/workflow_exec_paths.mjs +6 -6
  1670. package/tests/worktree_claim_guard.mjs +1 -1
  1671. package/tests/worktree_helper.mjs +2 -2
  1672. package/tests/write_validation_gaps.mjs +3 -3
  1673. package/scripts/gds/api.sh +0 -6
  1674. package/scripts/gds/artifact-staleness.js +0 -267
  1675. package/scripts/gds/audit-exports.js +0 -128
  1676. package/scripts/gds/classify-discipline.js +0 -153
  1677. package/scripts/gds/codemod-rename-src-gds.js +0 -145
  1678. package/scripts/gds/coreB-carve-proof.sh +0 -725
  1679. package/scripts/gds/goal-names.js +0 -102
  1680. package/scripts/gds/rename-goals.js +0 -109
  1681. package/scripts/gds/resolve-skill-model.js +0 -57
  1682. package/scripts/gds/security-baseline-check.sh +0 -180
  1683. package/scripts/gds/seed-adopt-tasks.js +0 -75
  1684. package/scripts/gds/seed-api-contract-goal-tasks.js +0 -141
  1685. package/scripts/gds/seed-board-room-tasks.js +0 -196
  1686. package/scripts/gds/seed-bongos-app-tasks.js +0 -294
  1687. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +0 -81
  1688. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +0 -100
  1689. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +0 -307
  1690. package/scripts/gds/seed-bongos-module-system-tasks.js +0 -346
  1691. package/scripts/gds/seed-bongos-tasks.js +0 -214
  1692. package/scripts/gds/seed-bongos-v1-seo-tasks.js +0 -104
  1693. package/scripts/gds/seed-bv1-community-tasks.js +0 -131
  1694. package/scripts/gds/seed-bv1-privacy-invites-tasks.js +0 -133
  1695. package/scripts/gds/seed-bv1-profile-page-tasks.js +0 -161
  1696. package/scripts/gds/seed-bv1-r01-delta-tasks.js +0 -154
  1697. package/scripts/gds/seed-bv2-tweak-mode-tasks.js +0 -277
  1698. package/scripts/gds/seed-gds-v4-tasks.js +0 -624
  1699. package/scripts/gds/seed-governance-tasks.js +0 -340
  1700. package/scripts/gds/seed-medusa-tasks.js +0 -440
  1701. package/scripts/gds/seed-module-upstreaming.js +0 -219
  1702. package/scripts/gds/seed-productization-tasks.js +0 -235
  1703. package/scripts/gds/seed-project-admin-console-tasks.js +0 -88
  1704. package/scripts/gds/seed-provisioning-tasks.js +0 -83
  1705. package/scripts/gds/seed-strict-versioning-tasks.js +0 -275
  1706. package/scripts/gds/seed-v2-world-tasks.js +0 -283
  1707. package/scripts/gds/spike-task-map.js +0 -899
  1708. package/scripts/migrate_cost_ledger.sh +0 -178
  1709. package/scripts/status-probe.mjs +0 -213
  1710. package/src/bongos/uptime-poller.js +0 -93
  1711. package/tests/artifact_staleness.mjs +0 -207
  1712. package/tests/goal_names.mjs +0 -120
  1713. package/tests/government_fold_bench.mjs +0 -50
  1714. package/tests/spike_task_map.mjs +0 -422
  1715. package/tests/status-probe.mjs +0 -89
  1716. /package/{scripts/gds → modules/raise}/CLAUDE.md +0 -0
  1717. /package/scripts/{gds → bongos}/cloudbongos-token-isolation.conf +0 -0
  1718. /package/scripts/{gds → bongos}/discipline-modes.json +0 -0
  1719. /package/scripts/{gds → bongos}/retired-core-skills.json +0 -0
@@ -0,0 +1,1071 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // scripts/bongos/go-live.js — run a go-live as ONE command instead of forty tool calls.
5
+ //
6
+ // WHY THIS EXISTS (task 1003189). Gate 3 of docs/recipes/core-release-pipeline.md —
7
+ // moving an instance's core pin, the only act that makes shipped work visible to
8
+ // users — is a DETERMINISTIC sequence that was nonetheless re-derived from prose by
9
+ // hand every time. The 2026-08-23 go-live took 101 tool calls / 211 model turns at a
10
+ // mean 143K context (29.7M cache-read tokens, ~69% of the bill). About four of those
11
+ // calls were engineering; the rest were lookups: what is on main, what is live, which
12
+ // PRs are green, what does the runbook say, what did the box just print. Cost here is
13
+ // turns x context, so collapsing the mechanical legs into one call is the whole fix.
14
+ //
15
+ // WHAT IT IS NOT. Not a new deploy mechanism, and not a privileged surface of its own.
16
+ // Every leg is an EXISTING proven part and this file only sequences them and reports:
17
+ // - deploy-divergence.js check() — live coreVersion vs main, UNRELEASED vs UNDEPLOYED
18
+ // - the published registry — proof a release carrying the work actually exists
19
+ // - `bongos upgrade --registry --commit-pin` — the pin move, health-gated, auto-rollback ON
20
+ // It is also NOT task 1003159: that gives the OWNER a door onto deploy without a shell
21
+ // (an authenticated control + an ADR settling the authority model). This is the AGENT
22
+ // side — a session that ALREADY holds the shell should spend two calls here, not forty.
23
+ //
24
+ // HALT, DO NOT GUESS. Every condition that needs judgement stops the run and names
25
+ // itself: a red CI check, unreleased commits, a registry missing the target, a dirty
26
+ // tree, a failed health check, an uncommitted pin. Those are exactly the parts worth
27
+ // an agent's attention; this script's job is to make everything AROUND them free.
28
+ //
29
+ // NO HOST TOPOLOGY LIVES HERE. This file ships in the portable core, so the ssh alias,
30
+ // paths, service names and health URLs come from a host-owned config (see --help for
31
+ // the schema) that is NOT publishable — the same shape as config/update-subscriptions.json.
32
+ // A core that named one instance's box would not be a core.
33
+ //
34
+ // Usage:
35
+ // node scripts/bongos/go-live.js # PLAN only — read-only, the default
36
+ // node scripts/bongos/go-live.js --apply # actually move the pin
37
+ // node scripts/bongos/go-live.js --to 1.19.306 # pin a target instead of main's CORE_VERSION
38
+ // node scripts/bongos/go-live.js --verify-marker src/x.js=needle
39
+ // # refuse a target that lacks the change
40
+ // node scripts/bongos/go-live.js --target web --json
41
+ //
42
+ // Exit codes: 0 plan clean / apply succeeded · 1 halted (reason printed) · 2 bad invocation.
43
+
44
+ const fs = require('node:fs');
45
+ const path = require('node:path');
46
+ const { spawnSync } = require('node:child_process');
47
+ const { arg, hasFlag, apiCall } = require('./cli-lib');
48
+ const divergence = require('./deploy-divergence.js');
49
+
50
+ const ROOT = path.resolve(__dirname, '..', '..');
51
+ const DEFAULT_CONFIG = 'config/go-live.json';
52
+
53
+ // ---------------------------------------------------------------------------
54
+ // Validation. Everything below reaches a remote shell that runs as root, so it
55
+ // is checked against a strict allowlist BEFORE interpolation — never quoted and
56
+ // hoped for. A config file is host-owned, but "host-owned" is not "trusted to
57
+ // contain shell metacharacters".
58
+ // ---------------------------------------------------------------------------
59
+
60
+ const SEMVER_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/;
61
+ // Deliberately narrow: POSIX-portable path/identifier characters only. No spaces,
62
+ // no quotes, no $ ` \ ; & | < > ( ) newline — i.e. nothing with meaning to a shell.
63
+ //
64
+ // `~` IS allowed, and is the one deliberate exception. It is shell-interpreted, but
65
+ // it cannot start a subshell, chain a command, or redirect — the runbook's backup dir
66
+ // is literally `~/backups`, and under `sudo -u <owner> -H` that expansion to the
67
+ // owner's home is the BEHAVIOUR WE WANT, not a leak. Everything with control meaning
68
+ // stays out.
69
+ const SAFE_TOKEN_RE = /^[A-Za-z0-9._@:/+=~-]+$/;
70
+ const SAFE_ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
71
+
72
+ function isSafeToken(v) {
73
+ return typeof v === 'string' && v.length > 0 && v.length <= 512 && SAFE_TOKEN_RE.test(v);
74
+ }
75
+
76
+ // The fields a target must carry, and the ones it may. Unknown keys are reported
77
+ // rather than ignored: a typo'd `healthURL` that silently disables the health gate
78
+ // is precisely the class of quiet failure this pipeline keeps being bitten by.
79
+ // `ssh` is NOT required: a target with no ssh host is LOCAL (the box driving itself).
80
+ //
81
+ // `deployTimer` is NOT required either — that is CO-TENANT MODE (task 1003521). A
82
+ // provisioned instance under /srv/<host>/<slug> has no pull-deploy timer at all (only
83
+ // its <slug>-db-backup.timer), so requiring the field forced an operator to invent a
84
+ // unit name that the script would then try to `systemctl stop`. Absent, the stop and
85
+ // the restart are simply skipped: there is no `reset --hard` to race.
86
+ const REQUIRED_FIELDS = ['instanceDir', 'service', 'healthUrl', 'versionUrl'];
87
+ const OPTIONAL_FIELDS = ['ssh', 'local', 'deployTimer', 'deployService', 'runAs', 'backupDb', 'backupDir', 'env', 'registryPackage', 'pinMode'];
88
+
89
+ // How the bump is made durable — the other half of co-tenant mode (task 1003521).
90
+ //
91
+ // On the PLATFORM instance the repo of record is ours, and a pull-deploy
92
+ // `git reset --hard origin/main` reverts any pin that was not PUSHED (task 1002712 —
93
+ // thirteen releases were lost exactly that way). So the default is `push`.
94
+ //
95
+ // On a provisioned co-tenant the repo of record is the CUSTOMER's own GitHub repo, so
96
+ // that push is both wrong and, in practice, uncredentialed. With no pull-deploy timer
97
+ // nothing will revert the pin, so a local commit is enough to leave the tree clean:
98
+ // local-commit — commit the pin, do not push it
99
+ // leave-dirty — do not commit at all; the bump lives in the working tree by design
100
+ const PIN_MODES = ['push', 'local-commit', 'leave-dirty'];
101
+ const DEFAULT_PIN_MODE = 'push';
102
+
103
+ function pinModeOf(target) {
104
+ return (target && target.pinMode) || DEFAULT_PIN_MODE;
105
+ }
106
+
107
+ function validateTarget(name, t) {
108
+ const errors = [];
109
+ if (!t || typeof t !== 'object' || Array.isArray(t)) return [`target "${name}" is not an object`];
110
+
111
+ for (const f of REQUIRED_FIELDS) {
112
+ if (t[f] === undefined) errors.push(`target "${name}" is missing required field "${f}"`);
113
+ }
114
+ const known = new Set([...REQUIRED_FIELDS, ...OPTIONAL_FIELDS]);
115
+ for (const k of Object.keys(t)) {
116
+ if (!known.has(k)) errors.push(`target "${name}" has unknown field "${k}" (typo? known: ${[...known].sort().join(', ')})`);
117
+ }
118
+ for (const [k, v] of Object.entries(t)) {
119
+ if (k === 'env') {
120
+ if (typeof v !== 'object' || v === null || Array.isArray(v)) { errors.push(`target "${name}".env must be an object`); continue; }
121
+ for (const [ek, ev] of Object.entries(v)) {
122
+ if (!SAFE_ENV_KEY_RE.test(ek)) errors.push(`target "${name}".env key "${ek}" is not a valid environment-variable name`);
123
+ if (!isSafeToken(String(ev))) errors.push(`target "${name}".env.${ek} contains characters that are unsafe in a shell`);
124
+ }
125
+ continue;
126
+ }
127
+ if (!known.has(k)) continue;
128
+ if (k === 'local') { // a flag, never interpolated into a command
129
+ if (typeof v !== 'boolean') errors.push(`target "${name}".local must be true or false`);
130
+ continue;
131
+ }
132
+ if (k === 'pinMode') { // an enum, never interpolated into a command
133
+ if (!PIN_MODES.includes(v)) errors.push(`target "${name}".pinMode must be one of ${PIN_MODES.join(', ')} (got ${JSON.stringify(v)})`);
134
+ continue;
135
+ }
136
+ if (!isSafeToken(v)) errors.push(`target "${name}".${k} contains characters that are unsafe in a shell (got ${JSON.stringify(v)})`);
137
+ }
138
+ return errors;
139
+ }
140
+
141
+ // ---------------------------------------------------------------------------
142
+ // Config
143
+ // ---------------------------------------------------------------------------
144
+
145
+ const CONFIG_TEMPLATE = `{
146
+ "defaultTarget": "web",
147
+ "targets": {
148
+ "web": {
149
+ "ssh": "my-box", // ssh alias or user@host
150
+ "instanceDir": "/home/me/my-instance", // the instance repo (holds the pin)
151
+ "service": "my-instance.service", // systemd unit to restart
152
+ "healthUrl": "http://127.0.0.1:3002/healthz", // box-side, NOT the apex
153
+ "versionUrl": "http://127.0.0.1:3002/version", // box-side truth read back after
154
+ "deployTimer": "my-deploy.timer", // optional: pull-deploy timer (its reset --hard is the hazard)
155
+ "deployService": "my-deploy.service", // optional: forced tick proves the pin stuck
156
+ "runAs": "me", // optional: unprivileged owner of the instance
157
+ "backupDb": "mydb", // optional: pg_dump before the bump
158
+ "backupDir": "~/backups",
159
+ "env": { "PGDATABASE": "mydb" }, // optional: load-bearing for migrate
160
+ "registryPackage": "@bongos/core",
161
+ "pinMode": "push" // optional: push (default) | local-commit | leave-dirty
162
+ },
163
+ "a-co-tenant": {
164
+ // A PROVISIONED instance: no pull-deploy timer to stop, and the repo of record
165
+ // is the customer's own GitHub repo — so the pin is committed, never pushed.
166
+ "ssh": "my-box",
167
+ "instanceDir": "/srv/my-host/their-slug",
168
+ "service": "their-slug.service",
169
+ "healthUrl": "http://127.0.0.1:3101/healthz",
170
+ "versionUrl": "http://127.0.0.1:3101/version",
171
+ "runAs": "their-slug",
172
+ "env": { "PGDATABASE": "their_slug" },
173
+ "pinMode": "local-commit"
174
+ }
175
+ }
176
+ }`;
177
+
178
+ function loadConfig({ configPath, readFile = fs.readFileSync, exists = fs.existsSync } = {}) {
179
+ const rel = configPath || DEFAULT_CONFIG;
180
+ const abs = path.isAbsolute(rel) ? rel : path.join(ROOT, rel);
181
+ if (!exists(abs)) {
182
+ return { error: 'NO_TARGET_CONFIG', path: rel, template: CONFIG_TEMPLATE };
183
+ }
184
+ let raw;
185
+ try { raw = readFile(abs, 'utf8'); } catch (e) { return { error: 'CONFIG_UNREADABLE', path: rel, detail: e.message }; }
186
+ let parsed;
187
+ // Tolerate // comments so the shipped template can stay self-documenting.
188
+ try { parsed = JSON.parse(raw.replace(/^\s*\/\/.*$/gm, '').replace(/(:\s*"[^"]*"|:\s*[\d.]+|[{[,])\s*\/\/.*$/gm, '$1')); }
189
+ catch (e) { return { error: 'CONFIG_MALFORMED', path: rel, detail: e.message }; }
190
+ if (!parsed || typeof parsed !== 'object' || !parsed.targets || typeof parsed.targets !== 'object') {
191
+ return { error: 'CONFIG_MALFORMED', path: rel, detail: 'expected a top-level "targets" object' };
192
+ }
193
+ return { ok: true, path: rel, config: parsed };
194
+ }
195
+
196
+ function selectTarget(config, name) {
197
+ const wanted = name || config.defaultTarget || Object.keys(config.targets)[0];
198
+ if (!wanted) return { error: 'UNKNOWN_TARGET', detail: 'the config declares no targets' };
199
+ const t = config.targets[wanted];
200
+ if (!t) {
201
+ return { error: 'UNKNOWN_TARGET', detail: `no target "${wanted}" (have: ${Object.keys(config.targets).join(', ') || 'none'})` };
202
+ }
203
+ const errors = validateTarget(wanted, t);
204
+ if (errors.length) return { error: 'CONFIG_INVALID', detail: errors.join('; ') };
205
+ return { ok: true, name: wanted, target: t };
206
+ }
207
+
208
+ // ---------------------------------------------------------------------------
209
+ // Remote execution. One ssh round-trip per phase, script fed on STDIN so no
210
+ // value is ever interpolated into an ssh ARGUMENT (which would be re-parsed by
211
+ // the remote login shell). Values are validated above; this is the second layer.
212
+ // ---------------------------------------------------------------------------
213
+
214
+ // Privilege preamble for any phase that touches systemd.
215
+ //
216
+ // Over ssh these phases run as ROOT, so `systemctl stop …` just works — which is what
217
+ // they originally assumed. Run LOCALLY by the nightly lane they run as the instance
218
+ // OWNER, where the same line fails with "Interactive authentication required" and the
219
+ // timer is never stopped: the pull-deploy `git reset --hard` then stays armed for the
220
+ // whole upgrade, which is the exact hazard the stop exists to remove. Deciding at RUN
221
+ // time keeps one script correct for both callers.
222
+ const SUDO_PREAMBLE = 'SUDO=""; [ "$(id -u)" -eq 0 ] || SUDO="sudo -n"';
223
+
224
+ // A target is LOCAL when it names no ssh host: the phases run through a local shell
225
+ // instead of a remote one. Everything else — the phases, the halts, the reporting —
226
+ // is byte-identical, which is the point: one deployment engine, reachable from a
227
+ // laptop (remote) or from the box itself (local, how the nightly lane uses it).
228
+ // Without this the unattended path would need its own second implementation, and the
229
+ // two would drift — which is exactly how the nightly deploy ended up with weaker
230
+ // checks than the manual one (task 1003219).
231
+ function isLocalTarget(target) {
232
+ return !target || !target.ssh;
233
+ }
234
+
235
+ function remote(target, script, { run = spawnSync, timeoutMs = 900000 } = {}) {
236
+ const [cmd, args] = isLocalTarget(target)
237
+ ? ['bash', ['-s']]
238
+ : ['ssh', ['-o', 'ConnectTimeout=20', '-o', 'BatchMode=yes', target.ssh, 'bash', '-s']];
239
+ const res = run(cmd, args, {
240
+ input: script, encoding: 'utf8', timeout: timeoutMs, maxBuffer: 32 * 1024 * 1024,
241
+ });
242
+ if (!res || res.error) return { ok: false, status: null, stdout: '', stderr: res && res.error ? res.error.message : 'spawn failed' };
243
+ return { ok: res.status === 0, status: res.status, stdout: res.stdout || '', stderr: res.stderr || '' };
244
+ }
245
+
246
+ // `sudo -u <user> -H env K=V … <cmd>` — the shape every runbook entry uses. Returns
247
+ // a string safe to embed because every component was allowlist-validated.
248
+ //
249
+ // `sudo -u <user> -H env K=V … <cmd>` — the shape every runbook entry uses. Returns
250
+ // a string safe to embed because every component was allowlist-validated.
251
+ //
252
+ // Only NON-secret configuration (PGDATABASE, HOME) travels in the plain `env K=V` list —
253
+ // seeing those in a log is useful rather than harmful.
254
+ //
255
+ // This used to take a `needsNpm` option wrapping the command in a preamble that DERIVED an
256
+ // npm credential on the far side, because sudo logs its whole invocation and there was no way
257
+ // to hand a privileged child a secret without journalling it (task 1003218). @bongos/core is
258
+ // public (task 1003872), so the deploy path needs no npm credential at all and the whole
259
+ // hazard is gone rather than mitigated (task 1003878).
260
+ function asOwner(target, cmd) {
261
+ const inner = cmd;
262
+ const envPairs = Object.entries(target.env || {}).map(([k, v]) => `${k}=${v}`);
263
+ if (!target.runAs) {
264
+ const joined = envPairs.join(' ');
265
+ return `${joined ? `env ${joined} ` : ''}${inner}`.trim();
266
+ }
267
+ const joined = [...envPairs, `HOME=/home/${target.runAs}`].join(' ');
268
+ return `sudo -u ${target.runAs} -H env ${joined} ${inner}`.trim();
269
+ }
270
+
271
+ // POSIX single-quote a value for embedding in a shell command.
272
+ function shq(s) {
273
+ return `'${String(s).replace(/'/g, `'\\''`)}'`;
274
+ }
275
+
276
+ // The content proof, as a shell snippet.
277
+ //
278
+ // TWO bugs live here in the obvious version, and both FAIL OPEN — they report "your
279
+ // change is missing" for a version that has it, which reads exactly like the real
280
+ // ADR-0161 trap and sends you chasing a later release that does not exist:
281
+ //
282
+ // 1. Do NOT derive the tarball name. `npm pack @bongos/core` writes
283
+ // `bongos-core-<v>.tgz`, and hand-rolled `tr`/`sed` on the package name gets the
284
+ // leading dashes wrong — so `tar` reads a file that is not there and greps 0 hits.
285
+ // npm PRINTS the filename it wrote; use that.
286
+ // 2. Pass the path + needle as base64 and match with `grep -F`. Interpolating them
287
+ // lets a quote break out of the command, and an unescaped regex metacharacter in
288
+ // the needle silently changes what is being matched.
289
+ //
290
+ // `set -o pipefail` is deliberately absent: `grep -c` exits 1 on zero matches, which
291
+ // is a legitimate answer here, not a failure.
292
+ function markerProbe(pkg, version, marker) {
293
+ const p64 = Buffer.from(marker.path, 'utf8').toString('base64');
294
+ const n64 = Buffer.from(marker.needle, 'utf8').toString('base64');
295
+ return [
296
+ `set -u`,
297
+ // Run from a neutral cwd. `npm pack <spec>` behaves differently inside a
298
+ // project directory, and an earlier section's `cd` used to leak this far —
299
+ // which made the pack fail and read as "your change is missing".
300
+ `cd /tmp`,
301
+ `P=$(echo ${p64} | base64 -d)`,
302
+ `N=$(echo ${n64} | base64 -d)`,
303
+ `ERR=$(mktemp)`,
304
+ `T=$(npm pack ${pkg}@${version} --pack-destination /tmp 2>"$ERR" | tail -1)`,
305
+ // Say WHY it failed. A bare PACK_FAILED cost four diagnostic round-trips once.
306
+ `if [ -z "$T" ] || [ ! -f "/tmp/$T" ]; then echo "PACK_FAILED $(tail -2 "$ERR" | tr '\\n' ' ')"; rm -f "$ERR"; exit 0; fi`,
307
+ `rm -f "$ERR"`,
308
+ // `grep -c` PRINTS 0 *and* exits 1 on no match, so a bare `|| echo 0` emits TWO
309
+ // lines ("0\n0") — which parses to NaN and compares equal to nothing, so an
310
+ // absent marker silently passed. Emit exactly one line.
311
+ `tar -xzOf "/tmp/$T" "package/$P" 2>/dev/null | grep -c -F -- "$N" | head -1`,
312
+ ].join('; ');
313
+ }
314
+
315
+ // Read the marker section back. Fails CLOSED: anything that is not a clean count is
316
+ // 'PACK_FAILED' (could not check), never a 0 that would read as a confident "absent"
317
+ // — and never a NaN that silently compares equal to nothing and lets the run proceed.
318
+ function parseMarkerHits(raw) {
319
+ const s = String(raw == null ? '' : raw).trim();
320
+ if (!s || s.includes('PACK_FAILED')) return 'PACK_FAILED';
321
+ const first = s.split('\n')[0].trim();
322
+ if (!/^\d+$/.test(first)) return 'PACK_FAILED';
323
+ return Number(first);
324
+ }
325
+
326
+ // Does this process sit inside a git repo that knows the given ref?
327
+ function gitRefExists(ref, { run = spawnSync } = {}) {
328
+ const r = run('git', ['rev-parse', '--verify', '--quiet', ref], { cwd: ROOT, encoding: 'utf8' });
329
+ return !!r && !r.error && r.status === 0;
330
+ }
331
+
332
+ // Refresh origin/main before reading anything from it.
333
+ //
334
+ // deploy-divergence reads CORE_VERSION at the local `origin/main` REF, and a ref is
335
+ // only as fresh as the last fetch. A worktree that has sat for an hour resolves a
336
+ // target version that is already superseded — and everything downstream agrees with
337
+ // it, because every check is consistent with the same stale ref. This actually
338
+ // happened mid-build: a parallel session merged twice, the plan targeted the older
339
+ // carrier, and only a manual fetch revealed it. Default ON; --no-fetch opts out.
340
+ //
341
+ // A fetch failure is NOT fatal: a box or a tarball checkout legitimately has no
342
+ // remote, and deploy-divergence already falls back to HEAD there.
343
+ function refreshMain({ run = spawnSync } = {}) {
344
+ const r = run('git', ['fetch', 'origin', 'main', '--quiet'], { cwd: ROOT, encoding: 'utf8', timeout: 60000 });
345
+ if (!r || r.error || r.status !== 0) {
346
+ return { ok: false, reason: (r && (r.stderr || '').trim().split('\n').pop()) || 'fetch failed' };
347
+ }
348
+ return { ok: true };
349
+ }
350
+
351
+ // Ask the LIVE instance about its own artist gate (ADR 0241, task 1003575).
352
+ //
353
+ // The instance answers because it is the only party that can: the policy arrives
354
+ // in its web.env and its board holds the reviews. This script only decides what to
355
+ // do with the answer, and the refusal sentence is composed there rather than here
356
+ // so one wording serves every caller.
357
+ //
358
+ // NEVER THROWS. Every failure — no session, a 401, an instance too old to carry
359
+ // the route, a network error — resolves to { unread: <why> }, which renders as a
360
+ // note. See artistGateEntries for why an unread gate is not a halt.
361
+ // The FULL path, not a bare `/artist-gate`. cli-lib's apiCall composes
362
+ // `${base}${urlPath}` verbatim and `base` is the instance ORIGIN — every other
363
+ // caller in this repo spells `/api/bongos/…` by hand for the same reason. Getting
364
+ // this wrong is silent in the worst way: the request lands on the origin's
365
+ // catch-all, the gate reports itself unread on every instance including the ones
366
+ // that fully support it, and the deploy check never fires. Exported so a test can
367
+ // pin it against the route's REAL mount point in the generated OpenAPI spec.
368
+ const ARTIST_GATE_PATH = '/api/bongos/artist-gate';
369
+ // The levels a real answer can carry — mirrored from src/bongos/artist-gate.js
370
+ // rather than imported, because this script also runs from an INSTALLED core on a
371
+ // box where that path is inside the package, and a require of it here would make
372
+ // the deploy tool depend on the server's own tree. Pinned by the same test that
373
+ // pins the path.
374
+ const ARTIST_GATE_LEVELS = ['off', 'advisory', 'strict'];
375
+
376
+ async function readArtistGate(call = apiCall) {
377
+ try {
378
+ const res = await call('GET', ARTIST_GATE_PATH, null, { allowUnauthenticated: true });
379
+ if (res.status === 404) return { unread: `this instance does not serve ${ARTIST_GATE_PATH} — it predates ADR 0241` };
380
+ // A 5xx is a gate that EXISTS and BROKE, which is not the same class of
381
+ // unknown as "no session" or "too old to have the route". The gate is
382
+ // fail-closed by design, so the one case where we know it is there and
383
+ // cannot get an answer from it HALTS rather than degrading to a note —
384
+ // otherwise a broken read is a quieter way past the gate than the owner's
385
+ // own override, which is the asymmetry worth refusing.
386
+ if (res.status >= 500) return { broken: `GET ${ARTIST_GATE_PATH} returned ${res.status}` };
387
+ if (!res.ok) return { unread: `GET ${ARTIST_GATE_PATH} returned ${res.status}` };
388
+ const d = res.data || {};
389
+ // A 200 that is not this route's answer — an SPA index.html served by a
390
+ // catch-all, a proxy's own page — must read as UNREAD, never as a gate that
391
+ // holds nothing. "I got a 200 from something" is the one failure that would
392
+ // wave a deploy through in silence, which is worse than any halt.
393
+ if (!ARTIST_GATE_LEVELS.includes(d.mode)) {
394
+ return { unread: `GET ${ARTIST_GATE_PATH} answered ${res.status} but not with a gate — got mode ${JSON.stringify(d.mode)}` };
395
+ }
396
+ return { mode: d.mode, since: d.since || null, holds: !!d.holds, reviews: d.reviews || [], halt: d.halt || null };
397
+ } catch (e) {
398
+ return { unread: (e && e.message) || 'request failed' };
399
+ }
400
+ }
401
+
402
+ // Parse a `key=value` marker into its parts. Kept pure + exported: the marker is
403
+ // the answer to the trap that the release current when your fix merges usually
404
+ // does NOT contain your fix (ADR 0161 carriers bump on their own cadence).
405
+ function parseMarker(spec) {
406
+ if (!spec) return null;
407
+ const i = String(spec).indexOf('=');
408
+ if (i <= 0 || i === spec.length - 1) return { error: 'expected --verify-marker <path>=<needle>' };
409
+ return { path: spec.slice(0, i), needle: spec.slice(i + 1) };
410
+ }
411
+
412
+ // ---------------------------------------------------------------------------
413
+ // Planning. Pure given its inputs, so the halt matrix tests without a box.
414
+ // ---------------------------------------------------------------------------
415
+
416
+ const HALTS = {
417
+ DIRTY_CHECKOUT: 'the core checkout has uncommitted changes — CORE_VERSION here cannot be trusted to match what was released',
418
+ DIVERGENCE_UNDETERMINED: 'could not determine what is live',
419
+ UNRELEASED_ON_MAIN: 'main carries commits past the last CORE_VERSION bump — no pin can reach them',
420
+ ALREADY_LIVE: 'live is already at the target',
421
+ REGISTRY_MISSING_TARGET: 'the registry does not carry the target version',
422
+ MARKER_ABSENT: 'the target version does not contain the change you named',
423
+ MARKER_UNCHECKED: 'could not inspect the target version — the content proof did not run',
424
+ BOX_TREE_DIRTY: 'the instance repo on the box has uncommitted changes',
425
+ LIVE_AHEAD: 'live is AHEAD of the target',
426
+ ARTIST_REVIEW_UNRESOLVED: 'an unresolved artist review holds this deploy (ADR 0241)',
427
+ ARTIST_GATE_UNREADABLE: 'the artist gate is there and answering with an error — this deploy cannot tell whether a review holds it',
428
+ };
429
+
430
+ // The artist gate (ADR 0241, task 1003575). This is the ONE place in the deploy
431
+ // path that the artist's authority touches, and the boundary is the whole point:
432
+ // `strict` may delay a PIN MOVE and nothing else. Nothing in the ship, grade,
433
+ // merge or land path consults this — a builder's work is credited and on `main`
434
+ // long before a go-live runs, which is what lets this gate coexist with ADR 0162
435
+ // instead of recreating the strand it retired.
436
+ //
437
+ // It reads a STATE, not a verdict: the instance reports which artist review tasks
438
+ // are still open, never whether an artist approved anything. See
439
+ // src/bongos/artist-gate.js, which composes the refusal sentence this renders.
440
+ // The halt and/or note one gate read contributes. Shared by planGoLive and by the
441
+ // gitless (on-box, no checkout) path, so a lane that skips the git-derived checks
442
+ // does not also silently skip the gate — the deploy is the same deploy either way.
443
+ // PURE.
444
+ function artistGateEntries(gate) {
445
+ const halts = [];
446
+ const notes = [];
447
+ if (gate && gate.halt) {
448
+ halts.push({ code: 'ARTIST_REVIEW_UNRESOLVED', message: gate.halt.message, detail: gate.halt.detail });
449
+ }
450
+ // A gate that is THERE and BROKEN halts. This is the fail-closed half: we know
451
+ // the instance has the route, so "it 500s" is a gate we cannot get an answer
452
+ // from, not a gate that does not apply. Its remedy is the instance's own logs,
453
+ // and it is named as such rather than as an artist problem.
454
+ if (gate && gate.broken) {
455
+ halts.push({
456
+ code: 'ARTIST_GATE_UNREADABLE',
457
+ message: HALTS.ARTIST_GATE_UNREADABLE,
458
+ detail: `${gate.broken}. The route exists, so this is a fault on the instance, not a missing feature — read its logs for the GET /artist-gate failure. Deploying past it would mean moving the pin without knowing whether a review holds it.`,
459
+ });
460
+ }
461
+ // NOT KNOWING is a different thing again, and it must not render as "nothing
462
+ // holds". It is a note rather than a halt on purpose: a go-live is already
463
+ // deliberate and reversible, and halting every deploy because there is no CLI
464
+ // session — or because the instance predates the route entirely — would brick
465
+ // the pin with no task id to release against, which is the blocked-state-that-
466
+ // does-not-explain-itself failure ADR 0241 §4 names.
467
+ if (gate && gate.unread) {
468
+ notes.push({
469
+ code: 'ARTIST_GATE_UNREAD',
470
+ message: `could not read this instance's artist gate (${gate.unread}) — if the project runs artist_gate 'strict', an unresolved artist review may be holding this deploy and this plan cannot see it`,
471
+ });
472
+ }
473
+ return { halts, notes };
474
+ }
475
+
476
+ function planGoLive({ div, target, targetVersion, dirtyCheckout, allowUnreleased = false, artistGate = null }) {
477
+ const halts = [];
478
+ const notes = [];
479
+
480
+ // Evaluated FIRST, before the git-derived checks, because it is the halt whose
481
+ // remedy takes longest: a review someone has to do is not a thing you fix in the
482
+ // next ten seconds, and finding it out after the other five checks passed is
483
+ // strictly worse than finding it out now.
484
+ const gate = artistGateEntries(artistGate);
485
+ halts.push(...gate.halts);
486
+ notes.push(...gate.notes);
487
+
488
+ if (dirtyCheckout) halts.push({ code: 'DIRTY_CHECKOUT', message: HALTS.DIRTY_CHECKOUT, detail: dirtyCheckout });
489
+
490
+ if (!div || div.undetermined) {
491
+ halts.push({ code: 'DIVERGENCE_UNDETERMINED', message: HALTS.DIVERGENCE_UNDETERMINED, detail: div && div.reason });
492
+ return { halts, notes, targetVersion, from: null };
493
+ }
494
+
495
+ const from = div.live && div.live.coreVersion;
496
+
497
+ // UNRELEASED is not the same failure as UNDEPLOYED and must not be conflated:
498
+ // no pin, at any version, can reach a commit no release carries. Deploying
499
+ // anyway is the "textbook-clean go-live that changed nothing" trap.
500
+ if (div.hasUnreleased) {
501
+ const c = div.unreleased && div.unreleased.count;
502
+ const entry = {
503
+ code: 'UNRELEASED_ON_MAIN',
504
+ message: HALTS.UNRELEASED_ON_MAIN,
505
+ detail: `${c} commit(s) on main since the last bump. The publish-on-merge job can also FAIL on a benign push race — check \`gh run list --workflow publish.yml\` for a failure before assuming this is just timing.`,
506
+ };
507
+ if (allowUnreleased) notes.push({ ...entry, downgraded: true }); else halts.push(entry);
508
+ }
509
+
510
+ if (from && targetVersion) {
511
+ const cmp = divergence.cmpSemver(from, targetVersion);
512
+ if (cmp === 0) halts.push({ code: 'ALREADY_LIVE', message: HALTS.ALREADY_LIVE, detail: `live and target are both ${from}` });
513
+ else if (cmp > 0) halts.push({ code: 'LIVE_AHEAD', message: HALTS.LIVE_AHEAD, detail: `live ${from} > target ${targetVersion}` });
514
+ }
515
+
516
+ return { halts, notes, from, targetVersion, target };
517
+ }
518
+
519
+ // ---------------------------------------------------------------------------
520
+ // Rendering
521
+ // ---------------------------------------------------------------------------
522
+
523
+ const BAR = ' ──────────────────────────────────────────────────────────';
524
+
525
+ function renderPlan(p, { targetName, configPath } = {}) {
526
+ const L = [];
527
+ L.push('');
528
+ L.push(` Go-live plan · ${targetName || 'target'}${configPath ? ` · ${configPath}` : ''}`);
529
+ L.push(BAR);
530
+ L.push(` live now ${p.from || '(unknown)'}`);
531
+ L.push(` target ${p.targetVersion || '(unresolved)'}`);
532
+ if (p.marker) L.push(` verify ${p.marker.path} contains "${p.marker.needle}"`);
533
+ if (p.registry) L.push(` registry ${p.registry.ok ? `carries ${p.targetVersion}` : 'MISSING'}`);
534
+ // The gate's state is worth a line even when it holds nothing: "artist gate
535
+ // advisory" is the answer to "why did nothing stop?", and a reader who cannot
536
+ // see the level has to go and find it.
537
+ if (p.artistGate && p.artistGate.mode) {
538
+ const open = (p.artistGate.reviews || []).length;
539
+ L.push(` artist gate ${p.artistGate.mode}${open ? ` · ${open} unresolved review${open === 1 ? '' : 's'}` : ' · nothing open'}`);
540
+ }
541
+ L.push('');
542
+ for (const n of p.notes || []) L.push(` ⚠ ${n.code} — ${n.message}`);
543
+ if (!p.halts.length) {
544
+ L.push(' ✓ no halt conditions — re-run with --apply to move the pin');
545
+ } else {
546
+ L.push(` ✖ ${p.halts.length} halt condition(s) — this go-live will NOT proceed:`);
547
+ for (const h of p.halts) {
548
+ L.push(` ${h.code} — ${h.message}`);
549
+ if (h.detail) L.push(` ${h.detail}`);
550
+ }
551
+ }
552
+ L.push('');
553
+ return L.join('\n');
554
+ }
555
+
556
+ // Pull the lines a human needs out of a failed phase. A report that says "exit 1"
557
+ // and swallows the tool's own words costs a whole extra round-trip to re-run the
558
+ // command by hand — which is the exact cost this script exists to remove.
559
+ function failureExcerpt(raw, max = 12) {
560
+ if (!raw) return [];
561
+ const text = `${raw.stdout || ''}\n${raw.stderr || ''}`;
562
+ const lines = text.split('\n').map((l) => l.trimEnd()).filter(Boolean);
563
+ // Prefer the lines that carry a diagnosis over the trailing noise.
564
+ const signal = lines.filter((l) => /error|fail|✖|✗|denied|not found|404|refus|rollback|↩|!\s/i.test(l));
565
+ return (signal.length ? signal : lines).slice(-max);
566
+ }
567
+
568
+ function renderReport(r) {
569
+ const L = [];
570
+ L.push('');
571
+ L.push(` Go-live · ${r.targetName}`);
572
+ L.push(BAR);
573
+ L.push(` ${r.from} → ${r.to}`);
574
+ for (const step of r.steps || []) L.push(` ${step.ok ? (step.warn ? '⚠' : '✓') : '✖'} ${step.name}${step.detail ? ` — ${step.detail}` : ''}`);
575
+
576
+ // A refused rehearsal moved nothing, so the pin and read-back lines below would only
577
+ // alarm: "pin committed NO — the next reset will revert this bump" about a bump that
578
+ // never started (task 1004306).
579
+ if (r.failedAt === 'PREFLIGHT') {
580
+ const ex = failureExcerpt(r.raw);
581
+ if (ex.length) {
582
+ L.push('');
583
+ L.push(' what the upgrade said:');
584
+ for (const l of ex) L.push(` ${l}`);
585
+ }
586
+ L.push('');
587
+ L.push(` Nothing changed — still on ${r.from || 'the current core'}. No timer was stopped and no backup was written.`);
588
+ L.push('');
589
+ return L.join('\n');
590
+ }
591
+
592
+ if (!r.ok) {
593
+ const ex = failureExcerpt(r.raw);
594
+ if (ex.length) {
595
+ L.push('');
596
+ L.push(` what ${r.failedAt ? r.failedAt.toLowerCase() : 'it'} actually said:`);
597
+ for (const l of ex) L.push(` ${l}`);
598
+ }
599
+ if (r.rolledBack) {
600
+ L.push('');
601
+ L.push(' The instance auto-rolled-back and is serving the PREVIOUS core — it is not broken.');
602
+ }
603
+ }
604
+
605
+ L.push('');
606
+ L.push(` live reads back ${r.liveVersion || '(unread)'}`);
607
+ const mode = r.pinMode || DEFAULT_PIN_MODE;
608
+ if (mode === 'leave-dirty') L.push(' pin left in the working tree (pinMode leave-dirty)');
609
+ else if (r.pinCommitted) L.push(` pin committed yes${mode === 'local-commit' ? ' (local commit — this target\'s remote is not ours to push)' : ''}`);
610
+ else L.push(' pin committed NO — the next pull-deploy reset will revert this bump');
611
+ L.push('');
612
+ return L.join('\n');
613
+ }
614
+
615
+ // ---------------------------------------------------------------------------
616
+ // Phases
617
+ // ---------------------------------------------------------------------------
618
+
619
+ // Registry proof + optional content proof, in ONE round-trip. The registry is still
620
+ // consulted ON THE BOX — not because auth lives there (the package is public now), but
621
+ // because the box's answer is the one that matters: its network, its resolver, its cache.
622
+ function probeRemote(target, targetVersion, marker, opts = {}) {
623
+ const pkg = target.registryPackage || '@bongos/core';
624
+ const script = `
625
+ set -uo pipefail
626
+ echo "##REGISTRY##"
627
+ ${asOwner(target, `npm view ${pkg}@${targetVersion} version`)} 2>&1 | tail -1
628
+ echo "##TREE##"
629
+ ( cd ${target.instanceDir} && ${target.runAs ? `sudo -u ${target.runAs} -H ` : ''}git status --porcelain | head -20 )
630
+ echo "##INSTALLED##"
631
+ ${asOwner(target, `node -e "console.log(require('${target.instanceDir}/node_modules/${pkg}/package.json').version)"`)} 2>&1 | tail -1
632
+ ${marker ? `echo "##MARKER##"
633
+ ${asOwner(target, `sh -c ${shq(markerProbe(pkg, targetVersion, marker))}`)}` : ''}
634
+ echo "##END##"
635
+ `;
636
+ const res = remote(target, script, opts);
637
+ const section = (n) => {
638
+ const m = res.stdout.split(`##${n}##`)[1];
639
+ return m === undefined ? null : m.split('##')[0].trim();
640
+ };
641
+ // `npm view` on a missing version exits non-zero and its last line is a path to a
642
+ // debug log — useless in a report. Anything that is not a version is reported as
643
+ // "not published", which is the fact the reader actually needs.
644
+ const registryRaw = section('REGISTRY');
645
+ const registryVersion = registryRaw && SEMVER_RE.test(registryRaw) ? registryRaw : null;
646
+ return {
647
+ reachable: res.ok || res.stdout.includes('##END##'),
648
+ raw: res,
649
+ registry: { ok: registryVersion === targetVersion, reported: registryVersion, raw: registryRaw },
650
+ boxTreeDirty: (section('TREE') || '') !== '',
651
+ boxTreeDetail: section('TREE') || '',
652
+ installed: section('INSTALLED'),
653
+ // null = not asked · 'PACK_FAILED' = could not check (NOT the same as absent) · a count.
654
+ markerHits: marker ? parseMarkerHits(section('MARKER')) : null,
655
+ markerError: marker ? (String(section('MARKER') || '').replace(/^PACK_FAILED\s*/, '').trim() || null) : null,
656
+ };
657
+ }
658
+
659
+ // The `bongos upgrade` invocation, as its own function so the pin-mode wiring is
660
+ // assertable without a box.
661
+ //
662
+ // Both non-default modes pass --pin-no-push, which is what tells upgrade.js the repo of
663
+ // record is not ours: `local-commit` pairs it with --commit-pin (commit, no push), and
664
+ // `leave-dirty` sends it alone, which downgrades upgrade.js's "PIN NOT COMMITTED" alarm
665
+ // to a note. That alarm is correct on a pull-deploy instance and misleading here, and an
666
+ // alarm an operator learns to ignore is worse than no alarm.
667
+ function upgradeCommand(target, targetVersion) {
668
+ const mode = pinModeOf(target);
669
+ return [
670
+ `./node_modules/.bin/bongos upgrade`,
671
+ `--to ${targetVersion}`, '--registry',
672
+ `--instance ${target.instanceDir}`,
673
+ `--service ${target.service}`,
674
+ `--health-url ${target.healthUrl}`,
675
+ ...(mode === 'leave-dirty' ? [] : ['--commit-pin']),
676
+ ...(mode === 'push' ? [] : ['--pin-no-push']),
677
+ '--force',
678
+ ].join(' ');
679
+ }
680
+
681
+ // Whether the post-bump pin state is what this target ASKED for. Under `leave-dirty` a
682
+ // modified working tree is the configured outcome, so reporting it as the durability
683
+ // failure it is on a pull-deploy instance would make a correct co-tenant run read as
684
+ // broken — the one place the three modes must not share a verdict.
685
+ function pinStep(mode, pinDirty, head) {
686
+ if (mode === 'leave-dirty') {
687
+ return {
688
+ name: 'pin left in the working tree (pinMode leave-dirty)',
689
+ ok: true,
690
+ detail: pinDirty ? 'package.json/-lock MODIFIED by design — this target has no pull-deploy to revert it' : (head || null),
691
+ };
692
+ }
693
+ return {
694
+ name: mode === 'local-commit' ? 'pin committed locally (not pushed)' : 'pin committed + pushed',
695
+ ok: !pinDirty,
696
+ detail: pinDirty ? 'package.json/-lock still MODIFIED — the next reset --hard reverts this bump' : (head || null),
697
+ };
698
+ }
699
+
700
+ // How many pre-upgrade dumps a backupDir keeps (task 1004306). Nothing pruned them, so
701
+ // the directory grew by one dump per attempt for as long as the lane ran: 37 dumps and
702
+ // 1.7 GB on cloudbongos.com by 2026-09-26, at about ONE attempt a day. The count, not an age,
703
+ // is the bound because the cadence is what varies — ten is ten at daily or at every
704
+ // fifteen minutes. These are the extra copies taken right before a pin move; the
705
+ // nightly backup (db-backup-nightly.sh, 30 days) is the history and is not touched.
706
+ const PRE_UPGRADE_KEEP = 10;
707
+ // Exactly the name Phase A writes: pre-<version>-<YYYYMMDDTHHMMSSZ>.sql.gz. A looser
708
+ // `pre-*` would also take a dump an operator named by hand — the box has a
709
+ // `pre-lane-sweep-<ts>.sql.gz` in that directory, and it is not ours to delete.
710
+ const D8 = '[0-9]'.repeat(8);
711
+ const D6 = '[0-9]'.repeat(6);
712
+ const PRE_UPGRADE_GLOB = `pre-[0-9]*-${D8}T${D6}Z.sql.gz`;
713
+
714
+ // Delete all but the newest PRE_UPGRADE_KEEP pre-upgrade dumps and print how many went.
715
+ // Newest by mtime, never by name: the name sorts 1.19.99 after 1.19.100. It runs only
716
+ // after a dump succeeded, so a run of failures can never empty the directory, and the
717
+ // dump just written is always the newest and always kept. No `$` anywhere, so the
718
+ // outer shell that feeds this to `bash -c` expands nothing in it.
719
+ function pruneCommand(dir, keep = PRE_UPGRADE_KEEP) {
720
+ return `bash -c "cd ${dir} && ls -1t -- ${PRE_UPGRADE_GLOB} 2>/dev/null | tail -n +${keep + 1} | xargs -r rm -v -- | wc -l"`;
721
+ }
722
+
723
+ // Read the prune section back into a step. A prune that could not run is a WARNING,
724
+ // not a failure: the dump it follows is good, and refusing the upgrade over a full
725
+ // cleanup would trade a real deploy for tidiness. It still says so on screen.
726
+ function pruneStep(section, keep = PRE_UPGRADE_KEEP) {
727
+ const name = `prune old pre-upgrade backups (keep the newest ${keep})`;
728
+ const s = String(section == null ? '' : section).trim();
729
+ if (/^\d+$/.test(s)) return { name, ok: true, detail: s === '0' ? 'nothing to remove' : `removed ${s}` };
730
+ return { name, ok: true, warn: true, detail: `could not prune${s ? ` (${s.split('\n').pop()})` : ''} — the directory will keep growing until this is fixed` };
731
+ }
732
+
733
+ function applyGoLive(target, targetName, targetVersion, from, opts = {}) {
734
+ const pkg = target.registryPackage || '@bongos/core';
735
+ const pinMode = pinModeOf(target);
736
+ const steps = [];
737
+ const upgrade = upgradeCommand(target, targetVersion);
738
+
739
+ // Phase 0 — ask the upgrade whether it WILL go, before anything is stopped or copied
740
+ // (task 1004306). `bongos upgrade --dry-run` runs every refusal the real bump has —
741
+ // the artist gate, module compatibility, the database identity, the downgrade guard —
742
+ // and returns before it changes anything. Phase A used to come first, so on
743
+ // cloudbongos.com (2026-09-26 17:10 and 17:15 UTC) each attempt the artist gate
744
+ // refused had already stopped the deploy timer and written a 65 MB dump: one a day at
745
+ // the daily cadence, a full disk in about three days at every fifteen minutes.
746
+ // runGoLive's own gate read did not stop those runs either, and left no trace of what
747
+ // it saw: on --apply a plan with no halts is never printed, notes included. The bump's
748
+ // pre-flight asks the instance directly, and it was the first thing to say no.
749
+ const rehearsal = remote(target, `
750
+ set -uo pipefail
751
+ ${asOwner(target, `bash -c "cd ${target.instanceDir} && ${upgrade} --dry-run"`)}
752
+ `, opts);
753
+ steps.push({
754
+ name: 'pre-flight (the upgrade, rehearsed with --dry-run)',
755
+ ok: rehearsal.ok,
756
+ detail: rehearsal.ok ? null : 'refused — nothing was stopped and nothing was backed up',
757
+ });
758
+ if (!rehearsal.ok) return { ok: false, steps, from, to: targetVersion, targetName, pinMode, failedAt: 'PREFLIGHT', refused: true, raw: rehearsal };
759
+
760
+ // Phase A — stop the pull-deploy timer, then back up. The timer's `reset --hard`
761
+ // is the hazard: it would revert an uncommitted pin mid-flight. A co-tenant has no
762
+ // such timer (see REQUIRED_FIELDS), so there is nothing to stop and no hazard.
763
+ //
764
+ // The dump must FAIL when pg_dump fails. `pg_dump | gzip > f` without pipefail
765
+ // reports gzip's success, leaving a 20-byte file that reads as a backup — harmless
766
+ // while nothing pruned, but the prune below keeps the newest ten, so a streak of
767
+ // those would retire every real dump (task 1004306). A failed dump removes its file
768
+ // and fails the phase, which stops the go-live before the pin moves: a bump with no
769
+ // backup behind it is not one to make unattended. $TS is expanded once by this
770
+ // script so the dump and its cleanup name the same file.
771
+ const backupDir = target.backupDir || '~/backups';
772
+ const dumpFile = `${backupDir}/pre-${targetVersion}-$TS.sql.gz`;
773
+ const backup = target.backupDb
774
+ ? asOwner(target, `bash -c "set -o pipefail; mkdir -p ${backupDir} && { pg_dump ${target.backupDb} | gzip > ${dumpFile} || { rm -f ${dumpFile}; exit 1; }; }"`)
775
+ : 'echo "(no backupDb configured — skipping)"';
776
+ // `|| echo`: under `set -e` a failed prune would otherwise fail the whole phase and
777
+ // stop a deploy whose backup is already safely on disk (see pruneStep).
778
+ const prune = target.backupDb
779
+ ? `echo "##PRUNE##"; ${asOwner(target, pruneCommand(backupDir))} || echo "prune exited non-zero"`
780
+ : '';
781
+ const phaseA = remote(target, `
782
+ set -euo pipefail
783
+ ${SUDO_PREAMBLE}
784
+ echo "##TIMER##"; ${target.deployTimer
785
+ ? `$SUDO systemctl stop ${target.deployTimer} && $SUDO systemctl is-active ${target.deployTimer} || true`
786
+ : 'echo "(no deployTimer configured — no pull-deploy to stop)"'}
787
+ TS="$(date -u +%Y%m%dT%H%M%SZ)"
788
+ echo "##BACKUP##"; ${backup}
789
+ ${prune}
790
+ echo "##END##"
791
+ `, opts);
792
+ steps.push({
793
+ name: target.deployTimer ? `stop ${target.deployTimer} + backup` : 'backup (no pull-deploy timer)',
794
+ ok: phaseA.ok,
795
+ detail: phaseA.ok ? null : (phaseA.stderr || '').trim().split('\n').pop(),
796
+ });
797
+ if (!phaseA.ok) {
798
+ // The timer may already be stopped — Phase A stops it before the dump, and a dump
799
+ // can now fail on its own (above). Put it back, as a failed upgrade does below.
800
+ if (target.deployTimer) remote(target, `${SUDO_PREAMBLE}\n$SUDO systemctl start ${target.deployTimer} || true`, opts);
801
+ return { ok: false, steps, from, to: targetVersion, targetName, pinMode, failedAt: 'PREPARE', raw: phaseA };
802
+ }
803
+ if (target.backupDb) {
804
+ const m = (phaseA.stdout || '').split('##PRUNE##')[1];
805
+ steps.push(pruneStep(m === undefined ? null : m.split('##')[0]));
806
+ }
807
+
808
+ // Phase B — the upgrade itself. --commit-pin makes the bump durable against the
809
+ // pull-deploy reset; auto-rollback stays ON (do NOT pass --no-rollback-on-failure).
810
+ const phaseB = remote(target, `
811
+ set -uo pipefail
812
+ ${asOwner(target, `bash -c "cd ${target.instanceDir} && ${upgrade}"`)}
813
+ `, opts);
814
+ const rolledBack = /rolled back/i.test(phaseB.stdout + phaseB.stderr);
815
+ steps.push({
816
+ name: `upgrade ${from} → ${targetVersion}`,
817
+ ok: phaseB.ok && !rolledBack,
818
+ detail: rolledBack ? 'AUTO-ROLLBACK ran — the health check failed after restart' : (phaseB.ok ? null : `exit ${phaseB.status}`),
819
+ });
820
+ if (!phaseB.ok || rolledBack) {
821
+ // Restart the timer even on failure — leaving it stopped silently disables
822
+ // the instance's pull-deploy until someone notices. Nothing was stopped on a
823
+ // co-tenant, so there is nothing to put back.
824
+ if (target.deployTimer) remote(target, `${SUDO_PREAMBLE}\n$SUDO systemctl start ${target.deployTimer} || true`, opts);
825
+ return { ok: false, steps, from, to: targetVersion, targetName, pinMode, failedAt: 'UPGRADE', rolledBack, raw: phaseB };
826
+ }
827
+
828
+ // Phase C — restart the timer, force one tick, and read back the BOX-SIDE truth.
829
+ // The apex may sit behind basic_auth and its HTML rides a CDN, so the apex is
830
+ // not evidence; 127.0.0.1 is.
831
+ const phaseC = remote(target, `
832
+ set -uo pipefail
833
+ ${SUDO_PREAMBLE}
834
+ ${target.deployTimer ? `echo "##TIMERSTART##"; $SUDO systemctl start ${target.deployTimer}; $SUDO systemctl is-active ${target.deployTimer}` : ''}
835
+ echo "##PIN##"; ( cd ${target.instanceDir} && ${target.runAs ? `sudo -u ${target.runAs} -H ` : ''}git status --porcelain -- package.json package-lock.json )
836
+ echo "##HEAD##"; ( cd ${target.instanceDir} && ${target.runAs ? `sudo -u ${target.runAs} -H ` : ''}git log -1 --format='%h %s' )
837
+ ${target.deployService ? `echo "##TICK##"; $SUDO systemctl start ${target.deployService} || true; $SUDO journalctl -u ${target.deployService} -n 20 --no-pager | tail -8` : ''}
838
+ echo "##VERSION##"; curl -s --max-time 20 ${target.versionUrl} | head -c 400
839
+ echo ""
840
+ echo "##INSTALLED##"; ${asOwner(target, `node -e "console.log(require('${target.instanceDir}/node_modules/${pkg}/package.json').version)"`)} 2>&1 | tail -1
841
+ echo "##END##"
842
+ `, opts);
843
+ const section = (n) => {
844
+ const m = phaseC.stdout.split(`##${n}##`)[1];
845
+ return m === undefined ? null : m.split('##')[0].trim();
846
+ };
847
+ const pinDirty = (section('PIN') || '') !== '';
848
+ const installed = section('INSTALLED');
849
+ let liveVersion = null;
850
+ try { liveVersion = JSON.parse(section('VERSION') || '{}').coreVersion || null; } catch { liveVersion = null; }
851
+
852
+ if (target.deployTimer) steps.push({ name: `restart ${target.deployTimer}`, ok: (section('TIMERSTART') || '').includes('active') });
853
+ steps.push(pinStep(pinMode, pinDirty, section('HEAD')));
854
+ steps.push({ name: 'installed package version', ok: installed === targetVersion, detail: installed === targetVersion ? installed : `reports ${installed}, expected ${targetVersion}` });
855
+ steps.push({ name: 'live reads back (box-side)', ok: liveVersion === targetVersion, detail: liveVersion === targetVersion ? liveVersion : `reports ${liveVersion}, expected ${targetVersion}` });
856
+
857
+ const ok = steps.every((s) => s.ok);
858
+ return { ok, steps, from, to: targetVersion, targetName, pinMode, liveVersion, installed, pinCommitted: !pinDirty, raw: phaseC };
859
+ }
860
+
861
+ // ---------------------------------------------------------------------------
862
+ // CLI
863
+ // ---------------------------------------------------------------------------
864
+
865
+ function usage() {
866
+ console.log(`
867
+ go-live — move an enrolled instance's core pin, as one command.
868
+
869
+ node scripts/bongos/go-live.js PLAN only (read-only, the default)
870
+ node scripts/bongos/go-live.js --apply move the pin
871
+ node scripts/bongos/go-live.js --to <version> target a version explicitly
872
+ node scripts/bongos/go-live.js --verify-marker <path>=<needle>
873
+ refuse a target that lacks the change
874
+ node scripts/bongos/go-live.js --target <name> pick a target from the config
875
+ node scripts/bongos/go-live.js --config <path> default: ${DEFAULT_CONFIG}
876
+ node scripts/bongos/go-live.js --allow-unreleased downgrade UNRELEASED_ON_MAIN to a warning
877
+ node scripts/bongos/go-live.js --no-fetch skip the origin/main refresh (default: fetch)
878
+ node scripts/bongos/go-live.js --target-json '{…}' pass a target inline instead of a config file
879
+ node scripts/bongos/go-live.js --no-divergence skip the git-derived checks (needs --to)
880
+ node scripts/bongos/go-live.js --json machine-readable
881
+
882
+ CO-TENANT TARGETS. A provisioned instance has no pull-deploy timer and its repo of
883
+ record is the customer's own, so omit "deployTimer" (the stop/restart is skipped) and
884
+ set "pinMode": "local-commit" (the pin is committed, never pushed). "leave-dirty"
885
+ leaves the bump in the working tree; "push" (the default) is the platform instance.
886
+
887
+ Host topology is NOT baked into the core. ${DEFAULT_CONFIG} (host-owned, not published):
888
+
889
+ ${CONFIG_TEMPLATE}
890
+ `);
891
+ }
892
+
893
+ async function main() {
894
+ if (hasFlag('--help') || hasFlag('-h')) { usage(); return 0; }
895
+
896
+ const json = hasFlag('--json');
897
+ const apply = hasFlag('--apply');
898
+ const allowUnreleased = hasFlag('--allow-unreleased');
899
+
900
+ // An inline target lets a CALLER drive this without inventing a second host-owned
901
+ // config file beside the one it already has. The nightly lane already holds a roster
902
+ // entry; making it also maintain config/go-live.json would be two sources of truth
903
+ // for one box, which is how they drift.
904
+ const inline = arg('--target-json');
905
+ if (inline) {
906
+ let parsed;
907
+ try { parsed = JSON.parse(inline); }
908
+ catch (e) { console.error(` go-live: --target-json is not valid JSON — ${e.message}`); return 2; }
909
+ const errors = validateTarget('inline', parsed);
910
+ if (errors.length) {
911
+ if (json) { console.log(JSON.stringify({ ok: false, halt: 'CONFIG_INVALID', detail: errors.join('; ') }, null, 2)); return 1; }
912
+ console.error(`\n go-live: CONFIG_INVALID — ${errors.join('; ')}\n`);
913
+ return 1;
914
+ }
915
+ return runGoLive({ target: parsed, targetName: arg('--target') || 'inline', configPath: '--target-json', json, apply, allowUnreleased });
916
+ }
917
+
918
+ const cfg = loadConfig({ configPath: arg('--config') });
919
+ if (cfg.error) {
920
+ if (json) { console.log(JSON.stringify({ ok: false, halt: cfg.error, path: cfg.path, detail: cfg.detail }, null, 2)); return 1; }
921
+ console.error(`\n go-live: ${cfg.error} — ${cfg.path}${cfg.detail ? `\n ${cfg.detail}` : ''}`);
922
+ if (cfg.error === 'NO_TARGET_CONFIG') {
923
+ console.error(`\n This file is host-owned and deliberately not shipped in the core.\n Create it with your box's topology:\n\n${CONFIG_TEMPLATE}\n`);
924
+ }
925
+ return 1;
926
+ }
927
+
928
+ const sel = selectTarget(cfg.config, arg('--target'));
929
+ if (sel.error) {
930
+ if (json) { console.log(JSON.stringify({ ok: false, halt: sel.error, detail: sel.detail }, null, 2)); return 1; }
931
+ console.error(`\n go-live: ${sel.error} — ${sel.detail}\n`);
932
+ return 1;
933
+ }
934
+ const { target, name: targetName } = sel;
935
+ return runGoLive({ target, targetName, configPath: cfg.path, json, apply, allowUnreleased });
936
+ }
937
+
938
+ async function runGoLive({ target, targetName, configPath, json, apply, allowUnreleased }) {
939
+ const marker = parseMarker(arg('--verify-marker'));
940
+ if (marker && marker.error) { console.error(` go-live: ${marker.error}`); return 2; }
941
+
942
+ // Resolve the target version: an explicit --to, else CORE_VERSION on main.
943
+ let targetVersion = arg('--to');
944
+ if (targetVersion && !SEMVER_RE.test(targetVersion)) { console.error(` go-live: --to "${targetVersion}" is not a version`); return 2; }
945
+
946
+ // Is there a core GIT CHECKOUT to reason about at all?
947
+ //
948
+ // Every git-derived signal — the target read from origin/main, the UNRELEASED halt,
949
+ // the dirty-checkout halt — presumes this process is running inside a core repo.
950
+ // The nightly lane is NOT: it runs on the box, against an installed package, and it
951
+ // resolves its target from the REGISTRY under a channel policy instead. Running the
952
+ // git checks there would halt every sweep on a condition that does not apply.
953
+ //
954
+ // So the git legs are SKIPPED only when both are true: there is no resolvable
955
+ // origin/main, AND the caller named the version explicitly. A missing checkout with
956
+ // no --to is still an error — silently inventing a target is exactly the class of
957
+ // guess this script exists to refuse.
958
+ // "Am I in a SOURCE checkout?" is `.git` AT OUR ROOT — not "is there a git repo
959
+ // somewhere above me". The installed core package lives inside the INSTANCE's repo
960
+ // and ships its own src/module-api.js, so a naive `git rev-parse HEAD` succeeds
961
+ // there and CORE_VERSION resolves — against the instance repo's main, which is a
962
+ // meaningless answer delivered confidently. That is the failure this check avoids.
963
+ const hasCheckout = fs.existsSync(path.join(ROOT, '.git'));
964
+ const gitless = (!hasCheckout || hasFlag('--no-divergence')) && !!targetVersion;
965
+
966
+ const fetched = (gitless || hasFlag('--no-fetch')) ? { ok: false, skipped: true } : refreshMain();
967
+ const div = gitless ? null : await divergence.check({ base: arg('--url') });
968
+ if (!targetVersion) targetVersion = div && div.onMain;
969
+ if (!targetVersion || !SEMVER_RE.test(targetVersion)) {
970
+ console.error(` go-live: could not resolve a target version${hasCheckout ? ` (read ${JSON.stringify(targetVersion)} from main)` : ' — this is not a core source checkout, so pass --to <version>'}`);
971
+ return 1;
972
+ }
973
+
974
+ const dirtyRes = gitless ? { status: 1 } : spawnSync('git', ['status', '--porcelain'], { cwd: ROOT, encoding: 'utf8' });
975
+ const dirtyCheckout = dirtyRes.status === 0 && (dirtyRes.stdout || '').trim() ? (dirtyRes.stdout || '').trim().split('\n').slice(0, 5).join(', ') : null;
976
+
977
+ // Always read, and deliberately NOT skippable by a flag. ADR 0241 §3 names one
978
+ // escape hatch — the project OWNER's override-request, rationale required and
979
+ // audit-logged — and a `--skip` here would be a second authority path that any
980
+ // builder with the shell could take silently, which is exactly the shape that
981
+ // ADR rejects. An unread gate already degrades to a note; that is the only
982
+ // by-pass, and it says so on screen.
983
+ const artistGate = await readArtistGate();
984
+
985
+ const gitlessGate = artistGateEntries(artistGate);
986
+ const plan = gitless
987
+ ? {
988
+ halts: gitlessGate.halts,
989
+ notes: [
990
+ { code: 'NO_CORE_CHECKOUT', message: `no core git checkout here — target ${targetVersion} was given explicitly, so the git-derived checks (unreleased-on-main, dirty tree) are skipped` },
991
+ ...gitlessGate.notes,
992
+ ],
993
+ from: null,
994
+ targetVersion,
995
+ target,
996
+ }
997
+ : planGoLive({ div, target, targetVersion, dirtyCheckout, allowUnreleased, artistGate });
998
+ plan.artistGate = artistGate;
999
+ plan.marker = marker;
1000
+ if (!fetched.ok && !fetched.skipped) {
1001
+ // Say so rather than silently planning off a ref of unknown age.
1002
+ plan.notes.push({ code: 'MAIN_NOT_FETCHED', message: `could not refresh origin/main (${fetched.reason}) — the target below is read from a ref of unknown age` });
1003
+ }
1004
+
1005
+ // Probe the box only once the local picture is worth acting on — an ssh
1006
+ // round-trip to confirm a plan that already has a halt is wasted.
1007
+ if (!plan.halts.length) {
1008
+ const probe = probeRemote(target, targetVersion, marker);
1009
+ plan.registry = probe.registry;
1010
+ // With no source checkout there is no git-derived `from`; the installed version on
1011
+ // the box IS the truth, and the probe just read it.
1012
+ if (gitless && probe.installed) {
1013
+ plan.from = probe.installed;
1014
+ if (probe.installed === targetVersion) {
1015
+ plan.halts.push({ code: 'ALREADY_LIVE', message: HALTS.ALREADY_LIVE, detail: `installed and target are both ${targetVersion}` });
1016
+ }
1017
+ }
1018
+ if (!probe.reachable) {
1019
+ plan.halts.push({ code: 'BOX_UNREACHABLE', message: `could not reach ${target.ssh}`, detail: (probe.raw.stderr || '').trim().split('\n').pop() });
1020
+ } else {
1021
+ if (!probe.registry.ok) {
1022
+ plan.halts.push({
1023
+ code: 'REGISTRY_MISSING_TARGET', message: HALTS.REGISTRY_MISSING_TARGET,
1024
+ detail: `npm reports ${probe.registry.reported ? JSON.stringify(probe.registry.reported) : 'not published'} for ${target.registryPackage || '@bongos/core'}@${targetVersion}. A version bumped on main but never published leaves main's code reachable by no pin — check \`gh run list --workflow publish.yml\` for a failed run.`,
1025
+ });
1026
+ }
1027
+ if (probe.boxTreeDirty) {
1028
+ plan.halts.push({ code: 'BOX_TREE_DIRTY', message: HALTS.BOX_TREE_DIRTY, detail: probe.boxTreeDetail.split('\n').slice(0, 5).join(', ') });
1029
+ }
1030
+ if (marker && probe.markerHits === 'PACK_FAILED') {
1031
+ // "Could not check" must never render as "absent" — that reads exactly like
1032
+ // the real trap and sends you chasing a version that does not exist.
1033
+ plan.halts.push({
1034
+ code: 'MARKER_UNCHECKED', message: HALTS.MARKER_UNCHECKED,
1035
+ detail: `could not download ${target.registryPackage || '@bongos/core'}@${targetVersion} to inspect it${probe.markerError ? `: ${probe.markerError}` : ''}. This is NOT evidence the change is missing — fix the fetch, or drop --verify-marker and verify by hand.`,
1036
+ });
1037
+ } else if (marker && probe.markerHits === 0) {
1038
+ plan.halts.push({
1039
+ code: 'MARKER_ABSENT', message: HALTS.MARKER_ABSENT,
1040
+ detail: `${targetVersion} does not contain "${marker.needle}" in ${marker.path}. The carrier sitting on main when your fix merged was usually cut BEFORE it (ADR 0161) — try the next version.`,
1041
+ });
1042
+ }
1043
+ }
1044
+ }
1045
+
1046
+ if (!apply || plan.halts.length) {
1047
+ if (json) { console.log(JSON.stringify({ ok: !plan.halts.length, mode: apply ? 'halted' : 'plan', targetName, ...plan }, null, 2)); }
1048
+ else { console.log(renderPlan(plan, { targetName, configPath })); }
1049
+ return plan.halts.length ? 1 : 0;
1050
+ }
1051
+
1052
+ const result = applyGoLive(target, targetName, targetVersion, plan.from);
1053
+ if (json) console.log(JSON.stringify(result, null, 2));
1054
+ else console.log(renderReport(result));
1055
+ return result.ok ? 0 : 1;
1056
+ }
1057
+
1058
+ if (require.main === module) {
1059
+ main().then((c) => { process.exitCode = c; }).catch((e) => {
1060
+ console.error(`go-live: fatal — ${e && e.message ? e.message : e}`);
1061
+ process.exitCode = 1;
1062
+ });
1063
+ }
1064
+
1065
+ module.exports = {
1066
+ loadConfig, selectTarget, validateTarget, planGoLive, artistGateEntries, readArtistGate, ARTIST_GATE_PATH, ARTIST_GATE_LEVELS,
1067
+ parseMarker, parseMarkerHits,
1068
+ renderPlan, renderReport, failureExcerpt, asOwner, isSafeToken, refreshMain, isLocalTarget, gitRefExists, SUDO_PREAMBLE,
1069
+ applyGoLive, upgradeCommand, pinStep, pinModeOf, pruneCommand, pruneStep, PRE_UPGRADE_KEEP, PRE_UPGRADE_GLOB,
1070
+ CONFIG_TEMPLATE, HALTS, SEMVER_RE, PIN_MODES, DEFAULT_PIN_MODE,
1071
+ };