@bongos/core 1.21.174 → 1.21.176

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 (1744) hide show
  1. package/.bongos-core.json +3565 -1515
  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 +14 -14
  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/docs/adr/0029-status-page-outage-resilience.md +6 -6
  58. package/docs/adr/0227-a-task-network-map-is-refused-the-goal-graph-is-the-map.md +1 -1
  59. package/docs/adr/0294-cli-sessions-do-not-expire.md +1 -1
  60. package/docs/adr/0383-sessions-end-after-ten-idle-days.md +35 -0
  61. package/docs/adr/0384-the-raise-page-is-a-hub-module-builders-edit-in-place.md +31 -0
  62. package/docs/adr/README.md +2 -0
  63. package/docs/api/openapi.json +606 -44
  64. package/docs/api-reference.md +25 -12
  65. package/docs/architecture.md +8 -7
  66. package/docs/canonical-permissions.md +3 -3
  67. package/docs/copy-inventory.md +1389 -1437
  68. package/docs/copy-registry.json +2160 -2634
  69. package/docs/design/demonolith-plan.md +6 -6
  70. package/docs/design/modular-architecture/00-research-report.md +1 -1
  71. package/docs/design/project-startup-direction.md +2 -2
  72. package/docs/design/projects-hub-direction-v2.md +1 -1
  73. package/docs/design/reviews/hall-v2/README.md +2 -2
  74. package/docs/design/vanilla-hall-ui-redesign-scope.md +1 -1
  75. package/docs/file-map.md +89 -88
  76. package/docs/handoff-template.md +4 -4
  77. package/docs/module-api-changelog.md +6 -2
  78. package/docs/modules-contract.md +8 -7
  79. package/docs/onboarding/diagrams/01-task-lifecycle.mmd +1 -1
  80. package/docs/onboarding/diagrams/02-rank-ladder.mmd +1 -1
  81. package/docs/onboarding/diagrams/03-drachmae-karma.mmd +1 -1
  82. package/docs/onboarding/diagrams/04-architecture.mmd +1 -1
  83. package/docs/onboarding/diagrams/05-versioning.mmd +1 -1
  84. package/docs/onboarding/diagrams/README.md +2 -2
  85. package/docs/onboarding/diagrams/assertions.json +2 -2
  86. package/docs/onboarding/slash-commands.md +2 -2
  87. package/docs/packs/artist.md +4 -4
  88. package/docs/packs/engineer.md +11 -10
  89. package/docs/packs/ideator.md +7 -7
  90. package/docs/page-inventory.json +25 -1
  91. package/docs/page-readings.json +4388 -4602
  92. package/docs/recipes/README.md +1 -1
  93. package/docs/recipes/audit-replay.md +4 -4
  94. package/docs/recipes/autobongos-windows-host.md +6 -6
  95. package/docs/recipes/bongos-cli-release.md +2 -2
  96. package/docs/recipes/claude-design-loop.md +7 -7
  97. package/docs/recipes/core-release-pipeline.md +19 -19
  98. package/docs/recipes/failed-ship-recovery-proof.md +2 -2
  99. package/docs/recipes/figma-design-loop.md +6 -6
  100. package/docs/recipes/gds-db-backup.md +9 -9
  101. package/docs/recipes/instance-deploy.md +3 -3
  102. package/docs/recipes/instance-first-run.md +1 -1
  103. package/docs/recipes/multi-builder-merge.md +2 -2
  104. package/docs/recipes/ops-gotchas.md +10 -9
  105. package/docs/recipes/packaging-the-core.md +6 -6
  106. package/docs/recipes/parallel-goal-waves.md +4 -4
  107. package/docs/recipes/private-npm-distribution.md +9 -9
  108. package/docs/recipes/redteam-patrol.md +5 -5
  109. package/docs/recipes/render-pilot.md +2 -2
  110. package/docs/recipes/reranking-a-goals-board.md +2 -2
  111. package/docs/recipes/search-index-ingestion.md +5 -5
  112. package/docs/recipes/self-host.md +1 -1
  113. package/docs/recipes/ship-and-regrade.md +4 -4
  114. package/docs/recipes/staging-environment.md +1 -1
  115. package/docs/recipes/standalone-live-docs.md +1 -1
  116. package/docs/recipes/ui-look-before-you-ship.md +2 -2
  117. package/docs/recipes/upgrading-the-core.md +11 -11
  118. package/docs/recipes/windows-builders.md +18 -18
  119. package/docs/research/llm-model-agnostic-and-cheaper-grader.md +6 -6
  120. package/docs/research/task-network-map-readability.md +3 -3
  121. package/migrations/core_278_builder_tester_tag.sql +18 -0
  122. package/migrations/core_279_bongos_shipper_new_scripts_path.sql +13 -0
  123. package/modules/agents/lib/answer-hold.js +1 -1
  124. package/modules/agents/lib/gate.js +1 -1
  125. package/modules/agents/lib/validate.js +1 -1
  126. package/modules/autonomy/gauge.js +1 -1
  127. package/modules/autonomy/governor-docket.js +2 -2
  128. package/modules/autonomy/pollers/routine-timers.js +3 -3
  129. package/modules/autonomy/routes/autonomy.js +3 -3
  130. package/modules/builder-settings/interaction-prefs.js +1 -1
  131. package/modules/builder-settings/render-prefs.js +1 -1
  132. package/modules/builder-settings/routes/settings.js +1 -1
  133. package/modules/builder-settings/skill-prefs.js +2 -2
  134. package/modules/builder-settings/wandering-prefs.js +2 -2
  135. package/modules/copy-desk/module.json +2 -2
  136. package/modules/copy-desk/page-data.js +5 -5
  137. package/modules/copy-desk/page-decisions.js +13 -1
  138. package/modules/copy-desk/proposals.js +4 -4
  139. package/modules/copy-desk/registry.js +2 -2
  140. package/modules/copy-desk/routes/copy-desk-release.js +119 -0
  141. package/modules/copy-desk/routes/copy-desk.js +3 -12
  142. package/modules/copy-desk/skills/tweak/SKILL.md +12 -12
  143. package/modules/copy-desk/tests/copy_flags.mjs +1 -1
  144. package/modules/copy-desk/tests/copy_no_cms.mjs +7 -3
  145. package/modules/copy-desk/tests/copy_proposals.mjs +2 -2
  146. package/modules/copy-desk/tests/copy_queue.mjs +1 -1
  147. package/modules/design-styles/skills/README.md +4 -4
  148. package/modules/design-styles/skills/imagegen-frontend-mobile/SKILL.md +1 -1
  149. package/modules/design-styles/skills/imagegen-frontend-web/SKILL.md +1 -1
  150. package/modules/discord/bug-attachments.js +1 -1
  151. package/modules/discord/ship-broadcast.js +1 -1
  152. package/modules/economy/achievements.js +49 -7
  153. package/modules/economy/cost-classify.js +6 -6
  154. package/modules/economy/cost-report.js +1 -1
  155. package/modules/economy/cost.js +1 -1
  156. package/modules/economy/credits.js +2 -1
  157. package/modules/economy/idea-size.js +2 -2
  158. package/modules/economy/reward.js +2 -0
  159. package/modules/economy/routes/cost.js +1 -1
  160. package/modules/economy/streak.js +43 -4
  161. package/modules/government/asks.js +1 -1
  162. package/modules/government/board.js +19 -2
  163. package/modules/government/catalog.js +3 -0
  164. package/modules/government/migrations/government_033_idea_vote.sql +46 -0
  165. package/modules/government/protected-surfaces.json +48 -47
  166. package/modules/government/recommendations.js +6 -2
  167. package/modules/government/routes/government.js +1 -1
  168. package/modules/grading/generated-provenance.js +13 -5
  169. package/modules/grading/grade-engine.js +1 -1
  170. package/modules/grading/grader-rubric.json +1 -1
  171. package/modules/grading/grader-score.js +1 -1
  172. package/modules/grading/grader-workers/index.js +1 -1
  173. package/modules/grading/grader.js +1 -1
  174. package/modules/grading/routes/grade.js +1 -1
  175. package/modules/hall-ui/public/atlas.html +5 -7
  176. package/modules/hall-ui/public/atlas.js +1 -1
  177. package/modules/hall-ui/public/atlas.states.json +1 -1
  178. package/modules/hall-ui/public/blockers.css +9 -0
  179. package/modules/hall-ui/public/blockers.html +6 -4
  180. package/modules/hall-ui/public/blockers.js +39 -27
  181. package/modules/hall-ui/public/board-room.css +5 -12
  182. package/modules/hall-ui/public/board-room.html +6 -6
  183. package/modules/hall-ui/public/board-room.js +41 -23
  184. package/modules/hall-ui/public/board-room.states.json +1 -1
  185. package/modules/hall-ui/public/brand-apply.js +1 -1
  186. package/modules/hall-ui/public/brand-holes.js +1 -1
  187. package/modules/hall-ui/public/builders.js +40 -86
  188. package/modules/hall-ui/public/city-decide.js +18 -4
  189. package/modules/hall-ui/public/city.html +1 -1
  190. package/modules/hall-ui/public/collab.html +1 -1
  191. package/modules/hall-ui/public/commands.html +6 -9
  192. package/modules/hall-ui/public/copy-desk.html +1 -1
  193. package/modules/hall-ui/public/copy-desk.js +2 -2
  194. package/modules/hall-ui/public/craft-mode.js +4 -0
  195. package/modules/hall-ui/public/deploy.html +6 -2
  196. package/modules/hall-ui/public/deploy.js +21 -13
  197. package/modules/hall-ui/public/diagrams.css +1 -1
  198. package/modules/hall-ui/public/diagrams.html +5 -8
  199. package/modules/hall-ui/public/diagrams.states.json +1 -1
  200. package/modules/hall-ui/public/drachmae.html +3 -7
  201. package/modules/hall-ui/public/fleet.html +3 -2
  202. package/modules/hall-ui/public/fleet.js +0 -4
  203. package/modules/hall-ui/public/gate.html +7 -7
  204. package/modules/hall-ui/public/gate.js +58 -77
  205. package/modules/hall-ui/public/goal-inbox.js +69 -86
  206. package/modules/hall-ui/public/goal-map.html +1 -1
  207. package/modules/hall-ui/public/goals-page.js +5 -5
  208. package/modules/hall-ui/public/goals-render.js +10 -11
  209. package/modules/hall-ui/public/goals.css +10 -0
  210. package/modules/hall-ui/public/goals.html +14 -7
  211. package/modules/hall-ui/public/government.html +3 -5
  212. package/modules/hall-ui/public/government.js +1 -5
  213. package/modules/hall-ui/public/hall-ask.css +57 -0
  214. package/modules/hall-ui/public/hall-ask.js +50 -0
  215. package/modules/hall-ui/public/hall-render.js +117 -57
  216. package/modules/hall-ui/public/hall-widgets.js +11 -11
  217. package/modules/hall-ui/public/idea.html +1 -1
  218. package/modules/hall-ui/public/ideas.html +3 -1
  219. package/modules/hall-ui/public/ideas.js +1 -0
  220. package/modules/hall-ui/public/index.html +15 -6
  221. package/modules/hall-ui/public/index.states.json +1 -1
  222. package/modules/hall-ui/public/mine-lens.js +1 -1
  223. package/modules/hall-ui/public/modules.html +7 -10
  224. package/modules/hall-ui/public/modules.js +0 -2
  225. package/modules/hall-ui/public/my-agents.html +1 -1
  226. package/modules/hall-ui/public/palette.js +5 -5
  227. package/modules/hall-ui/public/primer.html +4 -9
  228. package/modules/hall-ui/public/profile-connections.js +10 -2
  229. package/modules/hall-ui/public/profile-roles.js +3 -10
  230. package/modules/hall-ui/public/profile.html +12 -10
  231. package/modules/hall-ui/public/profile.js +13 -17
  232. package/modules/hall-ui/public/project-settings.html +3 -4
  233. package/modules/hall-ui/public/project-settings.js +0 -3
  234. package/modules/hall-ui/public/ranks.html +5 -11
  235. package/modules/hall-ui/public/ranks.js +6 -8
  236. package/modules/hall-ui/public/roadmap.css +0 -2
  237. package/modules/hall-ui/public/roadmap.html +1 -1
  238. package/modules/hall-ui/public/roadmap.js +16 -51
  239. package/modules/hall-ui/public/roster.html +1 -1
  240. package/modules/hall-ui/public/sessions.html +6 -8
  241. package/modules/hall-ui/public/sessions.js +7 -7
  242. package/modules/hall-ui/public/settings.html +1 -1
  243. package/modules/hall-ui/public/shell-trail.js +1 -1
  244. package/modules/hall-ui/public/shell.js +17 -17
  245. package/modules/hall-ui/public/street-deck.css +2 -1
  246. package/modules/hall-ui/public/street-deck.js +10 -2
  247. package/modules/hall-ui/public/street-desk.js +16 -5
  248. package/modules/hall-ui/public/street.html +1 -1
  249. package/modules/hall-ui/public/studio-lib.js +4 -0
  250. package/modules/hall-ui/public/studio.css +2 -0
  251. package/modules/hall-ui/public/studio.html +1 -1
  252. package/modules/hall-ui/public/studio.js +27 -1
  253. package/modules/hall-ui/public/style.css +43 -26
  254. package/modules/hall-ui/public/task-detail.js +10 -7
  255. package/modules/hall-ui/public/task.css +2 -0
  256. package/modules/hall-ui/public/task.html +3 -1
  257. package/modules/hall-ui/public/task.js +23 -7
  258. package/modules/hall-ui/public/thinking.html +1 -1
  259. package/modules/hall-ui/public/tweak-editor.html +1 -1
  260. package/modules/hall-ui/public/vote-control.js +208 -0
  261. package/modules/hall-ui/public/watch.html +3 -5
  262. package/modules/hall-ui/public/watch.js +5 -4
  263. package/modules/hall-ui/public/welcome-boot.css +130 -0
  264. package/modules/hall-ui/public/welcome-boot.js +334 -0
  265. package/modules/hall-ui/public/welcome-day.webp +0 -0
  266. package/modules/hall-ui/public/welcome-night.webp +0 -0
  267. package/modules/hall-ui/public/work-summary.js +1 -1
  268. package/modules/hall-ui/public/work.css +1 -0
  269. package/modules/hall-ui/public/work.html +3 -1
  270. package/modules/hall-ui/public/work.js +2 -1
  271. package/modules/hall-ui/records/accomplishments.md +16 -0
  272. package/modules/hall-ui/records/hall-ask-card.md +33 -0
  273. package/modules/hall-ui/records/karma-vote-control.md +13 -0
  274. package/modules/hall-ui/records/oversight-family.md +1 -1
  275. package/modules/hall-ui/records/profile-connections.md +2 -0
  276. package/modules/hall-ui/records/profile-roles.md +1 -1
  277. package/modules/hall-ui/records/reading-rooms.md +1 -1
  278. package/modules/hall-ui/records/welcome-tower.md +50 -0
  279. package/modules/ideas/migrations/ideas_011_idea_votes.sql +31 -0
  280. package/modules/ideas/projection.js +1 -1
  281. package/modules/ideas/routes/blockers.js +3 -3
  282. package/modules/ideas/routes/inbox.js +29 -1
  283. package/modules/ideas/routes/ratify-goal.js +1 -1
  284. package/modules/ideas/routing.js +1 -1
  285. package/modules/ideas/templates.js +1 -1
  286. package/modules/ideas/trail-descent.js +1 -1
  287. package/modules/ideas/trail-size.js +1 -1
  288. package/modules/ideas/votes.js +93 -0
  289. package/modules/lifecycle/abandon-leftovers.js +1 -1
  290. package/modules/lifecycle/cascade.js +1 -1
  291. package/modules/lifecycle/conflict-resolve.js +13 -21
  292. package/modules/lifecycle/criterion-ref.js +1 -1
  293. package/modules/lifecycle/db-analytics.js +57 -4
  294. package/modules/lifecycle/db-deps-criteria.js +1 -1
  295. package/modules/lifecycle/db-ship.js +2 -2
  296. package/modules/lifecycle/db-tasks.js +2 -2
  297. package/modules/lifecycle/db-versions.js +1 -1
  298. package/modules/lifecycle/db.js +2 -0
  299. package/modules/lifecycle/dead-deps.js +3 -3
  300. package/modules/lifecycle/dependency-advisory.js +3 -3
  301. package/modules/lifecycle/goal-category.js +1 -1
  302. package/modules/lifecycle/goal-forest.js +1 -1
  303. package/modules/lifecycle/goal-task-relevance-advisory.js +1 -1
  304. package/modules/lifecycle/kickoff-checklist.js +1 -1
  305. package/modules/lifecycle/kickoff-seed.js +1 -1
  306. package/modules/lifecycle/lifecycle.js +2 -0
  307. package/modules/lifecycle/merge-reach.js +29 -15
  308. package/modules/lifecycle/missing-dep-classify.js +3 -3
  309. package/modules/lifecycle/module.json +2 -1
  310. package/modules/lifecycle/page-tweak-approve.js +85 -1
  311. package/modules/lifecycle/page-tweak-hold.js +1 -1
  312. package/modules/lifecycle/publish-reconciler.js +1 -2
  313. package/modules/lifecycle/rot.js +1 -1
  314. package/modules/lifecycle/routes/artist-gate.js +1 -1
  315. package/modules/lifecycle/routes/gate-approvals.js +22 -1
  316. package/modules/lifecycle/routes/goals.js +1 -1
  317. package/modules/lifecycle/routes/task-route-helpers.js +1 -1
  318. package/modules/lifecycle/routes/task-votes.js +54 -0
  319. package/modules/lifecycle/routes/task-write-routes.js +1 -1
  320. package/modules/lifecycle/routes/tasks.js +2 -2
  321. package/modules/lifecycle/routes/versions.js +2 -2
  322. package/modules/lifecycle/ship-card.js +4 -4
  323. package/modules/lifecycle/ship-preflight.js +1 -1
  324. package/modules/lifecycle/task-classifier.js +1 -1
  325. package/modules/lifecycle/task-status.js +1 -1
  326. package/modules/lifecycle/task-visual-db.js +1 -1
  327. package/modules/memory/learnings.js +1 -1
  328. package/modules/memory/pollers/search-index.js +2 -2
  329. package/modules/memory/routes/learnings.js +1 -1
  330. package/modules/memory/routes/memory.js +1 -1
  331. package/modules/memory/search.js +2 -2
  332. package/modules/npm-release/release.js +1 -1
  333. package/modules/onboarding/howto-moments.js +1 -1
  334. package/modules/onboarding/newcomer-restock.js +3 -3
  335. package/modules/onboarding/onboarding.js +1 -1
  336. package/modules/pixel-art/skills/otb-tile-generate/SKILL.md +1 -1
  337. package/modules/platform-identity/origin-containment.js +1 -1
  338. package/modules/platform-identity/publish-gate.js +1 -1
  339. package/modules/platform-identity/tests/platform-identity.mjs +1 -1
  340. package/modules/provisioning/capacity.js +1 -1
  341. package/modules/provisioning/core-upgrade.js +15 -9
  342. package/modules/provisioning/credential-preflight.js +3 -3
  343. package/modules/provisioning/disconnect.js +1 -1
  344. package/modules/provisioning/dns-resolves.js +1 -1
  345. package/modules/provisioning/module.json +1 -1
  346. package/modules/provisioning/onboard-plan.js +1 -1
  347. package/modules/provisioning/paid-shape-gate.js +2 -2
  348. package/modules/provisioning/planet-physics.js +11 -2
  349. package/modules/provisioning/pollers/liveness-sweep.js +1 -1
  350. package/modules/provisioning/pollers/runner-drift-notify.js +5 -5
  351. package/modules/provisioning/provisioning.js +2 -2
  352. package/modules/provisioning/render-lookup.js +1 -1
  353. package/modules/provisioning/render-standup.js +3 -3
  354. package/modules/provisioning/repo-private.js +1 -1
  355. package/modules/provisioning/routes/callback-page.js +1 -1
  356. package/modules/provisioning/routes/core-upgrade.js +23 -3
  357. package/modules/provisioning/routes/provisioning.js +2 -2
  358. package/modules/provisioning/routes/render-standup.js +1 -1
  359. package/modules/provisioning/routes/repo-private.js +1 -1
  360. package/modules/provisioning/soft-limits.js +1 -1
  361. package/modules/provisioning/starter-bundles.js +4 -2
  362. package/modules/provisioning/tests/provisioning.mjs +1 -1
  363. package/modules/public-landing/public/account.html +4 -6
  364. package/modules/public-landing/public/assets/cosmos.css +13 -6
  365. package/modules/public-landing/public/connections.html +4 -6
  366. package/modules/public-landing/public/contact.html +4 -6
  367. package/modules/public-landing/public/guild.html +4 -6
  368. package/modules/public-landing/public/index.html +11 -9
  369. package/modules/public-landing/public/invitations.html +4 -6
  370. package/modules/public-landing/public/privacy.html +4 -6
  371. package/modules/public-landing/public/projects.html +168 -46
  372. package/modules/public-landing/public/terms.html +4 -6
  373. package/modules/raise/content/copy.json +40 -0
  374. package/modules/raise/content/nda.html +39 -0
  375. package/modules/raise/content/settings.json +49 -0
  376. package/modules/raise/db.js +95 -0
  377. package/modules/raise/migrations/raise_001_tables.sql +71 -0
  378. package/modules/raise/module.json +28 -0
  379. package/modules/raise/page.js +194 -0
  380. package/modules/raise/public/edit.js +152 -0
  381. package/modules/raise/public/favicon.svg +1 -0
  382. package/modules/raise/public/logo-ink.svg +1 -0
  383. package/modules/raise/public/logo-night.svg +1 -0
  384. package/modules/raise/public/mode.js +8 -0
  385. package/modules/raise/public/raise.css +234 -0
  386. package/modules/raise/public/raise.js +91 -0
  387. package/modules/raise/raise.js +174 -0
  388. package/modules/raise/routes/raise.js +152 -0
  389. package/modules/raise/views/gate.html +39 -0
  390. package/modules/raise/views/nda.html +21 -0
  391. package/modules/raise/views/page.html +133 -0
  392. package/modules/raise/web.js +72 -0
  393. package/modules/render-deploy/deploys.js +1 -1
  394. package/modules/render-deploy/render.js +2 -2
  395. package/modules/security/secret-scrub.js +3 -3
  396. package/modules/security/security.js +1 -1
  397. package/modules/security/tests/artifact_scan.mjs +1 -1
  398. package/modules/security/tests/mirror.mjs +1 -1
  399. package/modules/security/tests/scan_store.mjs +1 -1
  400. package/modules/sessions/db.js +2 -2
  401. package/modules/sessions/pulse.js +2 -2
  402. package/modules/sessions/routes/sessions.js +1 -1
  403. package/modules/specialities/specialities.js +1 -1
  404. package/modules/status-ui/public/README.md +3 -4
  405. package/modules/status-ui/public/index.html +5 -31
  406. package/modules/status-ui/public/status.js +6 -174
  407. package/modules/status-ui/public/style.css +4 -133
  408. package/modules/ui-design/docs/design-contract.md +3 -3
  409. package/modules/ui-design/kit/README.md +1 -1
  410. package/modules/ui-design/kit/serve.js +13 -4
  411. package/modules/ui-design/scripts/design-sync.js +1 -1
  412. package/modules/ui-design/scripts/figma-design-sync.js +1 -1
  413. package/modules/ui-design/scripts/validate-design.js +1 -1
  414. package/package-lock.json +27 -11
  415. package/package.json +2 -3
  416. package/release-notes.json +178 -0
  417. package/scripts/bongos/CLAUDE.md +15 -0
  418. package/scripts/bongos/abandon.js +137 -0
  419. package/scripts/bongos/accessibility-replay.js +195 -0
  420. package/scripts/bongos/address-park-sweep.sh +91 -0
  421. package/scripts/bongos/adopt-detect.js +123 -0
  422. package/scripts/bongos/adopt-import.js +111 -0
  423. package/scripts/bongos/adopt-preflight.js +187 -0
  424. package/scripts/bongos/adr-namespace.js +273 -0
  425. package/scripts/bongos/agent-invoke.js +689 -0
  426. package/scripts/bongos/agents-sync.js +502 -0
  427. package/scripts/bongos/api-alias-caller-scan.js +256 -0
  428. package/scripts/bongos/api-artifacts.js +91 -0
  429. package/scripts/bongos/api.js +86 -0
  430. package/scripts/bongos/api.ps1 +26 -0
  431. package/scripts/bongos/architect-audit.js +294 -0
  432. package/scripts/bongos/artifact-audit.js +326 -0
  433. package/scripts/bongos/artifact-format.js +203 -0
  434. package/scripts/bongos/artifact-staleness.js +267 -0
  435. package/scripts/bongos/ask.js +231 -0
  436. package/scripts/bongos/audit-authorship.sh +329 -0
  437. package/scripts/bongos/audit-deps.js +189 -0
  438. package/scripts/bongos/audit-gate.js +121 -0
  439. package/scripts/bongos/audit-rank-roles.js +172 -0
  440. package/scripts/bongos/audit-replay.sh +205 -0
  441. package/scripts/bongos/autobongos-digest.js +123 -0
  442. package/scripts/bongos/autobongos-grade-cap.js +187 -0
  443. package/scripts/bongos/autobongos-loop.js +210 -0
  444. package/scripts/bongos/autobongos-run.js +1361 -0
  445. package/scripts/bongos/autobongos-service.cmd +50 -0
  446. package/scripts/bongos/autobongos-service.ps1 +270 -0
  447. package/scripts/bongos/autobongos-tweak-lane.js +262 -0
  448. package/scripts/bongos/autobongos-verify.js +618 -0
  449. package/scripts/bongos/autonomy-gate.js +135 -0
  450. package/scripts/bongos/autonomy-gauge-statusline.js +124 -0
  451. package/scripts/bongos/autonomy-gauge.js +84 -0
  452. package/scripts/bongos/backfill-cost.js +176 -0
  453. package/scripts/bongos/backfill-disciplines.js +144 -0
  454. package/scripts/bongos/backfill-session-earnings.js +123 -0
  455. package/scripts/bongos/backfill-session-types.js +87 -0
  456. package/scripts/bongos/backfill-sessions.js +411 -0
  457. package/scripts/bongos/backfill-subagent-rewards.js +485 -0
  458. package/scripts/bongos/backfill-task-rewards.js +413 -0
  459. package/scripts/bongos/backlog-review.js +399 -0
  460. package/scripts/bongos/backup-dropin-sweep.sh +95 -0
  461. package/scripts/bongos/backup.js +116 -0
  462. package/scripts/bongos/baseline-staleness.js +217 -0
  463. package/scripts/bongos/bfg-principal-token.js +65 -0
  464. package/scripts/bongos/bug-attachment-audit.js +149 -0
  465. package/scripts/bongos/bug-attachment-recover.js +198 -0
  466. package/scripts/bongos/bug-triage.js +292 -0
  467. package/scripts/bongos/build-bongos.js +94 -0
  468. package/scripts/bongos/bump-version.js +221 -0
  469. package/scripts/bongos/capture.js +481 -0
  470. package/scripts/bongos/category-advisory-guard.js +206 -0
  471. package/scripts/bongos/ci-grade.js +82 -0
  472. package/scripts/bongos/claim-recall.js +112 -0
  473. package/scripts/bongos/claim.js +789 -0
  474. package/scripts/bongos/classify-discipline.js +153 -0
  475. package/scripts/bongos/claude-materialize.js +1200 -0
  476. package/scripts/bongos/claude-md-template.js +142 -0
  477. package/scripts/bongos/cleanup-orphans.js +74 -0
  478. package/scripts/bongos/cli-lib.js +1226 -0
  479. package/scripts/bongos/client-baseurl-guard.js +116 -0
  480. package/scripts/bongos/codemod-rename-scripts-gds.js +381 -0
  481. package/scripts/bongos/codemod-rename-src-gds.js +145 -0
  482. package/scripts/bongos/conductor-dispatch.js +535 -0
  483. package/scripts/bongos/context-pack.js +326 -0
  484. package/scripts/bongos/control-manifest.js +199 -0
  485. package/scripts/bongos/copy-apply.js +758 -0
  486. package/scripts/bongos/copy-inventory.js +571 -0
  487. package/scripts/bongos/core-origin-follow.js +185 -0
  488. package/scripts/bongos/core-pin-sync.js +260 -0
  489. package/scripts/bongos/coreB-carve-proof.sh +725 -0
  490. package/scripts/bongos/cost-report.js +63 -0
  491. package/scripts/bongos/cost.js +47 -0
  492. package/scripts/bongos/credential-presence.js +296 -0
  493. package/scripts/bongos/cutover-codemod.js +240 -0
  494. package/scripts/bongos/db-backup-nightly.sh +232 -0
  495. package/scripts/bongos/db-backup-offsite.sh +267 -0
  496. package/scripts/bongos/demote.js +45 -0
  497. package/scripts/bongos/deploy-divergence.js +454 -0
  498. package/scripts/bongos/deploy-main-audit-gate.sh +97 -0
  499. package/scripts/bongos/design-sync.js +12 -0
  500. package/scripts/bongos/dev-box-guard.js +166 -0
  501. package/scripts/bongos/dev-lib.js +722 -0
  502. package/scripts/bongos/dev.js +645 -0
  503. package/scripts/bongos/device-flow-help.js +72 -0
  504. package/scripts/bongos/diagnose-achievements.js +118 -0
  505. package/scripts/bongos/diagram-facts.js +355 -0
  506. package/scripts/bongos/discord-channels.js +77 -0
  507. package/scripts/bongos/do-api.js +109 -0
  508. package/scripts/bongos/doc-cli-guard.js +274 -0
  509. package/scripts/bongos/doc-comment-coverage.js +139 -0
  510. package/scripts/bongos/doc-control-claims.js +170 -0
  511. package/scripts/bongos/docs-entropy.js +453 -0
  512. package/scripts/bongos/doctor.js +493 -0
  513. package/scripts/bongos/enroll-control-plane.js +101 -0
  514. package/scripts/bongos/exec-path-guard.js +564 -0
  515. package/scripts/bongos/feedback-send.js +249 -0
  516. package/scripts/bongos/fetch-art-key.js +106 -0
  517. package/scripts/bongos/fetch-sound-prefs.js +126 -0
  518. package/scripts/bongos/figma-design-sync.js +11 -0
  519. package/scripts/bongos/find-untested.js +371 -0
  520. package/scripts/bongos/fitness-checks-error-envelope.js +134 -0
  521. package/scripts/bongos/fitness-checks-identity.js +343 -0
  522. package/scripts/bongos/fitness-checks-packaging.js +132 -0
  523. package/scripts/bongos/fitness-checks-route-pins.js +76 -0
  524. package/scripts/bongos/fitness-checks-vocabulary.js +392 -0
  525. package/scripts/bongos/fitness-checks-write-validation.js +157 -0
  526. package/scripts/bongos/fitness-lib.js +127 -0
  527. package/scripts/bongos/fitness-migration-contraction.js +50 -0
  528. package/scripts/bongos/fitness-ratchets.js +594 -0
  529. package/scripts/bongos/fitness.js +1498 -0
  530. package/scripts/bongos/forwarder.js +80 -0
  531. package/scripts/bongos/gate-review.js +330 -0
  532. package/scripts/bongos/gating.js +348 -0
  533. package/scripts/{gds → bongos}/gds-db-backup.service +6 -6
  534. package/scripts/{gds → bongos}/gds-db-backup.timer +4 -4
  535. package/scripts/{gds → bongos}/gds-db-offsite.service +4 -4
  536. package/scripts/{gds → bongos}/gds-db-offsite.timer +4 -4
  537. package/scripts/bongos/gds-literal-scan.js +196 -0
  538. package/scripts/bongos/gen-api-client.js +576 -0
  539. package/scripts/bongos/gen-api-docs.js +1111 -0
  540. package/scripts/bongos/gen-atlas.js +366 -0
  541. package/scripts/bongos/gen-diagrams.js +608 -0
  542. package/scripts/bongos/gen-file-map.js +337 -0
  543. package/scripts/bongos/gen-freshness.js +32 -0
  544. package/scripts/bongos/gen-interaction-posture.js +122 -0
  545. package/scripts/bongos/gen-repo-map.js +540 -0
  546. package/scripts/bongos/gen-role-responsibilities.js +134 -0
  547. package/scripts/bongos/gen-session-index.js +243 -0
  548. package/scripts/bongos/gen-sounds.js +176 -0
  549. package/scripts/bongos/git-merge-regen.js +254 -0
  550. package/scripts/bongos/go-live.js +1071 -0
  551. package/scripts/bongos/goal-names.js +102 -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 +336 -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-goals.js +109 -0
  655. package/scripts/bongos/rename-history-check.js +369 -0
  656. package/scripts/bongos/rename-ledger-prose.js +482 -0
  657. package/scripts/bongos/render-api.js +197 -0
  658. package/scripts/bongos/render-check.js +206 -0
  659. package/scripts/bongos/render-ideas.js +226 -0
  660. package/scripts/bongos/render-payload.js +85 -0
  661. package/scripts/bongos/repo-metrics.js +363 -0
  662. package/scripts/bongos/review-sheet.js +108 -0
  663. package/scripts/bongos/role-pack-guard.js +142 -0
  664. package/scripts/bongos/route-shadow-guard.js +175 -0
  665. package/scripts/bongos/routine-schedule.js +283 -0
  666. package/scripts/bongos/run-routine.js +257 -0
  667. package/scripts/bongos/run-unit-tests.js +654 -0
  668. package/scripts/bongos/runner-drift.js +151 -0
  669. package/scripts/bongos/sandbox-stage.js +459 -0
  670. package/scripts/bongos/scope-map-guard.js +300 -0
  671. package/scripts/bongos/scope-roster-guard.js +118 -0
  672. package/scripts/bongos/seam-wiring-guard.js +275 -0
  673. package/scripts/bongos/search-ingest-db.js +288 -0
  674. package/scripts/bongos/search-ingest-md.js +269 -0
  675. package/scripts/bongos/seed-adopt-tasks.js +75 -0
  676. package/scripts/bongos/seed-api-contract-goal-tasks.js +141 -0
  677. package/scripts/bongos/seed-board-room-tasks.js +196 -0
  678. package/scripts/bongos/seed-bongos-app-tasks.js +294 -0
  679. package/scripts/bongos/seed-bongos-coreB-tranche1-tasks.js +81 -0
  680. package/scripts/bongos/seed-bongos-coreB-tranche2-tasks.js +100 -0
  681. package/scripts/bongos/seed-bongos-goal-hierarchy-tasks.js +307 -0
  682. package/scripts/bongos/seed-bongos-module-system-tasks.js +346 -0
  683. package/scripts/bongos/seed-bongos-tasks.js +214 -0
  684. package/scripts/bongos/seed-bongos-v1-idea-routing-tasks.js +152 -0
  685. package/scripts/bongos/seed-bongos-v1-seo-tasks.js +104 -0
  686. package/scripts/bongos/seed-bv1-community-tasks.js +131 -0
  687. package/scripts/bongos/seed-bv1-privacy-invites-tasks.js +133 -0
  688. package/scripts/bongos/seed-bv1-profile-page-tasks.js +161 -0
  689. package/scripts/bongos/seed-bv1-profiles-tasks.js +135 -0
  690. package/scripts/bongos/seed-bv1-r01-delta-tasks.js +154 -0
  691. package/scripts/bongos/seed-bv2-ideator-surface-tasks.js +390 -0
  692. package/scripts/bongos/seed-bv2-tweak-mode-tasks.js +277 -0
  693. package/scripts/bongos/seed-gds-v4-tasks.js +624 -0
  694. package/scripts/bongos/seed-governance-tasks.js +340 -0
  695. package/scripts/bongos/seed-medusa-tasks.js +440 -0
  696. package/scripts/bongos/seed-module-upstreaming.js +219 -0
  697. package/scripts/bongos/seed-productization-tasks.js +235 -0
  698. package/scripts/bongos/seed-project-admin-console-tasks.js +88 -0
  699. package/scripts/bongos/seed-provisioning-tasks.js +83 -0
  700. package/scripts/bongos/seed-staging.sh +117 -0
  701. package/scripts/bongos/seed-strict-versioning-tasks.js +275 -0
  702. package/scripts/bongos/seed-v2-world-tasks.js +283 -0
  703. package/scripts/bongos/seed-verify-criteria.js +124 -0
  704. package/scripts/bongos/sequence.js +597 -0
  705. package/scripts/bongos/session-cost.js +430 -0
  706. package/scripts/bongos/session-digest-build.js +293 -0
  707. package/scripts/bongos/session-digest.js +200 -0
  708. package/scripts/bongos/session-eval.js +631 -0
  709. package/scripts/bongos/session-transcript-build.js +155 -0
  710. package/scripts/bongos/session-transcript-upload.js +29 -0
  711. package/scripts/bongos/session.js +404 -0
  712. package/scripts/bongos/setup.js +646 -0
  713. package/scripts/bongos/ship-check.js +89 -0
  714. package/scripts/bongos/ship-deploy-target.js +393 -0
  715. package/scripts/bongos/ship-escalation.js +167 -0
  716. package/scripts/bongos/ship-finish.js +420 -0
  717. package/scripts/bongos/ship-flow.js +1217 -0
  718. package/scripts/bongos/ship-git.js +100 -0
  719. package/scripts/bongos/ship-grade-steps.js +547 -0
  720. package/scripts/bongos/ship-grade.js +426 -0
  721. package/scripts/bongos/ship-honesty.js +314 -0
  722. package/scripts/bongos/ship-io.js +139 -0
  723. package/scripts/bongos/ship-land.js +1130 -0
  724. package/scripts/bongos/ship-memory-sync.js +249 -0
  725. package/scripts/bongos/ship-merge-gate.js +225 -0
  726. package/scripts/bongos/ship-merge.js +466 -0
  727. package/scripts/bongos/ship-mode-ask.js +138 -0
  728. package/scripts/bongos/ship-mode-manual.js +54 -0
  729. package/scripts/bongos/ship-preflight-steps.js +399 -0
  730. package/scripts/bongos/ship-regen.js +292 -0
  731. package/scripts/bongos/ship-resume.js +201 -0
  732. package/scripts/bongos/ship-session-upload.js +313 -0
  733. package/scripts/bongos/ship-state.js +110 -0
  734. package/scripts/bongos/ship-surprise.js +84 -0
  735. package/scripts/bongos/ship-visual.js +75 -0
  736. package/scripts/bongos/ship.js +382 -0
  737. package/scripts/bongos/shipping-mode.js +71 -0
  738. package/scripts/bongos/skill-lint.js +250 -0
  739. package/scripts/bongos/skill-preflight.js +361 -0
  740. package/scripts/bongos/smoke-batch-claim.sh +238 -0
  741. package/scripts/bongos/smoke-batch-release.sh +316 -0
  742. package/scripts/bongos/smoke-claim-consistency.sh +222 -0
  743. package/scripts/bongos/smoke-dependencies.sh +143 -0
  744. package/scripts/bongos/smoke-gds.js +256 -0
  745. package/scripts/bongos/smoke-write.sh +275 -0
  746. package/scripts/bongos/source-text-test-scan.js +106 -0
  747. package/scripts/bongos/spark.js +294 -0
  748. package/scripts/bongos/stale-worktrees.js +212 -0
  749. package/scripts/bongos/start-goals.js +102 -0
  750. package/scripts/bongos/start.js +1090 -0
  751. package/scripts/bongos/status.js +545 -0
  752. package/scripts/bongos/strand-watch.js +315 -0
  753. package/scripts/bongos/stranded-rows.js +200 -0
  754. package/scripts/bongos/stray-unit-sweep.sh +71 -0
  755. package/scripts/bongos/surface.js +101 -0
  756. package/scripts/bongos/task.js +273 -0
  757. package/scripts/bongos/test-path-guard.js +99 -0
  758. package/scripts/bongos/triage.js +742 -0
  759. package/scripts/bongos/turn-end-sound.js +74 -0
  760. package/scripts/bongos/tweak-halt.js +70 -0
  761. package/scripts/bongos/tweak-renders.js +200 -0
  762. package/scripts/bongos/uat.js +120 -0
  763. package/scripts/bongos/ui-kit-transform.js +43 -0
  764. package/scripts/bongos/update-channel.js +512 -0
  765. package/scripts/bongos/update-sweep.js +829 -0
  766. package/scripts/bongos/upgrade-artist-gate.js +46 -0
  767. package/scripts/bongos/upgrade-commit-identity.js +32 -0
  768. package/scripts/bongos/upgrade-migrate.js +224 -0
  769. package/scripts/bongos/upgrade-operator.js +73 -0
  770. package/scripts/bongos/upgrade-outcome.js +174 -0
  771. package/scripts/bongos/upgrade.js +1499 -0
  772. package/scripts/bongos/validate-design.js +12 -0
  773. package/scripts/bongos/version-close.js +621 -0
  774. package/scripts/bongos/version-literal-guard.js +140 -0
  775. package/scripts/bongos/version-select.js +79 -0
  776. package/scripts/bongos/visual-review-nudge.js +39 -0
  777. package/scripts/bongos/wedge-remedy.js +174 -0
  778. package/scripts/bongos/worktree-claim-guard.js +130 -0
  779. package/scripts/bongos/worktree.js +449 -0
  780. package/scripts/discord/post.js +1 -1
  781. package/scripts/gds/README.md +9 -0
  782. package/scripts/gds/abandon.js +6 -136
  783. package/scripts/gds/accessibility-replay.js +5 -194
  784. package/scripts/gds/address-park-sweep.sh +7 -90
  785. package/scripts/gds/adopt-detect.js +5 -121
  786. package/scripts/gds/adopt-import.js +5 -109
  787. package/scripts/gds/adopt-preflight.js +5 -185
  788. package/scripts/gds/adr-namespace.js +5 -271
  789. package/scripts/gds/agent-invoke.js +5 -687
  790. package/scripts/gds/agents-sync.js +5 -500
  791. package/scripts/gds/api-alias-caller-scan.js +5 -255
  792. package/scripts/gds/api-artifacts.js +6 -0
  793. package/scripts/gds/api.js +6 -85
  794. package/scripts/gds/api.ps1 +8 -26
  795. package/scripts/gds/architect-audit.js +6 -293
  796. package/scripts/gds/artifact-audit.js +5 -324
  797. package/scripts/gds/artifact-format.js +6 -203
  798. package/scripts/gds/artifact-staleness.js +5 -265
  799. package/scripts/gds/ask.js +5 -229
  800. package/scripts/gds/audit-authorship.sh +7 -328
  801. package/scripts/gds/audit-deps.js +6 -188
  802. package/scripts/gds/audit-gate.js +5 -119
  803. package/scripts/gds/audit-rank-roles.js +6 -171
  804. package/scripts/gds/audit-replay.sh +7 -204
  805. package/scripts/gds/autobongos-digest.js +5 -121
  806. package/scripts/gds/autobongos-grade-cap.js +5 -186
  807. package/scripts/gds/autobongos-loop.js +5 -208
  808. package/scripts/gds/autobongos-run.js +5 -1359
  809. package/scripts/gds/autobongos-service.cmd +8 -49
  810. package/scripts/gds/autobongos-service.ps1 +8 -270
  811. package/scripts/gds/autobongos-tweak-lane.js +5 -261
  812. package/scripts/gds/autobongos-verify.js +5 -616
  813. package/scripts/gds/autonomy-gate.js +5 -133
  814. package/scripts/gds/autonomy-gauge-statusline.js +5 -122
  815. package/scripts/gds/autonomy-gauge.js +5 -82
  816. package/scripts/gds/backfill-cost.js +6 -175
  817. package/scripts/gds/backfill-disciplines.js +5 -142
  818. package/scripts/gds/backfill-session-earnings.js +5 -121
  819. package/scripts/gds/backfill-session-types.js +5 -85
  820. package/scripts/gds/backfill-sessions.js +5 -409
  821. package/scripts/gds/backfill-subagent-rewards.js +5 -483
  822. package/scripts/gds/backfill-task-rewards.js +5 -411
  823. package/scripts/gds/backlog-review.js +6 -398
  824. package/scripts/gds/backup-dropin-sweep.sh +7 -94
  825. package/scripts/gds/backup.js +6 -115
  826. package/scripts/gds/baseline-staleness.js +5 -215
  827. package/scripts/gds/bfg-principal-token.js +6 -64
  828. package/scripts/gds/bug-attachment-audit.js +5 -147
  829. package/scripts/gds/bug-attachment-recover.js +5 -196
  830. package/scripts/gds/bug-triage.js +6 -291
  831. package/scripts/gds/build-bongos.js +5 -92
  832. package/scripts/gds/bump-version.js +5 -219
  833. package/scripts/gds/capture.js +6 -480
  834. package/scripts/gds/category-advisory-guard.js +5 -205
  835. package/scripts/gds/ci-grade.js +6 -81
  836. package/scripts/gds/claim-recall.js +6 -111
  837. package/scripts/gds/claim.js +6 -788
  838. package/scripts/gds/classify-discipline.js +6 -152
  839. package/scripts/gds/claude-materialize.js +5 -1198
  840. package/scripts/gds/claude-md-template.js +5 -140
  841. package/scripts/gds/cleanup-orphans.js +6 -73
  842. package/scripts/gds/cli-lib.js +6 -1204
  843. package/scripts/gds/client-baseurl-guard.js +5 -114
  844. package/scripts/gds/codemod-rename-src-gds.js +6 -144
  845. package/scripts/gds/conductor-dispatch.js +6 -534
  846. package/scripts/gds/context-pack.js +6 -325
  847. package/scripts/gds/control-manifest.js +5 -197
  848. package/scripts/gds/copy-apply.js +5 -756
  849. package/scripts/gds/copy-inventory.js +5 -569
  850. package/scripts/gds/core-origin-follow.js +5 -184
  851. package/scripts/gds/core-pin-sync.js +5 -258
  852. package/scripts/gds/coreB-carve-proof.sh +7 -724
  853. package/scripts/gds/cost-report.js +6 -62
  854. package/scripts/gds/cost.js +6 -46
  855. package/scripts/gds/credential-presence.js +5 -294
  856. package/scripts/gds/cutover-codemod.js +5 -239
  857. package/scripts/gds/db-backup-nightly.sh +7 -231
  858. package/scripts/gds/db-backup-offsite.sh +7 -266
  859. package/scripts/gds/demote.js +6 -44
  860. package/scripts/gds/deploy-divergence.js +6 -445
  861. package/scripts/gds/deploy-main-audit-gate.sh +7 -96
  862. package/scripts/gds/design-sync.js +5 -10
  863. package/scripts/gds/dev-box-guard.js +5 -164
  864. package/scripts/gds/dev-lib.js +5 -721
  865. package/scripts/gds/dev.js +5 -643
  866. package/scripts/gds/device-flow-help.js +5 -70
  867. package/scripts/gds/diagnose-achievements.js +5 -116
  868. package/scripts/gds/diagram-facts.js +6 -355
  869. package/scripts/gds/discord-channels.js +5 -75
  870. package/scripts/gds/do-api.js +6 -109
  871. package/scripts/gds/doc-cli-guard.js +5 -266
  872. package/scripts/gds/doc-comment-coverage.js +5 -137
  873. package/scripts/gds/doc-control-claims.js +5 -166
  874. package/scripts/gds/docs-entropy.js +5 -443
  875. package/scripts/gds/doctor.js +6 -492
  876. package/scripts/gds/enroll-control-plane.js +5 -99
  877. package/scripts/gds/exec-path-guard.js +5 -562
  878. package/scripts/gds/feedback-send.js +5 -247
  879. package/scripts/gds/fetch-art-key.js +5 -104
  880. package/scripts/gds/fetch-sound-prefs.js +5 -124
  881. package/scripts/gds/figma-design-sync.js +5 -9
  882. package/scripts/gds/find-untested.js +5 -369
  883. package/scripts/gds/fitness-checks-error-envelope.js +5 -133
  884. package/scripts/gds/fitness-checks-identity.js +5 -342
  885. package/scripts/gds/fitness-checks-packaging.js +5 -131
  886. package/scripts/gds/fitness-checks-route-pins.js +5 -75
  887. package/scripts/gds/fitness-checks-vocabulary.js +5 -391
  888. package/scripts/gds/fitness-checks-write-validation.js +5 -156
  889. package/scripts/gds/fitness-lib.js +5 -126
  890. package/scripts/gds/fitness-migration-contraction.js +5 -49
  891. package/scripts/gds/fitness-ratchets.js +5 -563
  892. package/scripts/gds/fitness.js +5 -1493
  893. package/scripts/gds/gate-review.js +5 -328
  894. package/scripts/gds/gating.js +5 -346
  895. package/scripts/gds/gds-literal-scan.js +5 -194
  896. package/scripts/gds/gen-api-client.js +5 -555
  897. package/scripts/gds/gen-api-docs.js +5 -1100
  898. package/scripts/gds/gen-atlas.js +5 -364
  899. package/scripts/gds/gen-diagrams.js +6 -607
  900. package/scripts/gds/gen-file-map.js +5 -335
  901. package/scripts/gds/gen-freshness.js +5 -31
  902. package/scripts/gds/gen-interaction-posture.js +5 -120
  903. package/scripts/gds/gen-repo-map.js +5 -538
  904. package/scripts/gds/gen-role-responsibilities.js +5 -133
  905. package/scripts/gds/gen-session-index.js +5 -241
  906. package/scripts/gds/gen-sounds.js +5 -174
  907. package/scripts/gds/git-merge-regen.js +6 -291
  908. package/scripts/gds/go-live.js +5 -1069
  909. package/scripts/gds/goal-names.js +5 -100
  910. package/scripts/gds/goal.js +6 -271
  911. package/scripts/gds/government-walk.js +5 -1475
  912. package/scripts/gds/grade-correlation-audit.js +5 -308
  913. package/scripts/gds/grade-replay.js +5 -235
  914. package/scripts/gds/grade-smoke.js +6 -204
  915. package/scripts/gds/home-isolation-guard.js +5 -125
  916. package/scripts/gds/hooks/pre-push.js +5 -209
  917. package/scripts/gds/howto.js +5 -143
  918. package/scripts/gds/http-api-client.js +6 -81
  919. package/scripts/gds/identity-strip.js +5 -74
  920. package/scripts/gds/init.js +5 -1157
  921. package/scripts/gds/install-git-hooks.js +5 -198
  922. package/scripts/gds/instance-apex.js +5 -37
  923. package/scripts/gds/intent-retry.js +5 -51
  924. package/scripts/gds/key-card.js +6 -221
  925. package/scripts/gds/key-status.js +5 -124
  926. package/scripts/gds/land-watch.js +5 -199
  927. package/scripts/gds/leak-scan-allowlist.js +5 -291
  928. package/scripts/gds/learning-capture.js +6 -144
  929. package/scripts/gds/lib.sh +7 -73
  930. package/scripts/gds/linkify-refs.js +6 -654
  931. package/scripts/gds/lint-infra-exec.js +5 -68
  932. package/scripts/gds/lint-migrations.js +5 -100
  933. package/scripts/gds/lint-workflow-exec.js +5 -61
  934. package/scripts/gds/local-preview-lib.js +6 -128
  935. package/scripts/gds/local-preview.js +6 -81
  936. package/scripts/gds/login.js +5 -358
  937. package/scripts/gds/main-audit.js +5 -623
  938. package/scripts/gds/me.js +6 -96
  939. package/scripts/gds/memory-map.js +5 -174
  940. package/scripts/gds/merge-lock.js +6 -70
  941. package/scripts/gds/migration-namespace.js +5 -311
  942. package/scripts/gds/mirror-lineage-check.js +5 -341
  943. package/scripts/gds/mirror-redact.js +5 -348
  944. package/scripts/gds/module-artifact.js +6 -289
  945. package/scripts/gds/module-assess-docs.js +6 -237
  946. package/scripts/gds/module-assess-installs.js +6 -227
  947. package/scripts/gds/module-assess-score.js +6 -110
  948. package/scripts/gds/module-assess-security.js +6 -251
  949. package/scripts/gds/module-assess-tests.js +6 -277
  950. package/scripts/gds/module-assess-version.js +6 -91
  951. package/scripts/gds/module-error-report.js +5 -146
  952. package/scripts/gds/module-test-runner.js +6 -413
  953. package/scripts/gds/module.js +5 -1374
  954. package/scripts/gds/move-escalation.js +5 -140
  955. package/scripts/gds/newcomer-floor.js +6 -420
  956. package/scripts/gds/newcomer-floor.test.js +6 -234
  957. package/scripts/gds/next-number.js +6 -162
  958. package/scripts/gds/oauth-secret.js +5 -200
  959. package/scripts/gds/onboard.js +5 -265
  960. package/scripts/gds/onboarding-analyze.js +6 -225
  961. package/scripts/gds/onboarding-config.js +6 -179
  962. package/scripts/gds/onboarding-ship.js +6 -91
  963. package/scripts/gds/pack-env-prefix.js +5 -72
  964. package/scripts/gds/package-core.js +5 -1102
  965. package/scripts/gds/page-inventory.js +5 -346
  966. package/scripts/gds/page-reader.js +5 -720
  967. package/scripts/gds/paste-token.js +6 -211
  968. package/scripts/gds/plain-cards.js +5 -350
  969. package/scripts/gds/portability-smoke-art.sh +7 -84
  970. package/scripts/gds/portability-smoke-memory.sh +7 -175
  971. package/scripts/gds/preflight.js +5 -212
  972. package/scripts/gds/probe-cache.js +5 -244
  973. package/scripts/gds/prove-strict-versioning.js +6 -283
  974. package/scripts/gds/provision-auto-upgrade.js +5 -161
  975. package/scripts/gds/provision-byo-host.js +5 -67
  976. package/scripts/gds/provision-capacity.js +5 -78
  977. package/scripts/gds/provision-caps.js +5 -62
  978. package/scripts/gds/provision-config.js +5 -232
  979. package/scripts/gds/provision-core-upgrade.js +5 -1165
  980. package/scripts/gds/provision-disconnect.js +5 -87
  981. package/scripts/gds/provision-github-setup.js +5 -167
  982. package/scripts/gds/provision-net.js +5 -356
  983. package/scripts/gds/provision-pin-key.js +5 -175
  984. package/scripts/gds/provision-pin-replay.js +5 -125
  985. package/scripts/gds/provision-process.js +5 -169
  986. package/scripts/gds/provision-render.js +5 -200
  987. package/scripts/gds/provision-repo-auth.js +5 -163
  988. package/scripts/gds/provision-repo-private.js +5 -97
  989. package/scripts/gds/provision-repo.js +5 -1336
  990. package/scripts/gds/provision-teardown.js +5 -105
  991. package/scripts/gds/provision-units.js +5 -468
  992. package/scripts/gds/provision.js +5 -1477
  993. package/scripts/gds/publish-credential-check.js +6 -65
  994. package/scripts/gds/publish-integration-gate.js +5 -140
  995. package/scripts/gds/publish-manifest.js +5 -437
  996. package/scripts/gds/publish-watch.js +5 -266
  997. package/scripts/gds/pulse.js +6 -335
  998. package/scripts/gds/push-main.js +5 -54
  999. package/scripts/gds/push-path-brief.js +5 -98
  1000. package/scripts/gds/read-session-export.js +5 -357
  1001. package/scripts/gds/reauth.js +6 -154
  1002. package/scripts/gds/recall.js +6 -182
  1003. package/scripts/gds/redteam-patrol.js +5 -435
  1004. package/scripts/gds/regen-instance-docs.js +5 -45
  1005. package/scripts/gds/release-core.js +5 -78
  1006. package/scripts/gds/release-notes.js +5 -270
  1007. package/scripts/gds/release.js +6 -138
  1008. package/scripts/gds/rename-goals.js +5 -107
  1009. package/scripts/gds/rename-history-check.js +5 -367
  1010. package/scripts/gds/rename-ledger-prose.js +5 -480
  1011. package/scripts/gds/render-api.js +5 -196
  1012. package/scripts/gds/render-check.js +5 -204
  1013. package/scripts/gds/render-ideas.js +6 -225
  1014. package/scripts/gds/render-payload.js +5 -84
  1015. package/scripts/gds/repo-metrics.js +6 -362
  1016. package/scripts/gds/review-sheet.js +5 -106
  1017. package/scripts/gds/role-pack-guard.js +5 -141
  1018. package/scripts/gds/route-shadow-guard.js +5 -173
  1019. package/scripts/gds/routine-schedule.js +5 -281
  1020. package/scripts/gds/run-routine.js +5 -255
  1021. package/scripts/gds/run-unit-tests.js +6 -659
  1022. package/scripts/gds/runner-drift.js +5 -149
  1023. package/scripts/gds/sandbox-stage.js +6 -458
  1024. package/scripts/gds/scope-map-guard.js +5 -299
  1025. package/scripts/gds/scope-roster-guard.js +5 -117
  1026. package/scripts/gds/seam-wiring-guard.js +5 -274
  1027. package/scripts/gds/search-ingest-db.js +6 -287
  1028. package/scripts/gds/search-ingest-md.js +6 -268
  1029. package/scripts/gds/seed-adopt-tasks.js +6 -74
  1030. package/scripts/gds/seed-api-contract-goal-tasks.js +6 -140
  1031. package/scripts/gds/seed-board-room-tasks.js +6 -196
  1032. package/scripts/gds/seed-bongos-app-tasks.js +6 -293
  1033. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +6 -80
  1034. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +6 -99
  1035. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +6 -306
  1036. package/scripts/gds/seed-bongos-module-system-tasks.js +6 -345
  1037. package/scripts/gds/seed-bongos-tasks.js +6 -213
  1038. package/scripts/gds/seed-bongos-v1-idea-routing-tasks.js +6 -152
  1039. package/scripts/gds/seed-bongos-v1-seo-tasks.js +6 -104
  1040. package/scripts/gds/seed-bv1-community-tasks.js +6 -131
  1041. package/scripts/gds/seed-bv1-privacy-invites-tasks.js +6 -133
  1042. package/scripts/gds/seed-bv1-profile-page-tasks.js +6 -161
  1043. package/scripts/gds/seed-bv1-profiles-tasks.js +6 -135
  1044. package/scripts/gds/seed-bv1-r01-delta-tasks.js +6 -154
  1045. package/scripts/gds/seed-bv2-ideator-surface-tasks.js +6 -390
  1046. package/scripts/gds/seed-bv2-tweak-mode-tasks.js +6 -277
  1047. package/scripts/gds/seed-gds-v4-tasks.js +6 -623
  1048. package/scripts/gds/seed-governance-tasks.js +6 -339
  1049. package/scripts/gds/seed-medusa-tasks.js +6 -439
  1050. package/scripts/gds/seed-module-upstreaming.js +5 -217
  1051. package/scripts/gds/seed-productization-tasks.js +6 -234
  1052. package/scripts/gds/seed-project-admin-console-tasks.js +6 -88
  1053. package/scripts/gds/seed-provisioning-tasks.js +6 -82
  1054. package/scripts/gds/seed-staging.sh +7 -116
  1055. package/scripts/gds/seed-strict-versioning-tasks.js +6 -274
  1056. package/scripts/gds/seed-v2-world-tasks.js +6 -282
  1057. package/scripts/gds/seed-verify-criteria.js +6 -124
  1058. package/scripts/gds/sequence.js +6 -596
  1059. package/scripts/gds/session-cost.js +6 -429
  1060. package/scripts/gds/session-digest-build.js +6 -293
  1061. package/scripts/gds/session-digest.js +6 -199
  1062. package/scripts/gds/session-eval.js +6 -630
  1063. package/scripts/gds/session-transcript-build.js +6 -155
  1064. package/scripts/gds/session-transcript-upload.js +6 -29
  1065. package/scripts/gds/session.js +6 -403
  1066. package/scripts/gds/setup.js +6 -645
  1067. package/scripts/gds/ship-check.js +5 -85
  1068. package/scripts/gds/ship-deploy-target.js +5 -392
  1069. package/scripts/gds/ship-escalation.js +5 -166
  1070. package/scripts/gds/ship-finish.js +5 -419
  1071. package/scripts/gds/ship-flow.js +5 -1216
  1072. package/scripts/gds/ship-git.js +5 -99
  1073. package/scripts/gds/ship-grade-steps.js +5 -546
  1074. package/scripts/gds/ship-grade.js +5 -425
  1075. package/scripts/gds/ship-honesty.js +5 -312
  1076. package/scripts/gds/ship-io.js +5 -138
  1077. package/scripts/gds/ship-land.js +5 -1129
  1078. package/scripts/gds/ship-memory-sync.js +5 -248
  1079. package/scripts/gds/ship-merge-gate.js +5 -224
  1080. package/scripts/gds/ship-merge.js +5 -465
  1081. package/scripts/gds/ship-mode-ask.js +5 -137
  1082. package/scripts/gds/ship-mode-manual.js +5 -53
  1083. package/scripts/gds/ship-preflight-steps.js +5 -398
  1084. package/scripts/gds/ship-regen.js +5 -313
  1085. package/scripts/gds/ship-resume.js +5 -200
  1086. package/scripts/gds/ship-session-upload.js +5 -312
  1087. package/scripts/gds/ship-state.js +5 -109
  1088. package/scripts/gds/ship-surprise.js +5 -83
  1089. package/scripts/gds/ship-visual.js +5 -74
  1090. package/scripts/gds/ship.js +5 -380
  1091. package/scripts/gds/shipping-mode.js +5 -69
  1092. package/scripts/gds/skill-lint.js +5 -248
  1093. package/scripts/gds/skill-preflight.js +5 -359
  1094. package/scripts/gds/smoke-batch-claim.sh +7 -237
  1095. package/scripts/gds/smoke-batch-release.sh +7 -315
  1096. package/scripts/gds/smoke-claim-consistency.sh +7 -221
  1097. package/scripts/gds/smoke-dependencies.sh +7 -142
  1098. package/scripts/gds/smoke-gds.js +6 -255
  1099. package/scripts/gds/smoke-write.sh +7 -274
  1100. package/scripts/gds/source-text-test-scan.js +7 -0
  1101. package/scripts/gds/spark.js +6 -293
  1102. package/scripts/gds/stale-worktrees.js +5 -210
  1103. package/scripts/gds/start-goals.js +5 -101
  1104. package/scripts/gds/start.js +6 -1089
  1105. package/scripts/gds/status.js +6 -544
  1106. package/scripts/gds/strand-watch.js +5 -313
  1107. package/scripts/gds/stranded-rows.js +5 -198
  1108. package/scripts/gds/stray-unit-sweep.sh +7 -70
  1109. package/scripts/gds/surface.js +5 -100
  1110. package/scripts/gds/task.js +6 -272
  1111. package/scripts/gds/test-path-guard.js +5 -97
  1112. package/scripts/gds/triage.js +6 -741
  1113. package/scripts/gds/turn-end-sound.js +5 -72
  1114. package/scripts/gds/tweak-halt.js +5 -68
  1115. package/scripts/gds/tweak-renders.js +5 -198
  1116. package/scripts/gds/uat.js +6 -119
  1117. package/scripts/gds/ui-kit-transform.js +5 -41
  1118. package/scripts/gds/update-channel.js +5 -510
  1119. package/scripts/gds/update-sweep.js +5 -827
  1120. package/scripts/gds/upgrade-artist-gate.js +5 -45
  1121. package/scripts/gds/upgrade-commit-identity.js +5 -31
  1122. package/scripts/gds/upgrade-migrate.js +5 -223
  1123. package/scripts/gds/upgrade-operator.js +6 -73
  1124. package/scripts/gds/upgrade-outcome.js +5 -173
  1125. package/scripts/gds/upgrade.js +5 -1497
  1126. package/scripts/gds/validate-design.js +5 -10
  1127. package/scripts/gds/version-close.js +6 -620
  1128. package/scripts/gds/version-literal-guard.js +5 -138
  1129. package/scripts/gds/version-select.js +5 -77
  1130. package/scripts/gds/visual-review-nudge.js +5 -38
  1131. package/scripts/gds/wedge-remedy.js +5 -173
  1132. package/scripts/gds/worktree-claim-guard.js +5 -129
  1133. package/scripts/gds/worktree.js +6 -448
  1134. package/scripts/hall-preview/refresh-fixtures.js +1 -1
  1135. package/scripts/hall-preview/server.js +2 -2
  1136. package/scripts/migrate.sh +3 -3
  1137. package/scripts/public-mirror-export.js +3 -3
  1138. package/scripts/setup-builder.js +7 -7
  1139. package/src/bongos/api-errors.js +1 -0
  1140. package/src/bongos/api-prefix.js +1 -1
  1141. package/src/bongos/auth-github.js +19 -3
  1142. package/src/bongos/auth-idp.js +7 -0
  1143. package/src/bongos/claim-attribution.js +2 -2
  1144. package/src/bongos/core-moves.js +1 -1
  1145. package/src/bongos/core-update.js +3 -3
  1146. package/src/bongos/craft-mode.js +2 -2
  1147. package/src/bongos/db-kernel.js +15 -3
  1148. package/src/bongos/db.js +30 -4
  1149. package/src/bongos/github-repos.js +1 -1
  1150. package/src/bongos/llm-cache.js +1 -1
  1151. package/src/bongos/llm-pricing.js +1 -1
  1152. package/src/bongos/metrics.js +1 -1
  1153. package/src/bongos/middleware/rate-limit.js +2 -2
  1154. package/src/bongos/module-listing.js +93 -1
  1155. package/src/bongos/module-scope-map.js +90 -85
  1156. package/src/bongos/module-store.js +1 -1
  1157. package/src/bongos/module-submissions.js +1 -1
  1158. package/src/bongos/optimizer.js +1 -1
  1159. package/src/bongos/package-registry.js +1 -1
  1160. package/src/bongos/path-match.js +1 -1
  1161. package/src/bongos/permission-path-check.js +3 -3
  1162. package/src/bongos/platform-visibility-gate.js +3 -5
  1163. package/src/bongos/prelaunch-gate.js +7 -6
  1164. package/src/bongos/route-rank-check.js +2 -2
  1165. package/src/bongos/routes/auth.js +15 -2
  1166. package/src/bongos/routes/backup.js +1 -1
  1167. package/src/bongos/routes/builders.js +29 -1
  1168. package/src/bongos/routes/me.js +49 -18
  1169. package/src/bongos/routes/modules.js +29 -9
  1170. package/src/bongos/routes/public.js +3 -72
  1171. package/src/bongos/schema-lag.js +1 -1
  1172. package/src/bongos/sensitive-surfaces.js +1 -1
  1173. package/src/bongos/serve-internal.js +65 -16
  1174. package/src/bongos/software-update.js +2 -2
  1175. package/src/bongos/upgrade-hold.js +3 -3
  1176. package/src/hall-look.js +6 -5
  1177. package/src/module-api.js +3 -3
  1178. package/src/module-loader/catalog.js +1 -1
  1179. package/src/module-loader/error-tally.js +3 -3
  1180. package/src/module-loader/manifest-schema.js +3 -3
  1181. package/src/platform-server.js +10 -0
  1182. package/src/role-responsibilities.js +1 -1
  1183. package/src/stale-timer.js +2 -2
  1184. package/tests/accessibility_replay.mjs +1 -1
  1185. package/tests/activity_rollup_order_db.mjs +1 -1
  1186. package/tests/activity_snapshots_db.mjs +1 -1
  1187. package/tests/adopt_detect.mjs +1 -1
  1188. package/tests/adopt_import.mjs +1 -1
  1189. package/tests/adopt_preflight.mjs +1 -1
  1190. package/tests/adr_0089_scope.mjs +10 -7
  1191. package/tests/adr_0162_citation.mjs +1 -1
  1192. package/tests/adr_0162_gate_citation.mjs +1 -1
  1193. package/tests/agent_invoke.mjs +1 -1
  1194. package/tests/agent_invoke_live.mjs +3 -3
  1195. package/tests/agents_cron_trigger.mjs +2 -2
  1196. package/tests/agents_roster.mjs +1 -1
  1197. package/tests/agents_sync.mjs +4 -4
  1198. package/tests/allow_rule_guard.mjs +20 -20
  1199. package/tests/api_alias_caller_ratchet.mjs +9 -10
  1200. package/tests/api_alias_exceptions.mjs +7 -6
  1201. package/tests/api_artifacts.mjs +214 -0
  1202. package/tests/api_cli_flags.mjs +3 -3
  1203. package/tests/api_client.mjs +56 -54
  1204. package/tests/api_docs.mjs +30 -9
  1205. package/tests/api_error_envelope_buildcheck.mjs +1 -1
  1206. package/tests/api_msys_path_repair.mjs +2 -2
  1207. package/tests/architect.mjs +1 -1
  1208. package/tests/art_stage.mjs +2 -2
  1209. package/tests/artifact_audit.mjs +2 -2
  1210. package/tests/artifact_staleness.mjs +9 -9
  1211. package/tests/atlas.mjs +1 -1
  1212. package/tests/audit_deps.mjs +1 -1
  1213. package/tests/audit_gate.mjs +1 -1
  1214. package/tests/auth_flow_slice1.mjs +3 -3
  1215. package/tests/auth_inactive_builder.mjs +43 -5
  1216. package/tests/auth_session_expiry_db.mjs +16 -4
  1217. package/tests/auth_session_ttl.mjs +23 -0
  1218. package/tests/authorship_audit.mjs +2 -2
  1219. package/tests/autobongos_cadence.mjs +1 -1
  1220. package/tests/autobongos_fence.mjs +1 -1
  1221. package/tests/autobongos_grade_cap.mjs +2 -2
  1222. package/tests/autobongos_heartbeat_head.mjs +1 -1
  1223. package/tests/autobongos_host_access.mjs +3 -3
  1224. package/tests/autobongos_loop.mjs +17 -17
  1225. package/tests/autobongos_service_ps1.mjs +3 -3
  1226. package/tests/autobongos_tweak_lane.mjs +2 -2
  1227. package/tests/autobongos_verify.mjs +2 -2
  1228. package/tests/autonomous_fit_protected_paths.mjs +3 -3
  1229. package/tests/autonomy_config_idle.mjs +1 -1
  1230. package/tests/autonomy_digest.mjs +1 -1
  1231. package/tests/autonomy_gate.mjs +1 -1
  1232. package/tests/autonomy_gauge.mjs +2 -2
  1233. package/tests/autonomy_runner_identity.mjs +1 -1
  1234. package/tests/backfill_sessions.mjs +8 -8
  1235. package/tests/backfill_subagent_rewards.mjs +1 -1
  1236. package/tests/backfill_task_rewards.mjs +2 -2
  1237. package/tests/backlog_review.mjs +3 -3
  1238. package/tests/baseline_staleness.mjs +2 -2
  1239. package/tests/bfg.mjs +11 -5
  1240. package/tests/bfg_write.mjs +20 -11
  1241. package/tests/blockers_hall.mjs +17 -5
  1242. package/tests/blockers_page_ui.mjs +56 -12
  1243. package/tests/bongos_dispatch.mjs +5 -5
  1244. package/tests/bongos_login.mjs +2 -2
  1245. package/tests/bug_attachment_audit.mjs +1 -1
  1246. package/tests/bug_attachment_recover.mjs +2 -2
  1247. package/tests/bug_triage.mjs +3 -3
  1248. package/tests/build_info.mjs +1 -1
  1249. package/tests/builder_tester_tag.mjs +184 -0
  1250. package/tests/bump_version.mjs +3 -3
  1251. package/tests/canonical_profile_url.mjs +1 -1
  1252. package/tests/capture_error_format.mjs +1 -1
  1253. package/tests/capture_goal_routing.mjs +2 -2
  1254. package/tests/category_advisory_guard.mjs +3 -3
  1255. package/tests/claim_error_surface.mjs +2 -2
  1256. package/tests/claim_from_task_and_home.mjs +1 -1
  1257. package/tests/claim_gate_open_blocker.mjs +7 -4
  1258. package/tests/claim_gate_rebase.mjs +12 -8
  1259. package/tests/claim_recall.mjs +4 -4
  1260. package/tests/claim_resolve_worktree_lock.mjs +1 -1
  1261. package/tests/claude_materialize.mjs +58 -58
  1262. package/tests/clawback_confirmed_backlog.mjs +8 -5
  1263. package/tests/cli_allowlist_permissions.mjs +11 -11
  1264. package/tests/cli_dispatcher.mjs +2 -2
  1265. package/tests/cli_err_code.mjs +6 -6
  1266. package/tests/cli_exit_no_abort.mjs +7 -7
  1267. package/tests/cli_lib_formatters.mjs +2 -2
  1268. package/tests/cli_sessions.mjs +5 -5
  1269. package/tests/cli_surface.mjs +15 -15
  1270. package/tests/cli_token_reissue.mjs +2 -2
  1271. package/tests/client_baseurl_guard.mjs +1 -1
  1272. package/tests/client_bundle_route.mjs +35 -4
  1273. package/tests/cloud_bongos_pack.mjs +1 -1
  1274. package/tests/community_leaderboard_db.mjs +1 -1
  1275. package/tests/conductor.mjs +18 -18
  1276. package/tests/conflict_resolve.mjs +14 -16
  1277. package/tests/consumer_layout_boot.mjs +12 -12
  1278. package/tests/context_pack.mjs +6 -6
  1279. package/tests/control_manifest.mjs +4 -4
  1280. package/tests/copy_desk_page_reads.mjs +1 -1
  1281. package/tests/copy_desk_page_release.mjs +192 -0
  1282. package/tests/copy_inventory.mjs +2 -2
  1283. package/tests/core_auto_upgrade.mjs +1 -1
  1284. package/tests/core_move_notice.mjs +2 -2
  1285. package/tests/core_origin_follow.mjs +7 -7
  1286. package/tests/core_pin_sync.mjs +3 -3
  1287. package/tests/core_upgrade_door.mjs +2 -2
  1288. package/tests/core_upgrade_owner_door.mjs +34 -1
  1289. package/tests/core_upgrade_runner.mjs +19 -19
  1290. package/tests/credential_presence.mjs +2 -2
  1291. package/tests/credit_grant.mjs +3 -3
  1292. package/tests/credit_log_single_writer.mjs +5 -5
  1293. package/tests/criterion_ref_status.mjs +2 -2
  1294. package/tests/cross_discipline_priority_direction.mjs +3 -3
  1295. package/tests/cutover_codemod.mjs +2 -4
  1296. package/tests/db_backup_nightly.mjs +1 -1
  1297. package/tests/db_backup_offsite.mjs +1 -1
  1298. package/tests/db_ownership_handover.mjs +2 -2
  1299. package/tests/dead_deps.mjs +3 -3
  1300. package/tests/dependency_advisory.mjs +1 -1
  1301. package/tests/deploy_audit_gate.mjs +4 -4
  1302. package/tests/deploy_divergence_line.mjs +36 -16
  1303. package/tests/deploy_page_projects.mjs +35 -4
  1304. package/tests/dev_lib.mjs +2 -2
  1305. package/tests/dev_windows.mjs +2 -2
  1306. package/tests/diagram_facts_offset.mjs +1 -1
  1307. package/tests/diagram_repo_slug.mjs +1 -1
  1308. package/tests/diff_derived_signals.mjs +2 -2
  1309. package/tests/dns_preflight.mjs +2 -2
  1310. package/tests/do_api.mjs +3 -3
  1311. package/tests/doc_cli_guard.mjs +28 -28
  1312. package/tests/doc_comment_coverage.mjs +1 -1
  1313. package/tests/doc_control_claims.mjs +11 -11
  1314. package/tests/docs_entropy.mjs +2 -2
  1315. package/tests/docs_openapi_route.mjs +8 -6
  1316. package/tests/doctor_hooks.mjs +1 -1
  1317. package/tests/edit_hints.mjs +3 -2
  1318. package/tests/effective_visibility_predicate.mjs +3 -3
  1319. package/tests/env_knobs_neutral_prefix.mjs +13 -13
  1320. package/tests/exec_path_guard.mjs +4 -4
  1321. package/tests/executed_closure.mjs +18 -12
  1322. package/tests/file_map.mjs +1 -1
  1323. package/tests/find_untested.mjs +13 -13
  1324. package/tests/first_admin_bootstrap.mjs +1 -1
  1325. package/tests/fitness.mjs +16 -16
  1326. package/tests/fitness_gds_ratchet.mjs +2 -2
  1327. package/tests/fitness_installed_core.mjs +3 -3
  1328. package/tests/fitness_no_raw_nul.mjs +1 -1
  1329. package/tests/fitness_ratchets.mjs +3 -3
  1330. package/tests/fitness_scope_roster.mjs +2 -2
  1331. package/tests/fitness_two_root.mjs +8 -8
  1332. package/tests/fixtures/accessibility-replay.json +5 -5
  1333. package/tests/fixtures/grade-replay/recorded-panel-grades.json +1 -1
  1334. package/tests/fixtures/ideator-prefold/README.md +1 -1
  1335. package/tests/fixtures/page-ledger.mjs +22 -0
  1336. package/tests/fixtures/session-506-digest.json +5 -5
  1337. package/tests/gate_approvals.mjs +50 -0
  1338. package/tests/gate_review.mjs +8 -8
  1339. package/tests/gating_review_retired.mjs +2 -2
  1340. package/tests/gen_freshness.mjs +3 -3
  1341. package/tests/git_guard.mjs +3 -3
  1342. package/tests/git_merge_regen.mjs +41 -65
  1343. package/tests/github_one_trip.mjs +4 -4
  1344. package/tests/github_pick_up.mjs +2 -2
  1345. package/tests/github_push_merge_driver.mjs +1 -1
  1346. package/tests/go_live.mjs +3 -2
  1347. package/tests/goal_category.mjs +1 -1
  1348. package/tests/goal_cli.mjs +2 -2
  1349. package/tests/goal_create_spec_entry.mjs +1 -1
  1350. package/tests/goal_invite_consent.mjs +3 -1
  1351. package/tests/goal_move.mjs +1 -1
  1352. package/tests/goal_names.mjs +2 -2
  1353. package/tests/goal_working_area.mjs +1 -1
  1354. package/tests/government_agent_asks.mjs +7 -7
  1355. package/tests/government_board_room_copy.mjs +6 -1
  1356. package/tests/government_board_view.mjs +39 -0
  1357. package/tests/government_board_vote_ui.mjs +39 -1
  1358. package/tests/government_config.mjs +2 -2
  1359. package/tests/government_live_proof_shape.mjs +1 -1
  1360. package/tests/government_protected_surfaces.mjs +54 -53
  1361. package/tests/government_require_permission.mjs +9 -1
  1362. package/tests/government_vanilla_boot.mjs +1 -1
  1363. package/tests/government_vocabulary.mjs +2 -2
  1364. package/tests/government_walk.mjs +2 -2
  1365. package/tests/grade_body_limit.mjs +6 -4
  1366. package/tests/grade_correlation_audit.mjs +3 -3
  1367. package/tests/grade_diff_hash.mjs +1 -1
  1368. package/tests/grade_engine_replay.mjs +2 -2
  1369. package/tests/grade_server_authoritative.mjs +1 -1
  1370. package/tests/grade_unavailable_display.mjs +1 -1
  1371. package/tests/grader.mjs +8 -24
  1372. package/tests/grader_generated_provenance.mjs +14 -14
  1373. package/tests/grader_no_artifact.mjs +1 -1
  1374. package/tests/grader_prompt_fencing.mjs +1 -1
  1375. package/tests/grader_quality_window_overflow.mjs +1 -1
  1376. package/tests/grader_reader_lens.mjs +3 -3
  1377. package/tests/grader_regrade_delta.mjs +1 -1
  1378. package/tests/grader_unbacked_score.mjs +2 -2
  1379. package/tests/hall_acclaim_vote_control.mjs +113 -0
  1380. package/tests/hall_asset_cache.mjs +127 -0
  1381. package/tests/hall_audit.mjs +63 -0
  1382. package/tests/hall_board_world.mjs +20 -0
  1383. package/tests/hall_city_card_words.mjs +61 -0
  1384. package/tests/hall_client_request_shape.mjs +5 -1
  1385. package/tests/hall_home_ships_bounded.mjs +160 -0
  1386. package/tests/hall_landing_boot.mjs +15 -2
  1387. package/tests/hall_nav.mjs +33 -0
  1388. package/tests/hall_onboarding_bongos_setup.mjs +1 -1
  1389. package/tests/hall_oversight_world.mjs +44 -4
  1390. package/tests/hall_palette.mjs +12 -9
  1391. package/tests/hall_preview_security.mjs +1 -1
  1392. package/tests/hall_profile_world.mjs +17 -0
  1393. package/tests/hall_reading_world.mjs +16 -1
  1394. package/tests/hall_roster_world.mjs +2 -1
  1395. package/tests/hall_studio_world.mjs +4 -1
  1396. package/tests/hall_work_history_id.mjs +39 -0
  1397. package/tests/held_tweak_reporting.mjs +4 -4
  1398. package/tests/helpers.mjs +3 -3
  1399. package/tests/home_attention_cards.mjs +2 -0
  1400. package/tests/home_bounded_reads.mjs +1 -1
  1401. package/tests/home_isolation_guard.mjs +1 -1
  1402. package/tests/hook_core_resolve.mjs +7 -7
  1403. package/tests/hook_user_agents.mjs +1 -1
  1404. package/tests/hooks_drain.mjs +2 -2
  1405. package/tests/host_topology_skips.mjs +1 -1
  1406. package/tests/howto_guide.mjs +1 -1
  1407. package/tests/howto_moments.mjs +3 -3
  1408. package/tests/hub_account_page.mjs +1 -1
  1409. package/tests/idea_capture_grades.mjs +2 -2
  1410. package/tests/idea_develop_spark.mjs +1 -1
  1411. package/tests/idea_filed_via.mjs +2 -2
  1412. package/tests/idea_ideate_full.mjs +1 -1
  1413. package/tests/idea_spark_mark.mjs +1 -1
  1414. package/tests/idea_spark_queue.mjs +1 -1
  1415. package/tests/idea_triage.mjs +1 -1
  1416. package/tests/idea_triage_grade.mjs +3 -3
  1417. package/tests/idea_vote_permission.mjs +113 -0
  1418. package/tests/idea_votes_fold_db.mjs +123 -0
  1419. package/tests/infra_exec_paths.mjs +12 -12
  1420. package/tests/init.mjs +2 -2
  1421. package/tests/instance_db_migrated_on_code_move.mjs +5 -5
  1422. package/tests/instance_feedback.mjs +9 -9
  1423. package/tests/instance_mismatch_guard.mjs +2 -2
  1424. package/tests/integration_parked_ratchet.mjs +24 -2
  1425. package/tests/intent_retry.mjs +1 -1
  1426. package/tests/interaction_posture.mjs +3 -3
  1427. package/tests/invite_expiry_db.mjs +1 -1
  1428. package/tests/joinability_invite_only.mjs +1 -1
  1429. package/tests/karma_vote_lists.mjs +270 -0
  1430. package/tests/key-card.mjs +2 -2
  1431. package/tests/key-status.mjs +2 -2
  1432. package/tests/knip_ratchet_ambient.mjs +2 -2
  1433. package/tests/known_failing_ratchet.mjs +1 -1
  1434. package/tests/land_watch.mjs +2 -2
  1435. package/tests/landing_legal_pages.mjs +1 -1
  1436. package/tests/landing_page.mjs +2 -2
  1437. package/tests/leaderboard_roles.mjs +4 -1
  1438. package/tests/leak_scan_allowlist.mjs +8 -8
  1439. package/tests/leak_scan_fail_closed.mjs +1 -1
  1440. package/tests/lib_sh_resolution.mjs +9 -9
  1441. package/tests/lifecycle-card.mjs +7 -7
  1442. package/tests/linkify_check.mjs +2 -2
  1443. package/tests/linkify_refs.mjs +1 -1
  1444. package/tests/llm-cache-route.mjs +1 -1
  1445. package/tests/local_preview.mjs +2 -2
  1446. package/tests/main_audit.mjs +3 -3
  1447. package/tests/main_audit_attestation.mjs +1 -1
  1448. package/tests/main_audit_db_roster.mjs +2 -2
  1449. package/tests/main_worktree_busy_reason.mjs +3 -3
  1450. package/tests/markdown_line_endings.mjs +2 -2
  1451. package/tests/me_streak_leaderboard_queries.mjs +193 -0
  1452. package/tests/membership_kind_lockstep.mjs +1 -1
  1453. package/tests/memory_isolation.mjs +16 -8
  1454. package/tests/memory_map.mjs +2 -2
  1455. package/tests/memory_pull.mjs +33 -25
  1456. package/tests/merge_driver_register.mjs +3 -3
  1457. package/tests/migration_allocation.mjs +2 -2
  1458. package/tests/migration_namespace.mjs +1 -1
  1459. package/tests/migrations_forward_safe.mjs +1 -1
  1460. package/tests/mingle.mjs +1 -1
  1461. package/tests/mirror_lineage_fulltree.mjs +3 -3
  1462. package/tests/mirror_lineage_proof.mjs +2 -2
  1463. package/tests/mirror_redact.mjs +4 -4
  1464. package/tests/missing_dep_classify.mjs +3 -3
  1465. package/tests/module-scope-map.mjs +22 -22
  1466. package/tests/module_api_lazy.mjs +1 -1
  1467. package/tests/module_assess_docs.mjs +2 -2
  1468. package/tests/module_assess_installs.mjs +3 -3
  1469. package/tests/module_assess_price_parity.mjs +5 -5
  1470. package/tests/module_assess_score.mjs +5 -5
  1471. package/tests/module_assess_security.mjs +4 -4
  1472. package/tests/module_assess_tests.mjs +3 -3
  1473. package/tests/module_assessments_migration.mjs +1 -1
  1474. package/tests/module_catalog.mjs +2 -2
  1475. package/tests/module_cli.mjs +3 -3
  1476. package/tests/module_entitlements.mjs +1 -1
  1477. package/tests/module_error_counts.mjs +1 -1
  1478. package/tests/module_install.mjs +4 -4
  1479. package/tests/module_loader.mjs +3 -1
  1480. package/tests/module_owned_tests.mjs +1 -1
  1481. package/tests/module_release_channels.mjs +1 -1
  1482. package/tests/module_store_howto.mjs +3 -3
  1483. package/tests/module_store_listing.mjs +139 -2
  1484. package/tests/module_store_publish.mjs +4 -4
  1485. package/tests/module_store_publish_route.mjs +1 -1
  1486. package/tests/module_store_reassess.mjs +1 -1
  1487. package/tests/module_store_registry_migration.mjs +1 -1
  1488. package/tests/module_test_runner.mjs +3 -3
  1489. package/tests/module_update.mjs +4 -4
  1490. package/tests/module_upgrade_updates.mjs +1 -1
  1491. package/tests/move_escalation.mjs +2 -2
  1492. package/tests/nav_permission_atoms.mjs +3 -2
  1493. package/tests/needs_rebase.mjs +7 -3
  1494. package/tests/newcomer_floor.mjs +1 -1
  1495. package/tests/newcomer_generator.mjs +48 -0
  1496. package/tests/next_number.mjs +1 -1
  1497. package/tests/no_artifact_escalation.mjs +3 -3
  1498. package/tests/npm_release_where.mjs +1 -1
  1499. package/tests/oauth_secret.mjs +2 -2
  1500. package/tests/onboard.mjs +6 -6
  1501. package/tests/onboarding_gate.mjs +2 -2
  1502. package/tests/opt_in_skill_modules.mjs +3 -3
  1503. package/tests/own_scope_guard.mjs +1 -1
  1504. package/tests/own_session_revoke.mjs +4 -1
  1505. package/tests/package_core.mjs +10 -11
  1506. package/tests/page_inventory.mjs +5 -5
  1507. package/tests/page_reader.mjs +7 -7
  1508. package/tests/page_tweak_hold.mjs +6 -6
  1509. package/tests/parallel-load.mjs +1 -1
  1510. package/tests/paste_token_api_base.mjs +1 -1
  1511. package/tests/paste_token_session_store.mjs +2 -2
  1512. package/tests/pending_invite_purge_db.mjs +1 -1
  1513. package/tests/permission_path.mjs +1 -1
  1514. package/tests/pin_replay.mjs +1 -1
  1515. package/tests/pin_write_key.mjs +7 -7
  1516. package/tests/plain_cards.mjs +15 -15
  1517. package/tests/pr_assign.mjs +1 -1
  1518. package/tests/pre_push_hook.mjs +3 -3
  1519. package/tests/preflight_checks.mjs +2 -2
  1520. package/tests/prelaunch_gate.mjs +1 -1
  1521. package/tests/privacy_matrix.mjs +1 -1
  1522. package/tests/probe_cache.mjs +6 -6
  1523. package/tests/profile_connections_ui.mjs +4 -3
  1524. package/tests/profile_fields.mjs +11 -1
  1525. package/tests/profile_privacy_owner_view.mjs +1 -1
  1526. package/tests/profile_role_headline.mjs +10 -9
  1527. package/tests/project_admin_console_model.mjs +1 -1
  1528. package/tests/projects_hub.mjs +1 -1
  1529. package/tests/projects_hub_cloud_hop.mjs +1 -1
  1530. package/tests/promote_goal_id.mjs +6 -6
  1531. package/tests/promotion_sweep.mjs +1 -1
  1532. package/tests/provision.mjs +24 -24
  1533. package/tests/provision_account_identity.mjs +2 -2
  1534. package/tests/provision_byo_host.mjs +1 -1
  1535. package/tests/provision_caddy_wiring.mjs +2 -2
  1536. package/tests/provision_disconnect.mjs +2 -2
  1537. package/tests/provision_dns_first.mjs +1 -1
  1538. package/tests/provision_render.mjs +9 -9
  1539. package/tests/provision_repo_private.mjs +3 -3
  1540. package/tests/provision_resource_caps.mjs +5 -5
  1541. package/tests/provision_restart.mjs +3 -3
  1542. package/tests/provision_settings_apply.mjs +7 -7
  1543. package/tests/provision_teardown_address.mjs +2 -2
  1544. package/tests/provisioning_capacity.mjs +5 -5
  1545. package/tests/provisioning_credential_preflight.mjs +1 -1
  1546. package/tests/provisioning_disconnect.mjs +1 -1
  1547. package/tests/provisioning_error_note_scope.mjs +4 -4
  1548. package/tests/provisioning_paid_shape_gate.mjs +2 -2
  1549. package/tests/provisioning_planet_physics.mjs +16 -0
  1550. package/tests/provisioning_runner_drift_notice.mjs +2 -2
  1551. package/tests/provisioning_settings_env.mjs +1 -1
  1552. package/tests/pruned_lockfile_integrity.mjs +1 -1
  1553. package/tests/public_mirror_export.mjs +1 -1
  1554. package/tests/publish_integration_gate.mjs +2 -2
  1555. package/tests/publish_manifest.mjs +6 -6
  1556. package/tests/publish_watch.mjs +1 -1
  1557. package/tests/push_path_brief.mjs +2 -2
  1558. package/tests/raise.mjs +248 -0
  1559. package/tests/rank_roles_audit.mjs +1 -1
  1560. package/tests/rank_tier_single_source.mjs +2 -2
  1561. package/tests/rate_limit_public.mjs +1 -1
  1562. package/tests/read_default_meter.mjs +2 -2
  1563. package/tests/read_session_export.mjs +1 -1
  1564. package/tests/rebase_gate_set_aside.mjs +1 -1
  1565. package/tests/recall_cli.mjs +1 -1
  1566. package/tests/recall_corpus_health.mjs +3 -2
  1567. package/tests/recall_hints.mjs +1 -1
  1568. package/tests/recruiter_sliver_boundary.mjs +1 -1
  1569. package/tests/redteam_patrol.mjs +2 -2
  1570. package/tests/regrade_actual_minutes.mjs +2 -2
  1571. package/tests/regrade_eligibility.mjs +2 -2
  1572. package/tests/release_core.mjs +2 -2
  1573. package/tests/release_notes.mjs +4 -4
  1574. package/tests/rename_history_restraint.mjs +3 -3
  1575. package/tests/rename_ledger_prose.mjs +6 -6
  1576. package/tests/render_api.mjs +1 -1
  1577. package/tests/render_check.mjs +4 -4
  1578. package/tests/render_deploy.mjs +1 -1
  1579. package/tests/repo_info_binding.mjs +1 -1
  1580. package/tests/repo_map.mjs +5 -5
  1581. package/tests/reward_mode_cost_plus_only.mjs +7 -3
  1582. package/tests/reward_mode_surfacing.mjs +1 -1
  1583. package/tests/role_responsibilities.mjs +1 -1
  1584. package/tests/rot_inbox.mjs +10 -7
  1585. package/tests/route_permission_check.mjs +1 -1
  1586. package/tests/route_shadow_guard.mjs +1 -1
  1587. package/tests/route_validation.mjs +1 -1
  1588. package/tests/routine_capture_kind.mjs +6 -6
  1589. package/tests/routine_schedule.mjs +9 -9
  1590. package/tests/run_routine.mjs +5 -5
  1591. package/tests/run_routine_two_root.mjs +5 -5
  1592. package/tests/runner_drift.mjs +17 -17
  1593. package/tests/sandbox_stage.mjs +5 -5
  1594. package/tests/scope_map_guard.mjs +7 -7
  1595. package/tests/scouting_owner_access_and_reach.mjs +1 -1
  1596. package/tests/scripts_gds_forwarders.mjs +224 -0
  1597. package/tests/scrubber_corpus.mjs +2 -2
  1598. package/tests/seam_wiring_guard.mjs +1 -1
  1599. package/tests/search_ingest.mjs +2 -2
  1600. package/tests/search_ingest_db.mjs +1 -1
  1601. package/tests/search_ingest_nul.mjs +6 -6
  1602. package/tests/seed_verify_criteria.mjs +3 -3
  1603. package/tests/sequence.mjs +3 -3
  1604. package/tests/served_paths_shipped.mjs +3 -3
  1605. package/tests/session_506_regression.mjs +1 -1
  1606. package/tests/session_accessibility.mjs +1 -1
  1607. package/tests/session_caps.mjs +1 -1
  1608. package/tests/session_cost.mjs +1 -1
  1609. package/tests/session_digest.mjs +2 -2
  1610. package/tests/session_eval.mjs +6 -6
  1611. package/tests/session_index.mjs +1 -1
  1612. package/tests/session_records.mjs +4 -4
  1613. package/tests/session_rename_fallback.mjs +2 -2
  1614. package/tests/session_reward_on_land.mjs +7 -149
  1615. package/tests/session_reward_on_land_db.mjs +191 -0
  1616. package/tests/session_reward_reconcile.mjs +6 -88
  1617. package/tests/session_reward_reconcile_db.mjs +132 -0
  1618. package/tests/session_transcript.mjs +1 -1
  1619. package/tests/sessions_kit_pager.mjs +2 -1
  1620. package/tests/setup_device_flow_fallback.mjs +2 -2
  1621. package/tests/setup_smoke.mjs +12 -5
  1622. package/tests/setup_status_facts.mjs +54 -12
  1623. package/tests/ship_autolinkify.mjs +2 -2
  1624. package/tests/ship_automerge_injection.mjs +1 -1
  1625. package/tests/ship_base_flag.mjs +1 -1
  1626. package/tests/ship_broadcast_routing.mjs +1 -1
  1627. package/tests/ship_broadcast_server.mjs +2 -2
  1628. package/tests/ship_builder_model.mjs +1 -1
  1629. package/tests/ship_cannot_lie.mjs +9 -9
  1630. package/tests/ship_card.mjs +2 -2
  1631. package/tests/ship_ci_deploy.mjs +7 -7
  1632. package/tests/ship_error_shape.mjs +1 -1
  1633. package/tests/ship_land_ci_not_started.mjs +3 -3
  1634. package/tests/ship_land_conflict.mjs +3 -3
  1635. package/tests/ship_land_proof.mjs +3 -3
  1636. package/tests/ship_land_red_pr.mjs +5 -5
  1637. package/tests/ship_merge_gate.mjs +14 -14
  1638. package/tests/ship_mode.mjs +1 -1
  1639. package/tests/ship_mode_first_ship.mjs +4 -4
  1640. package/tests/ship_mode_hands_off.mjs +8 -8
  1641. package/tests/ship_post_land_verify.mjs +1 -1
  1642. package/tests/ship_preflight.mjs +19 -19
  1643. package/tests/ship_premerge.mjs +1 -1
  1644. package/tests/ship_publish_error.mjs +2 -2
  1645. package/tests/ship_push_diagnosis.mjs +1 -1
  1646. package/tests/ship_regen_copy_inventory.mjs +3 -3
  1647. package/tests/ship_resume.mjs +4 -4
  1648. package/tests/ship_smoke_gate.mjs +1 -1
  1649. package/tests/ship_upload_skip.mjs +1 -1
  1650. package/tests/ship_upstream_deletion.mjs +1 -1
  1651. package/tests/ship_vendored_instance.mjs +8 -8
  1652. package/tests/ship_visual_regrade.mjs +3 -3
  1653. package/tests/ship_zero_commit.mjs +1 -1
  1654. package/tests/skill_docs_unavailable_regrade.mjs +3 -3
  1655. package/tests/skill_friction_kind.mjs +1 -1
  1656. package/tests/skill_grade_recover.mjs +1 -1
  1657. package/tests/skill_grader_health.mjs +1 -1
  1658. package/tests/skill_lint.mjs +1 -1
  1659. package/tests/skill_menu_ruling.mjs +1 -1
  1660. package/tests/skill_preflight.mjs +7 -7
  1661. package/tests/skip_is_not_pass.mjs +22 -1
  1662. package/tests/smoke_dependencies_witness.mjs +2 -2
  1663. package/tests/smoke_preflight.mjs +1 -1
  1664. package/tests/smoke_target.mjs +2 -2
  1665. package/tests/smoke_write_contract.mjs +2 -2
  1666. package/tests/sound_player.mjs +8 -8
  1667. package/tests/source_text_test_ratchet.mjs +97 -0
  1668. package/tests/speciality_corpus_scope.mjs +1 -1
  1669. package/tests/speciality_session_skills.mjs +1 -1
  1670. package/tests/sso_checkin_legacy_field_gone.mjs +4 -2
  1671. package/tests/stale_timer.mjs +3 -3
  1672. package/tests/stale_worktrees.mjs +1 -1
  1673. package/tests/start_env_guard.mjs +1 -1
  1674. package/tests/start_goal_first.mjs +3 -3
  1675. package/tests/start_inbox_count.mjs +1 -1
  1676. package/tests/start_rebase_warning.mjs +1 -1
  1677. package/tests/status_default_version.mjs +3 -3
  1678. package/tests/status_mirror_sync.mjs +1 -1
  1679. package/tests/status_page_no_dead_uptime.mjs +80 -0
  1680. package/tests/stop_refcheck.mjs +1 -1
  1681. package/tests/strand_watch.mjs +1 -1
  1682. package/tests/stranded_rows.mjs +1 -1
  1683. package/tests/stuck_detector.mjs +14 -14
  1684. package/tests/sweep_app_account.mjs +3 -3
  1685. package/tests/task_cli.mjs +2 -2
  1686. package/tests/task_detail_ui.mjs +11 -1
  1687. package/tests/task_discipline_required.mjs +2 -2
  1688. package/tests/task_list_paging.mjs +1 -1
  1689. package/tests/task_visual_slots.mjs +2 -2
  1690. package/tests/terms_acceptance.mjs +1 -1
  1691. package/tests/terms_grandfather_db.mjs +1 -1
  1692. package/tests/test_path_guard.mjs +1 -1
  1693. package/tests/triage_development.mjs +1 -1
  1694. package/tests/tweak_batch_apply.mjs +2 -2
  1695. package/tests/tweak_land_heal.mjs +3 -3
  1696. package/tests/tweak_unattended.mjs +3 -3
  1697. package/tests/ui_design_skills.mjs +2 -2
  1698. package/tests/unit_report_status.mjs +2 -2
  1699. package/tests/unit_runner_serial.mjs +2 -2
  1700. package/tests/unit_runner_teardown_abort.mjs +1 -1
  1701. package/tests/update_channel.mjs +2 -2
  1702. package/tests/update_channel_db.mjs +4 -4
  1703. package/tests/update_subscription_engine.mjs +26 -26
  1704. package/tests/update_sweep_home.mjs +14 -14
  1705. package/tests/upgrade.mjs +11 -11
  1706. package/tests/upgrade_artist_gate.mjs +4 -4
  1707. package/tests/upgrade_commit_identity.mjs +2 -2
  1708. package/tests/upgrade_migrate.mjs +7 -7
  1709. package/tests/upgrade_operator.mjs +2 -2
  1710. package/tests/upgrade_outcome.mjs +2 -2
  1711. package/tests/upgrade_persist_pin.mjs +5 -5
  1712. package/tests/upkeep_home.mjs +1 -1
  1713. package/tests/version_close.mjs +2 -2
  1714. package/tests/version_close_cli.mjs +2 -2
  1715. package/tests/version_close_route.mjs +1 -1
  1716. package/tests/version_literals.mjs +23 -23
  1717. package/tests/visual_review.mjs +5 -5
  1718. package/tests/wedge_remedy.mjs +5 -5
  1719. package/tests/welcome_boot.mjs +116 -0
  1720. package/tests/welcome_boot_browser.mjs +271 -0
  1721. package/tests/wizard_born_first_board.mjs +3 -3
  1722. package/tests/wizard_demo.mjs +1 -1
  1723. package/tests/wizard_one_page.mjs +4 -3
  1724. package/tests/wizard_physics.mjs +3 -1
  1725. package/tests/wizard_physics_more.mjs +42 -3
  1726. package/tests/work_title_wrap.mjs +1 -1
  1727. package/tests/workflow_exec_paths.mjs +6 -6
  1728. package/tests/worktree_claim_guard.mjs +1 -1
  1729. package/tests/worktree_helper.mjs +2 -2
  1730. package/tests/write_validation_gaps.mjs +3 -3
  1731. package/scripts/gds/api.sh +0 -6
  1732. package/scripts/gds/audit-exports.js +0 -128
  1733. package/scripts/gds/resolve-skill-model.js +0 -57
  1734. package/scripts/gds/security-baseline-check.sh +0 -180
  1735. package/scripts/gds/spike-task-map.js +0 -899
  1736. package/scripts/status-probe.mjs +0 -213
  1737. package/src/bongos/uptime-poller.js +0 -93
  1738. package/tests/government_fold_bench.mjs +0 -50
  1739. package/tests/spike_task_map.mjs +0 -422
  1740. package/tests/status-probe.mjs +0 -89
  1741. /package/{scripts/gds → modules/raise}/CLAUDE.md +0 -0
  1742. /package/scripts/{gds → bongos}/cloudbongos-token-isolation.conf +0 -0
  1743. /package/scripts/{gds → bongos}/discipline-modes.json +0 -0
  1744. /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
+ };