@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,1361 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ // scripts/bongos/autobongos-run.js — the Autobongos supervisor's I/O half
5
+ // (task 1003902; ADR 0307 §1). One iteration is: gauge → pick → claim → spawn
6
+ // one worker → record. No model anywhere in this file; every branch it takes is
7
+ // a branch a person can read.
8
+ //
9
+ // node scripts/bongos/autobongos-run.js --forever # the daemon shape
10
+ // node scripts/bongos/autobongos-run.js # one task, then exit
11
+ // node scripts/bongos/autobongos-run.js --goal 1000119 # narrow to one goal
12
+ // node scripts/bongos/autobongos-run.js --max-tasks 5
13
+ // node scripts/bongos/autobongos-run.js --dry-run # pick only, claim nothing
14
+ //
15
+ // SCOPE, and what deliberately is NOT here:
16
+ // · the ALLOWLIST and the KILL SWITCH live in the DATABASE (task 1003908,
17
+ // ADR 0307 §6) and are read at step 0 of every iteration. `--goal` and
18
+ // AUTOBONGOS_GOALS survive only as a NARROWING filter — they can take goals
19
+ // away from the allowlist and can never add one, because a setting on this
20
+ // machine is editable by the very bypassPermissions worker the allowlist
21
+ // exists to bound.
22
+ // · CONFIRMING a ship against the ledger is autobongos-verify.js (task
23
+ // 1003903), called at step 6. A worker's `shipped` is a CLAIM — recorded here
24
+ // as `claims_shipped` so nothing can mistake it for a fact — and the ledger
25
+ // read is what turns it into one, or into a released claim and a blocker.
26
+ // · IT NEVER TERMINALLY STOPS (task 1003904, ADR 0307 §5). `--forever` runs the
27
+ // cadence state machine in modules/autonomy/cadence.js: three straight
28
+ // failures drop to `probing` — no new work, a growing wait, then exactly one
29
+ // task — and one success returns it to full speed. Nothing exits the loop,
30
+ // not even the kill switch, because a machine nobody is watching must not be
31
+ // able to look idle while it is dead. On boot it reconciles every claim a
32
+ // previous run left behind.
33
+
34
+ const { execFile, spawn } = require('node:child_process');
35
+ const fs = require('node:fs');
36
+ const path = require('node:path');
37
+ const crypto = require('node:crypto');
38
+ const os = require('node:os');
39
+
40
+ const seq = require('./sequence.js');
41
+ const gauge = require('./autonomy-gauge.js');
42
+ const {
43
+ buildWorkerArgs, buildWorkerPrompt, classifyRun, usageLimitHit, DEFAULT_MODEL, DEFAULT_WORKER_TIMEOUT_MS,
44
+ } = require('./autobongos-loop.js');
45
+ const { verifyShip, failureReason, recheckLands, pendingLandIds } = require('./autobongos-verify.js');
46
+ const gradeCap = require('./autobongos-grade-cap.js');
47
+ const fence = require('../../modules/autonomy/fence.js');
48
+ const tweakLane = require('./autobongos-tweak-lane.js');
49
+ // The ADR 0043 protected-path registry, reused rather than re-derived. scripts/
50
+ // sits outside the kernel boundary, so this direct core require is allowed here
51
+ // where it would not be inside modules/ — which is exactly why fence.js takes the
52
+ // hits as an argument instead of matching them itself.
53
+ const { matchProtected } = require('../../src/bongos/permission-path-check');
54
+ const { resolveEnv, envPrefix, LEGACY_ENV_PREFIXES } = require('../../src/instance-config');
55
+ const cadence = require('../../modules/autonomy/cadence.js');
56
+ const configIdle = require('../../modules/autonomy/config-idle.js');
57
+
58
+ const REPO_ROOT = path.resolve(__dirname, '..', '..');
59
+
60
+ function readArgv(argv) {
61
+ const out = { goals: [], maxTasks: 1, dryRun: false, json: false, forever: false, maxLoops: Infinity, model: DEFAULT_MODEL, timeoutMs: DEFAULT_WORKER_TIMEOUT_MS };
62
+ for (let i = 0; i < argv.length; i++) {
63
+ const a = argv[i];
64
+ if (a === '--goal') { out.goals.push(Number(argv[++i])); continue; }
65
+ if (a.startsWith('--goal=')) { out.goals.push(Number(a.slice(7))); continue; }
66
+ if (a === '--max-tasks') { out.maxTasks = Number(argv[++i]); continue; }
67
+ if (a === '--model') { out.model = argv[++i]; continue; }
68
+ if (a === '--timeout-min') { out.timeoutMs = Number(argv[++i]) * 60_000; continue; }
69
+ if (a === '--dry-run') { out.dryRun = true; continue; }
70
+ if (a === '--json') { out.json = true; continue; }
71
+ // --forever is the DAEMON shape: never returns, decides its own speed.
72
+ if (a === '--forever') { out.forever = true; continue; }
73
+ // --max-loops bounds the forever loop. It exists so a test (and an operator
74
+ // trying the thing out) can run the machine to completion; production passes
75
+ // it never, and Infinity is the honest default.
76
+ if (a === '--max-loops') { out.maxLoops = Number(argv[++i]); continue; }
77
+ }
78
+ if (!out.goals.length && process.env.AUTOBONGOS_GOALS) {
79
+ out.goals = String(process.env.AUTOBONGOS_GOALS).split(',').map((g) => Number(g.trim())).filter(Boolean);
80
+ }
81
+ // NOTE the semantics changed in task 1003908: `out.goals` is a REQUESTED filter,
82
+ // intersected with the database allowlist. An empty list no longer means "refuse
83
+ // to run" — it means "every allowlisted goal" — because the thing that refuses
84
+ // when nothing is permitted is now the fence, which this machine cannot edit.
85
+ return out;
86
+ }
87
+
88
+ const run = (file, args, opts = {}) => new Promise((resolve) => {
89
+ execFile(file, args, { cwd: REPO_ROOT, maxBuffer: 32 * 1024 * 1024, ...opts },
90
+ (err, stdout, stderr) => resolve({ ok: !err, code: err ? (err.code ?? 1) : 0, stdout: stdout || '', stderr: stderr || '' }));
91
+ });
92
+
93
+ // The run log is the supervisor's own record. It is NOT the ledger — Bongos is —
94
+ // but a machine nobody is watching must be able to say afterwards what it did,
95
+ // and an append-only JSONL survives a kill -9 mid-iteration.
96
+ function logPath() {
97
+ if (process.env.AUTOBONGOS_LOG_FILE) return process.env.AUTOBONGOS_LOG_FILE;
98
+ try { return require('../../src/instance-config.js').configPath('autobongos-runs.jsonl'); }
99
+ catch (_) { return path.join(REPO_ROOT, 'autobongos-runs.jsonl'); }
100
+ }
101
+
102
+ function record(entry) {
103
+ const row = { at: new Date().toISOString(), ...entry };
104
+ try {
105
+ const p = logPath();
106
+ fs.mkdirSync(path.dirname(p), { recursive: true });
107
+ fs.appendFileSync(p, `${JSON.stringify(row)}\n`);
108
+ } catch (_) { /* a runner that cannot log must still run */ }
109
+ return row;
110
+ }
111
+
112
+ // readRunLogRows — the run log back as rows, newest last. Only the TAIL is read
113
+ // (a log that runs for weeks must not be slurped whole every loop), and a line
114
+ // that will not parse — the half-written last line of a kill -9 — is skipped.
115
+ function readRunLogRows(p = logPath(), maxBytes = 4 * 1024 * 1024) {
116
+ let text = '';
117
+ try {
118
+ const size = fs.statSync(p).size;
119
+ const fd = fs.openSync(p, 'r');
120
+ try {
121
+ const len = Math.min(size, maxBytes);
122
+ const buf = Buffer.alloc(len);
123
+ fs.readSync(fd, buf, 0, len, size - len);
124
+ text = buf.toString('utf8');
125
+ } finally { fs.closeSync(fd); }
126
+ } catch (_) { return []; }
127
+ const rows = [];
128
+ for (const line of text.split('\n')) {
129
+ if (!line.trim()) continue;
130
+ try { rows.push(JSON.parse(line)); } catch (_) { /* partial line */ }
131
+ }
132
+ return rows;
133
+ }
134
+
135
+ // recheckPendingLands — once per loop (task 1004538). Which tasks are waiting on
136
+ // a land comes from the run log on disk and when they shipped comes from the
137
+ // ledger, so a restart loses neither. Open `shipped_no_artifact` blockers are read
138
+ // from the database and resolved once main carries the commit. Every outcome is a
139
+ // row, so the next pass reads it back.
140
+ //
141
+ // The blocker sweep runs at most once per LAND_SWEEP_MS per process (and at once
142
+ // after a restart): a false alarm closing within the hour is plenty, and the
143
+ // open-blocker list need not be read on every loop. Pending lands are re-probed
144
+ // every loop — and cost nothing when there are none.
145
+ const LAND_SWEEP_MS = 60 * 60 * 1000;
146
+ async function recheckPendingLands(deps = {}) {
147
+ const log = deps.record || record;
148
+ const st = deps.state || RUNNER_STATE;
149
+ const now = deps.now ? deps.now() : Date.now();
150
+ const sweepBlockers = !st.landSweepAt || now - st.landSweepAt >= LAND_SWEEP_MS;
151
+ const ids = pendingLandIds(readRunLogRows());
152
+ if (!ids.length && !sweepBlockers) return { rechecked: [], resolved: [], errors: [] };
153
+ const out = await recheckLands({ pendingIds: ids, sweepBlockers }, { ...(deps.api ? { api: deps.api } : {}), ...(deps.landDeps || {}) });
154
+ if (sweepBlockers) st.landSweepAt = now;
155
+ for (const r of out.rechecked) log({ event: 'land_recheck', ...r });
156
+ for (const r of out.resolved) {
157
+ log({ event: 'land_blocker_resolved', task_id: r.task_id, blocker_id: r.blocker_id, sha: r.sha,
158
+ reason: `main now carries ${r.sha} naming task ${r.task_id} — the no-artifact blocker was a slow land, resolved` });
159
+ }
160
+ if (out.errors.length) log({ event: 'land_recheck_failed', errors: out.errors.slice(0, 10) });
161
+ return out;
162
+ }
163
+
164
+ // pickedFrom — the row fields that say where a pick came from (task 1004453).
165
+ // `priority` is true only when the fence named a priority goal AND this pick came
166
+ // from it, so "the priority goal ran dry and the runner moved on" reads as
167
+ // priority:false beside the goal it moved on to.
168
+ function pickedFrom(goalId, gate) {
169
+ const p = gate && gate.priorityGoal != null ? gate.priorityGoal : null;
170
+ return { priority: p !== null && Number(goalId) === p };
171
+ }
172
+
173
+ // pickTask — the allowlisted goals, in order, through sequence.js's halt matrix.
174
+ // The matrix is reused rather than re-derived: it already refuses thin specs,
175
+ // protected paths, judgement kinds and unmet dependencies, from facts on the row.
176
+ // The assembly below mirrors sequence.js's own --goal --next path step for step,
177
+ // so the runner and a person running /builder-sequence cannot disagree about
178
+ // which task is next.
179
+ //
180
+ // `claimableIds` is fetched because the matrix's `not_claimable` reason defers to
181
+ // the server's own feed rather than re-deriving its filter here. A null (feed
182
+ // unreadable) makes that one reason stay QUIET rather than halt everything —
183
+ // ADR 0153 records the bug where the opposite turned an empty read into a
184
+ // universal halt.
185
+ async function pickTask(goals, deps = {}) {
186
+ const api = deps.api || await (require('./cli-lib').cliClient)();
187
+ let rank = deps.rank;
188
+ if (rank === undefined) {
189
+ const me = await api.me.getMe();
190
+ rank = me.ok ? me.data.builder?.rank : null;
191
+ }
192
+ const claimableIds = await seq.fetchClaimableIds(api);
193
+
194
+ // The skipped lists from EVERY goal are kept, not just the last one. An empty
195
+ // queue and a queue where every task halts both yield no task, and telling them
196
+ // apart is the whole of `unworkable_queue` (task 1003904): calling the second
197
+ // one "idle" is how a goal full of blocked work sits for a week with the runner
198
+ // reporting itself perfectly healthy.
199
+ const allSkipped = [];
200
+ for (const goalId of goals) {
201
+ let byId;
202
+ try { byId = await seq.fetchGoalTasks(api, goalId, seq.GOAL_PAGE); }
203
+ catch (e) { return { error: `goal ${goalId}: ${e.message}` }; }
204
+
205
+ const candidates = Array.from(byId.values()).filter((t) => !seq.TERMINAL.has(t.status));
206
+ const { order } = seq.topoOrder(candidates);
207
+ // Tasks this process set aside after a refused claim (task 1004396) drop out
208
+ // AFTER ordering, so a dependent of one is still halted by its own unmet
209
+ // dependency rather than promoted by the task's absence.
210
+ const exclude = deps.exclude || null;
211
+ const unexcluded = exclude && exclude.size ? order.filter((t) => !exclude.has(String(t.id))) : order;
212
+ // Work this machine structurally cannot do — SSH, root, systemd on a live
213
+ // host (task 1004537) — is skipped BEFORE the claim, and listed with its
214
+ // reason. It is decided here and not in sequence.js's matrix because the
215
+ // matrix also serves /builder-sequence, where the builder may well hold the
216
+ // host access an unattended runner never has.
217
+ const hostSkipped = [];
218
+ const open = unexcluded.filter((t) => {
219
+ const host = fence.needsHostAccess(t);
220
+ if (!host.needs) return true;
221
+ hostSkipped.push({ id: t.id, title: t.title, reasons: [{ code: 'needs_host_access', detail: `${fence.REFUSALS.needs_host_access} (${host.signals.join('; ')})` }] });
222
+ return false;
223
+ });
224
+ const { next, skipped } = seq.pickNext(open, { rank, claimableIds });
225
+ if (next) return { task: next, goalId, skipped: [...hostSkipped, ...skipped] };
226
+ for (const sk of [...hostSkipped, ...skipped]) allSkipped.push({ ...sk, goal_id: goalId });
227
+ }
228
+ return { none: true, skipped: allSkipped };
229
+ }
230
+
231
+ // WORKER_ENV_ALLOW — what a worker is allowed to inherit (grader finding, task
232
+ // 1003902). Spreading `process.env` handed a bypassPermissions session every
233
+ // credential the supervisor happened to hold — DB URLs, npm and git tokens — to a
234
+ // process whose only injection defence is a prompt fence. The fence is good and
235
+ // it is not a technical barrier, so the blast radius of a jailbreak has to be
236
+ // bounded by something that is.
237
+ //
238
+ // The worker needs: to run node and claude (PATH/HOME/SHELL and the platform's
239
+ // own required vars), to reach the instance (BONGOS_API_BASE), and to be told it
240
+ // is a subagent. It does NOT need a git push credential — the road to main is the
241
+ // server-mediated pipeline (ADR 0307 §6) — so none is passed.
242
+ function claudeBinEnvNames() {
243
+ return [...new Set([envPrefix(), ...LEGACY_ENV_PREFIXES].map((p) => `${p}_CLAUDE_BIN`)), 'CLAUDE_BIN'];
244
+ }
245
+
246
+ const WORKER_ENV_ALLOW = [
247
+ 'PATH', 'HOME', 'SHELL', 'LANG', 'LC_ALL', 'TZ', 'TMPDIR', 'USER', 'LOGNAME',
248
+ 'SystemRoot', 'windir', 'COMSPEC', 'PATHEXT', 'USERPROFILE', 'APPDATA', 'LOCALAPPDATA', 'TEMP', 'TMP',
249
+ 'BONGOS_API_BASE', 'CLOUDBONGOS_API_BASE',
250
+ // Every spelling resolveWorkerBin below can read (task 1001441): the branded
251
+ // <PREFIX>_CLAUDE_BIN, the legacy ones, and the unprefixed CLAUDE_BIN. A name
252
+ // missing here would be set on the host and silently absent in the worker.
253
+ ...claudeBinEnvNames(),
254
+ 'XDG_CONFIG_HOME',
255
+ // THE WORKER'S OWN CREDENTIAL, and it has to be here (task 1003907, found by
256
+ // running it). On a desktop, the claude CLI authenticates from the credential
257
+ // store under USERPROFILE/HOME, which are already allowed - so this list looked
258
+ // complete. On a HEADLESS host there is no interactive login to have written
259
+ // one, and setup.js's own preflight says to set CLAUDE_CODE_OAUTH_TOKEN there
260
+ // instead. Stripping it meant every worker on the machine this was built for
261
+ // started unauthenticated, exited in ~2s, and the run recorded only "worker
262
+ // output was not JSON".
263
+ //
264
+ // This is not the leak the list exists to prevent. The worker IS a Claude
265
+ // session; its own auth is the one credential it cannot do its job without.
266
+ // Everything the comment above refuses - DB URLs, git and npm tokens - stays
267
+ // refused.
268
+ 'CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY',
269
+ ];
270
+
271
+ function workerEnv(source = process.env, extra = {}) {
272
+ const out = {};
273
+ for (const k of WORKER_ENV_ALLOW) if (source[k] !== undefined) out[k] = source[k];
274
+ // An operator can widen this deliberately and visibly, never by accident.
275
+ const widen = String(source.AUTOBONGOS_WORKER_ENV_EXTRA || '').split(',').map((x) => x.trim()).filter(Boolean);
276
+ for (const k of widen) if (source[k] !== undefined) out[k] = source[k];
277
+ return { ...out, OTB_SUBAGENT: '1', ...extra };
278
+ }
279
+
280
+ const MAX_WORKER_OUTPUT = 8 * 1024 * 1024; // a misbehaving worker must not grow memory until the timeout
281
+
282
+ // resolveWorkerBin — WHICH `claude`, and whether it needs a shell.
283
+ //
284
+ // THE BUG THIS EXISTS FOR (task 1003907, found by running it on the real Windows
285
+ // host). On Windows `claude` on PATH is a .cmd shim, and Node has refused to
286
+ // spawn .cmd/.bat without a shell since CVE-2024-27980 — so this used to pass
287
+ // `shell: process.platform === 'win32'`. But `shell: true` does not pass argv
288
+ // through: it CONCATENATES it into one command line that cmd.exe re-parses,
289
+ // which destroys every embedded quote. `--json-schema` is a JSON blob made
290
+ // almost entirely of quotes, so claude received a mangled argument and exited in
291
+ // ~2s with `--json-schema is not valid JSON`. Every worker. Every run. Forever —
292
+ // and the cadence classes that as `quiet`, so it never trips the failure ladder.
293
+ //
294
+ // The npm package ships a REAL claude.exe beside the shim, so prefer it: a true
295
+ // executable spawns with shell:false and exact argv, and nothing re-parses.
296
+ // Falling back to the old behaviour is deliberate — a host with a differently
297
+ // laid-out install should still run, and a corrupted schema surfaces as a failed
298
+ // worker rather than as a refusal to start at all.
299
+ function resolveWorkerBin(env = process.env, platform = process.platform) {
300
+ const override = resolveEnv('CLAUDE_BIN', { env }) || env.CLAUDE_BIN;
301
+ if (override) return { bin: override, shell: platform === 'win32' && /\.(cmd|bat)$/i.test(override) };
302
+ if (platform !== 'win32') return { bin: 'claude', shell: false };
303
+ for (const dir of String(env.PATH || env.Path || '').split(path.delimiter)) {
304
+ if (!dir) continue;
305
+ const candidates = [
306
+ path.join(dir, 'node_modules', '@anthropic-ai', 'claude-code', 'bin', 'claude.exe'),
307
+ path.join(dir, 'claude.exe'),
308
+ ];
309
+ for (const c of candidates) {
310
+ try { if (fs.existsSync(c)) return { bin: c, shell: false }; } catch (_) {}
311
+ }
312
+ }
313
+ return { bin: 'claude', shell: true };
314
+ }
315
+
316
+ // gradeLedgerPath — the run's LOCAL ledger (task 1004536): the file ship.js reads
317
+ // to refuse a third grade early. A fresh file per run, under the instance config
318
+ // dir, never inside the task's tree. It is the courtesy half of the cap — see the
319
+ // header of autobongos-grade-cap.js; the boundary is the server count below.
320
+ const GRADE_CAP_WATCH_MS = 30_000;
321
+ function gradeLedgerPath(taskId) {
322
+ const id = Number(taskId);
323
+ if (!Number.isSafeInteger(id) || id <= 0) throw new Error(`gradeLedgerPath: task id must be a positive integer, got ${taskId}`);
324
+ const name = path.join('autobongos-grades', `${id}-${Date.now()}-${crypto.randomBytes(3).toString('hex')}.jsonl`);
325
+ try { return require('../../src/instance-config.js').configPath(name); }
326
+ catch (_) { return path.join(os.tmpdir(), name); }
327
+ }
328
+
329
+ // gradeCapReader — how the supervisor counts this run's graded rounds.
330
+ //
331
+ // The SERVER's grade_attempts is the count that matters: the worker has no write
332
+ // path to it, so clearing an env var or deleting a file cannot reset it. The
333
+ // baseline is the newest attempt recorded BEFORE the worker starts; only rounds
334
+ // after it belong to this run. When the server cannot be read, the local ledger
335
+ // is the fallback — and either source showing the cap exhausted is enough.
336
+ async function gradeCapReader({ api, taskId, ledger }) {
337
+ const before = await gradeCap.readServerAttempts(api, taskId);
338
+ const afterMs = before ? gradeCap.newestAttemptAt(before) : null;
339
+ return async function read() {
340
+ const local = gradeCap.gradeCapState(gradeCap.readLedger(ledger), taskId);
341
+ const attempts = before ? await gradeCap.readServerAttempts(api, taskId) : null;
342
+ if (!attempts) return { ...local, source: 'local' };
343
+ const server = gradeCap.gradeCapState(gradeCap.roundsFromAttempts(attempts, taskId, afterMs), taskId);
344
+ return server.exhausted || !local.exhausted ? { ...server, source: 'server' } : { ...local, source: 'local' };
345
+ };
346
+ }
347
+
348
+ // spawnWorker — one headless session, bounded by WALL CLOCK, in the task's own
349
+ // working tree.
350
+ async function spawnWorker({ task, model, timeoutMs, cwd, gradeLedger = null, capCheck = null, prompt: givenPrompt = null, deps = {} }) {
351
+ const spawnFn = deps.spawn || spawn;
352
+ const sessionId = deps.sessionId || crypto.randomUUID(); // pinned, so the session can be resumed
353
+ const { bin, shell: workerShell } = deps.resolveBin ? deps.resolveBin() : resolveWorkerBin();
354
+ const isRoot = typeof process.getuid === 'function' && process.getuid() === 0;
355
+ const args = buildWorkerArgs({ sessionId, model, isRoot });
356
+ const prompt = givenPrompt || buildWorkerPrompt({ task }); // the tweak lane names its own (task 1004679)
357
+
358
+ return new Promise((resolve) => {
359
+ let child;
360
+ try {
361
+ child = spawnFn(bin, args, {
362
+ cwd,
363
+ // stdin is a PIPE we write the prompt into and close. Never inherit: a
364
+ // `claude -p` with an open inherited stdin waits seconds for input that
365
+ // never comes, on every single spawn.
366
+ stdio: ['pipe', 'pipe', 'pipe'],
367
+ shell: workerShell,
368
+ windowsHide: true,
369
+ // The run's local grade ledger (task 1004536): ship.js appends each graded
370
+ // round to it and refuses a third early. The worker can see this variable,
371
+ // so it is the courtesy half only — capCheck below is the boundary.
372
+ env: workerEnv(process.env, gradeLedger ? { [gradeCap.LEDGER_ENV]: gradeLedger } : {}),
373
+ });
374
+ } catch (e) { return resolve({ spawnError: e.message }); }
375
+
376
+ let stdout = ''; let stderr = ''; let timedOut = false; let truncated = false; let gradeCapped = false;
377
+ const cap = (cur, d) => {
378
+ if (cur.length >= MAX_WORKER_OUTPUT) { truncated = true; return cur; }
379
+ return cur + String(d).slice(0, MAX_WORKER_OUTPUT - cur.length);
380
+ };
381
+ const timer = setTimeout(() => { timedOut = true; try { child.kill('SIGKILL'); } catch (_) {} }, timeoutMs);
382
+ // task 1004536: once the second graded FAIL is recorded the run is over — the
383
+ // task goes to the owner. capCheck reads the SERVER's grade_attempts (see
384
+ // gradeCapReader), so a worker that cleared the ledger env or deleted the file
385
+ // is still stopped. One read at a time: a slow API must not stack polls.
386
+ let capBusy = false;
387
+ const capWatch = capCheck ? setInterval(async () => {
388
+ if (capBusy || gradeCapped) return;
389
+ capBusy = true;
390
+ try {
391
+ if ((await capCheck()).exhausted) {
392
+ gradeCapped = true; clearInterval(capWatch);
393
+ try { child.kill('SIGKILL'); } catch (_) {}
394
+ }
395
+ } catch (_) { /* an unreadable count is retried next tick; the post-run read still decides */ }
396
+ capBusy = false;
397
+ }, deps.capWatchMs || GRADE_CAP_WATCH_MS) : null;
398
+ const stopWatch = () => { if (capWatch) clearInterval(capWatch); };
399
+ child.stdout.on('data', (d) => { stdout = cap(stdout, d); });
400
+ child.stderr.on('data', (d) => { stderr = cap(stderr, d); });
401
+ child.on('error', (e) => { clearTimeout(timer); stopWatch(); resolve({ spawnError: e.message, sessionId }); });
402
+ child.on('close', (code) => {
403
+ clearTimeout(timer); stopWatch();
404
+ resolve({ envelope: stdout, exitCode: code, timedOut, truncated, gradeCapped, sessionId, stderr: stderr.slice(-2000) });
405
+ });
406
+ child.stdin.end(prompt);
407
+ });
408
+ }
409
+
410
+ // worktreeFor — the task gets its OWN linked working tree, and this is not a
411
+ // nicety (grader finding, task 1003902).
412
+ //
413
+ // worktree-per-claim is an ENFORCED project default: worktree-claim-guard.js
414
+ // refuses any claim made from the main checkout, with no escape but `--here`.
415
+ // The natural shape for a long-lived unattended supervisor is one persistent
416
+ // checkout — which is the main checkout — so the first cut of this loop would
417
+ // have taken `claim_failed` on every single iteration and never done any work.
418
+ // Reaching for `--here` would "fix" that by defeating the guard: the worker's
419
+ // branch would land in the supervisor's own tree, which is precisely the strand
420
+ // the guard exists to prevent.
421
+ //
422
+ // The name carries the task id plus a random suffix. Unique by construction, so
423
+ // it cannot collide with another active claim's tree — a collision makes the
424
+ // server store a disambiguated name the ship lock can never match (task 1004031).
425
+ function worktreeName(taskId) {
426
+ return `autobongos-${taskId}-${crypto.randomBytes(3).toString('hex')}`;
427
+ }
428
+
429
+ // readFence — the two facts the fence is made of, in one place.
430
+ //
431
+ // BOTH come from the server. `GET /autonomy/fence` is the kill switch and the
432
+ // allowlist; `GET /me`'s `grader_bypass` is ADR 0041's global grader killswitch,
433
+ // resolved server-side from the server's own env. Neither is readable from a file
434
+ // on this machine, and that is the entire point — see modules/autonomy/fence.js.
435
+ //
436
+ // A failure of EITHER read returns the shape that refuses. An unreachable
437
+ // instance and a thrown kill switch are different facts, but they license the
438
+ // same action: do nothing.
439
+ async function readFence(deps = {}) {
440
+ const api = deps.api || await (require('./cli-lib').cliClient)();
441
+ let raw = null;
442
+ let graderBypassed = null;
443
+ try {
444
+ const r = await api.autonomy.getAutonomyFence();
445
+ if (r && r.ok) raw = r.data;
446
+ } catch (_) { /* unreadable → refuses below */ }
447
+ try {
448
+ const me = await api.me.getMe();
449
+ // Strictly a boolean or nothing. `undefined` from an older server is NOT
450
+ // `false`: it means this instance cannot tell us, which refuses.
451
+ if (me && me.ok && typeof me.data.grader_bypass === 'boolean') graderBypassed = me.data.grader_bypass;
452
+ } catch (_) { /* unreadable → refuses below */ }
453
+ return { raw, graderBypassed };
454
+ }
455
+
456
+ // ── what one process remembers between iterations (task 1004396) ────────────
457
+ //
458
+ // Owner ruling, 2026-09-30: a refused claim must not put the runner into waiting
459
+ // by default. It sets THAT task aside and tries the next one. It waits only when
460
+ // there is a block and nothing else it can claim.
461
+ //
462
+ // The two refusals are told apart by claim.js's exit code, because the message is
463
+ // prose and the first cut of this read prose. The run that found this burned
464
+ // ~30 attempts on task 1004254, whose refusal quoted "Your work changes the
465
+ // tools…" — which reads like a per-task protected-path verdict and was in fact
466
+ // the plain-words line of a QUEUE-WIDE gate about a different, stranded task.
467
+ // Setting 1004254 aside would have moved the runner on to the next task, which
468
+ // the same gate refuses too.
469
+ //
470
+ // QUEUE_GATED_EXIT is pinned against claim.js's own value in a test rather than
471
+ // required from it: requiring the CLI would load its whole dependency graph into
472
+ // a process that runs for weeks, to read one integer.
473
+ const QUEUE_GATED_EXIT = 4;
474
+ // How long a task refused ON ITS OWN is left alone. Not forever: most per-task
475
+ // refusals clear (a dependency ships, a claim is released, a blocker resolves),
476
+ // and a process that remembered them for its whole life would shelve work it can
477
+ // do. Half an hour is several wakes at full speed, so a refused head of the queue
478
+ // costs one attempt per half hour instead of one per wake.
479
+ const CLAIM_SET_ASIDE_MS = 30 * 60 * 1000;
480
+ // A bound on claim attempts in ONE pass, so a queue of refusals cannot turn one
481
+ // iteration into dozens of worktree creations.
482
+ const MAX_CLAIM_ATTEMPTS = 5;
483
+ // A limit message with no machine-readable reset (the CLI's human forms name a
484
+ // clock time in a zone we would have to guess). Half an hour is short against a
485
+ // five-hour window and long against a spawn that is cut off in two seconds, so a
486
+ // guess that is wrong costs one wasted spawn per half hour, not one per wake.
487
+ const LIMIT_UNKNOWN_RESET_MS = 30 * 60 * 1000;
488
+
489
+ function newRunnerState() {
490
+ return { setAside: new Map(), queueGate: null, limitUntil: null, diskHead: null, mainHead: null, landSweepAt: null };
491
+ }
492
+ const RUNNER_STATE = newRunnerState();
493
+
494
+ // The stranded task ids a queue-gated refusal names (" - task 777 Title"). An
495
+ // empty list is a legal answer: the gate is still a gate, the runner simply has
496
+ // nothing to poll and tries one claim per wake instead.
497
+ function owedTaskIds(text) {
498
+ const ids = [];
499
+ const re = /^\s*-\s*task\s+(\d+)/gm;
500
+ let m;
501
+ while ((m = re.exec(String(text || ''))) !== null) ids.push(m[1]);
502
+ return ids;
503
+ }
504
+
505
+ // Does the gate still hold? Asked of the LEDGER, one read per stranded task, and
506
+ // never by attempting a claim: a claim attempt per wake is the loop this replaces.
507
+ // An unreadable task keeps the wait — guessing "cleared" would restart the
508
+ // attempts on a read failure, the opposite of backing off.
509
+ async function queueGateHolds(queueGate, deps = {}) {
510
+ if (!queueGate.owed.length) return false;
511
+ const api = deps.api && deps.api.tasks ? deps.api : await (require('./cli-lib').cliClient)();
512
+ for (const id of queueGate.owed) {
513
+ let r = null;
514
+ try { r = await api.tasks.getTasksId({ id: Number(id) }); } catch (_) { return true; }
515
+ if (!r || !r.ok || !r.data || !r.data.task) return true;
516
+ if (r.data.task.status === 'confirmed') return true;
517
+ }
518
+ return false;
519
+ }
520
+
521
+ function queueGatedRow(queueGate, now) {
522
+ const on = queueGate.owed.length ? queueGate.owed.map((id) => `task ${id}`).join(', ') : 'a stranded confirmed task';
523
+ return {
524
+ event: 'queue_gated', waiting_on: queueGate.owed,
525
+ waited_s: Math.max(0, Math.round((now - queueGate.since) / 1000)),
526
+ reason: `every claim is refused until ${on} lands — waiting, not claiming (${queueGate.reason})`,
527
+ };
528
+ }
529
+
530
+ async function iteration(opts, deps = {}) {
531
+ const runCmd = deps.run || run;
532
+ const spawnWork = deps.spawnWorker || spawnWorker;
533
+ const readGauge = deps.gauge || (() => gauge.evaluate());
534
+ const pick = deps.pickTask || pickTask;
535
+ const log = deps.record || record;
536
+
537
+ // 0. THE FENCE (task 1003908, ADR 0307 §6). Before the gauge, because three of
538
+ // its four gates make every task refusable and there is no sense paying for a
539
+ // capacity read to discover that. Before anything is picked, claimed or spawned,
540
+ // because a fence checked after the fact is not a fence.
541
+ const { raw, graderBypassed } = deps.readFence ? await deps.readFence(deps) : await readFence(deps);
542
+ // NOT named `run`. The module-level exec helper above is called `run`, and a
543
+ // `const run` anywhere in this function hoists into a Temporal Dead Zone that
544
+ // covers the WHOLE body — including `deps.run || run` at the top, which is the
545
+ // PRODUCTION call shape (main() passes no deps). That shadowing threw
546
+ // `ReferenceError: Cannot access 'run' before initialization` on the first line
547
+ // of every real iteration while every test stayed green, because the harness
548
+ // always injected deps.run. Caught by the grader on task 1003908; the test that
549
+ // now drives iteration() with no deps is the actual fix — this rename is half.
550
+ const gate = fence.decideRun({ fence: raw, requestedGoals: opts.goals, graderBypassed });
551
+ // ADR 0371 D3 (task 1004679): the tweak lane's own setting replaces the GOAL
552
+ // ALLOWLIST for that lane only, so a fence that refused on goals alone still lets
553
+ // the lane run below; the kill switch and the grader stop refuse it here.
554
+ const fencedRow = () => log({ event: 'fenced', code: gate.code, reason: gate.reason, refused_goals: gate.refusedGoals || [] });
555
+ const goalsOnly = !gate.go && tweakLane.GOAL_ONLY_CODES.has(gate.code)
556
+ && await (deps.laneSwitchOn || tweakLane.laneSwitchOn)(deps.api);
557
+ if (!gate.go && !goalsOnly) return fencedRow();
558
+
559
+ // 1. The gauge. Never start a task we cannot pay for out of the window.
560
+ const g = readGauge();
561
+ if (!g.decision.go) {
562
+ return log({ event: 'hold', go: false, unknown: !!g.decision.unknown, reason: g.decision.reason, sleep_until: g.decision.sleepUntil ?? null });
563
+ }
564
+
565
+ // 1b. The usage limit, once HIT (task 1004454). Owner ruling 2026-09-30: no
566
+ // fixed cap on how much work a reading buys — the gauge above is read before
567
+ // every task and a derived reading proceeds — and hitting the limit is
568
+ // acceptable, so long as the runner then waits for the reset and resumes by
569
+ // itself. A worker cut off by the limit records when it resets; until then no
570
+ // task is taken, because every worker spawned would be cut off the same way.
571
+ const state = deps.state || RUNNER_STATE;
572
+ const now = deps.now ? deps.now() : Date.now();
573
+ if (state.limitUntil) {
574
+ if (now < state.limitUntil) {
575
+ return log({
576
+ event: 'hold', go: false, unknown: false, usage_limit: true,
577
+ reason: 'the subscription usage limit was hit — sleeping to its reset, then resuming by itself',
578
+ sleep_until: Math.round(state.limitUntil / 1000),
579
+ });
580
+ }
581
+ log({ event: 'usage_limit_reset', was_until: new Date(state.limitUntil).toISOString() });
582
+ state.limitUntil = null;
583
+ }
584
+
585
+ // 1c. A QUEUE-WIDE gate from an earlier pass (task 1004396). While the
586
+ // stranded task it named is still `confirmed`, every claim would be refused, so
587
+ // none is attempted. The wait wakes early when main moves (waitOrJump), which is
588
+ // exactly what the strand landing does.
589
+ if (state.queueGate) {
590
+ if (await queueGateHolds(state.queueGate, deps)) return log(queueGatedRow(state.queueGate, now));
591
+ log({ event: 'queue_gate_cleared', waited_on: state.queueGate.owed, waited_s: Math.max(0, Math.round((now - state.queueGate.since) / 1000)) });
592
+ state.queueGate = null;
593
+ }
594
+ for (const [id, until] of state.setAside) if (until <= now) state.setAside.delete(id);
595
+
596
+ // 1d. THE TWEAK LANE (task 1004679, ADR 0371 D1): before ordinary work, the
597
+ // oldest submitted page round the lane may take. Null means it took none.
598
+ const laneRow = await (deps.tweakLaneStep || tweakLane.tweakLaneStep)({ opts, state }, {
599
+ api: deps.api || await (require('./cli-lib').cliClient)(), log, matchProtected, runCmd, spawnWork,
600
+ worktreeName: deps.worktreeName || worktreeName, spawnDeps: deps, gradeCapReader,
601
+ gradeLedgerPath: deps.gradeLedgerPath || gradeLedgerPath, ...(deps.laneDeps || {}),
602
+ });
603
+ if (laneRow) return laneRow;
604
+ if (goalsOnly) return fencedRow();
605
+
606
+ // 2–4, up to MAX_CLAIM_ATTEMPTS times: pick, fence, tree, claim. A task refused
607
+ // on its own is set aside and the NEXT one is tried in the same pass.
608
+ let task = null; let picked = null; let wtName = null; let wtPath = null;
609
+ let lastRefusal = null;
610
+ for (let attempt = 0; attempt < MAX_CLAIM_ATTEMPTS && !task; attempt++) {
611
+ const exclude = new Set(state.setAside.keys());
612
+ // 2. Pick — from the ALLOWLISTED goals, never from what the command line asked
613
+ // for. gate.goals is already the intersection.
614
+ const got = await pick(gate.goals, { ...(deps.pickDeps || {}), exclude });
615
+ if (got.error) return log({ event: 'pick_failed', reason: got.error });
616
+ // A picker that hands back a set-aside task is treated as having none left:
617
+ // the exclusion is this function's contract, not the picker's courtesy.
618
+ if (got.none || exclude.has(String(got.task.id))) {
619
+ // Everything left was refused in THIS pass: return the last refusal, not
620
+ // "nothing claimable". Every claim failing at once is also what an outage
621
+ // looks like, and it must still reach the failure ladder (task 1004179).
622
+ if (lastRefusal) return lastRefusal;
623
+ return log({
624
+ event: 'nothing_claimable', goals: gate.goals, priority_goal: gate.priorityGoal ?? null,
625
+ // Carried so the cadence can tell an EMPTY queue from one where every task
626
+ // halts — the reasons are the matrix's own codes, safe to print.
627
+ skipped: (got.skipped || []).map((sk) => ({ id: sk.id, goal_id: sk.goal_id, reasons: (sk.reasons || []).map((r) => r.code) })),
628
+ set_aside: Array.from(state.setAside, ([id, until]) => ({ id, until: new Date(until).toISOString() })),
629
+ });
630
+ }
631
+ const candidate = got.task;
632
+
633
+ // 2b. The per-TASK half of the fence. sequence.js's halt matrix already refuses
634
+ // a protected-path task, and this re-asks anyway — not from distrust of the
635
+ // matrix, but because the matrix is a shared component with its own callers and
636
+ // the fence must not be a property of whoever happens to be picking. A gate that
637
+ // only holds while a collaborator keeps calling it is not a gate.
638
+ //
639
+ // Both halves read the task's DECLARED touches[], which is a claim, not a fact —
640
+ // see the header of modules/autonomy/fence.js for why that is acceptable as the
641
+ // OUTER of three layers and would not be as the only one.
642
+ const taskGate = fence.decideTask({
643
+ task: candidate, goals: gate.goals, protectedHits: matchProtected(candidate.touches || []),
644
+ });
645
+ if (!taskGate.go) {
646
+ return log({ event: 'fenced', code: taskGate.code, reason: taskGate.reason, task_id: candidate.id, goal_id: got.goalId, ...pickedFrom(got.goalId, gate), globs: taskGate.globs || [] });
647
+ }
648
+
649
+ if (opts.dryRun) return log({ event: 'dry_run', task_id: candidate.id, title: candidate.title, goal_id: got.goalId, ...pickedFrom(got.goalId, gate) });
650
+
651
+ // 3. The task's own working tree.
652
+ const name = deps.worktreeName ? deps.worktreeName(candidate.id) : worktreeName(candidate.id);
653
+ const made = await runCmd(process.execPath, [path.join('scripts', 'bongos', 'worktree.js'), 'add', name, '--base', 'origin/main']);
654
+ if (!made.ok) {
655
+ return log({ event: 'worktree_failed', task_id: candidate.id, worktree: name, reason: failureReason(made, 'worktree.js') });
656
+ }
657
+ const treePath = path.join(REPO_ROOT, '.claude', 'worktrees', name);
658
+
659
+ // 4. Claim FROM that tree, so claim.js records it as the claim's tree and the
660
+ // ship lock later agrees with where the work actually is.
661
+ const claimed = await runCmd(process.execPath, [path.join(REPO_ROOT, 'scripts', 'bongos', 'claim.js'), String(candidate.id)], { cwd: treePath });
662
+ if (!claimed.ok) {
663
+ await runCmd(process.execPath, [path.join('scripts', 'bongos', 'worktree.js'), 'remove', name]);
664
+ const reason = failureReason(claimed, 'claim.js');
665
+ if (claimed.code === QUEUE_GATED_EXIT) {
666
+ state.queueGate = { owed: owedTaskIds(`${claimed.stderr || ''}\n${claimed.stdout || ''}`), since: now, reason };
667
+ return log({ ...queueGatedRow(state.queueGate, now), task_id: candidate.id, worktree: name });
668
+ }
669
+ state.setAside.set(String(candidate.id), now + CLAIM_SET_ASIDE_MS);
670
+ lastRefusal = log({ event: 'claim_failed', task_id: candidate.id, worktree: name, reason, set_aside_s: CLAIM_SET_ASIDE_MS / 1000 });
671
+ continue;
672
+ }
673
+ task = candidate; picked = got; wtName = name; wtPath = treePath;
674
+ }
675
+ if (!task) return lastRefusal;
676
+
677
+ // 5. Work, in that tree.
678
+ const started = Date.now();
679
+ const gradeLedger = deps.gradeLedgerPath ? deps.gradeLedgerPath(task.id) : gradeLedgerPath(task.id);
680
+ // Same client rule as verifyShip below: an injected api is used as given.
681
+ let capApi = deps.api || null;
682
+ if (!capApi) { try { capApi = await (require('./cli-lib').cliClient)(); } catch (_) { capApi = null; } }
683
+ const capCheck = await gradeCapReader({ api: capApi, taskId: task.id, ledger: gradeLedger });
684
+ const res = await spawnWork({ task, model: opts.model, timeoutMs: opts.timeoutMs, cwd: wtPath, gradeLedger, capCheck, deps });
685
+ let verdict = classifyRun(res);
686
+ // 5b. THE GRADE CAP (task 1004536). The owner's rule — a task that fails the
687
+ // grade twice goes to the owner — read from the run's ledger, not from the
688
+ // worker's verdict: the worker was told this in its prompt and kept re-grading.
689
+ const grades = await capCheck();
690
+ try { fs.rmSync(gradeLedger, { force: true }); } catch (_) {} // its counts travel in the run-log row
691
+ if (grades && grades.exhausted) {
692
+ verdict = {
693
+ ...verdict, outcome: 'needs_human', releaseClaim: true,
694
+ reason: `the grade failed ${grades.fails} times in this run — handed to the owner instead of re-graded again (task 1004536)`,
695
+ };
696
+ }
697
+ // Cut off by the usage limit? Recorded here so the NEXT iteration sleeps to the
698
+ // reset instead of spawning a worker that will be cut off the same way.
699
+ const limit = verdict.outcome === 'claims_shipped' ? null : usageLimitHit({ envelope: res.envelope, stderr: res.stderr });
700
+ if (limit) state.limitUntil = limit.resetAt ? limit.resetAt * 1000 : now + LIMIT_UNKNOWN_RESET_MS;
701
+
702
+ // 6. VERIFY FROM THE LEDGER (task 1003903). Read the task back from Bongos and
703
+ // let IT say what happened — for every outcome, not only a claimed ship. The
704
+ // worker's own verdict becomes context in the blocker body, never the branch: a
705
+ // worker that stopped dead needing a decision and one that finished the job
706
+ // return structurally identical envelopes, and the ledger is the only thing
707
+ // that can tell them apart.
708
+ //
709
+ // The release decision moved HERE from the worker's verdict, and that move is
710
+ // the point of the step rather than a tidy-up. `still_held` is a fact about the
711
+ // ledger; `worker_failed` is a report from the thing being checked. The TREE is
712
+ // left alone either way — it may hold committed work, and the land/ship
713
+ // pipeline owns worktree cleanup.
714
+ const ledger = await verifyShip(
715
+ { taskId: task.id, taskTitle: task.title, worker: { outcome: verdict.outcome, reason: verdict.reason } },
716
+ {
717
+ api: deps.api,
718
+ cwd: wtPath,
719
+ release: deps.release || ((id, reason) => runCmd(process.execPath,
720
+ [path.join(REPO_ROOT, 'scripts', 'bongos', 'release.js'), String(id), '--reason', reason], { cwd: wtPath })),
721
+ ...(deps.verifyDeps || {}),
722
+ },
723
+ );
724
+
725
+ const row = {
726
+ event: 'worked', task_id: task.id, title: task.title, goal_id: picked.goalId,
727
+ ...pickedFrom(picked.goalId, gate),
728
+ worktree: wtName,
729
+ outcome: verdict.outcome, reason: verdict.reason,
730
+ session_id: res.sessionId || null, duration_s: Math.round((Date.now() - started) / 1000),
731
+ cost_usd: verdict.costUsd ?? null,
732
+ ...(grades && (grades.graded || grades.outages) ? { grade_rounds: grades.graded, grade_outages: grades.outages, grade_cap_reached: grades.exhausted, grade_count_source: grades.source } : {}),
733
+ output_truncated: !!res.truncated,
734
+ ...(limit ? { usage_limit: { reset_at: limit.resetAt } } : {}),
735
+ undetermined_decisions: verdict.verdict ? verdict.verdict.undetermined_decisions : null,
736
+ // What the LEDGER says, kept separate from what the worker said, so the run
737
+ // log can be read afterwards without having to trust either one alone.
738
+ ledger_status: ledger.status, ledger_shape: ledger.shape, verified: !!ledger.verified,
739
+ // The LEDGER's own explanation, kept beside the worker's. `reason` above is
740
+ // verdict.reason — what the WORKER said happened — and it was the only reason
741
+ // in the row, so anything reading the log afterwards was quoting the thing
742
+ // being checked rather than the check. The morning digest did exactly that
743
+ // until the grader caught it (task 1003906).
744
+ ledger_reason: ledger.reason || null,
745
+ ledger_remedy: ledger.remedy || null,
746
+ artifact_on_main: ledger.artifact && ledger.artifact.checked ? !!ledger.artifact.onMain : null,
747
+ claim_released: !!ledger.released,
748
+ blocker_id: ledger.blocker && ledger.blocker.blockerId ? ledger.blocker.blockerId : null,
749
+ task_parked: !!(ledger.blocker && ledger.blocker.parked),
750
+ };
751
+ // An unreadable ledger stops the run. Picking another task while unable to see
752
+ // what happened to the last one is how a machine nobody is watching digs.
753
+ if (ledger.halt) row.event = 'verify_halt';
754
+ return log(row);
755
+ }
756
+
757
+ // ---------------------------------------------------------------------------
758
+ // Boot recovery, and the forever loop (task 1003904, ADR 0307 §5)
759
+ // ---------------------------------------------------------------------------
760
+
761
+ // reconcileLeftoverClaims — the FIRST thing a run does.
762
+ //
763
+ // "A silently locked task is the worst outcome this loop can produce" is the
764
+ // task's own wording, and cutting power mid-task is exactly how it happens: the
765
+ // claim is held by a session that no longer exists anywhere, and nothing times it
766
+ // out. So before taking any new work, every claim a previous run left behind is
767
+ // read back from the ledger and resolved.
768
+ //
769
+ // The reconciliation is autobongos-verify.js, unchanged (task 1003903). That file
770
+ // already answers "did this actually ship, and if not what do I do about it" for
771
+ // a worker that just exited; a worker that exited three days ago in a power cut
772
+ // is the same question with a longer gap. Writing a second, subtly different
773
+ // answer here is how two code paths end up disagreeing about what `confirmed`
774
+ // means.
775
+ //
776
+ // ONLY TREES THE RUNNER ITSELF MADE, matched against the EXACT shape
777
+ // worktreeName() produces — not a loose prefix.
778
+ //
779
+ // FOUND THE HARD WAY, twice. `autobongos-` as a prefix reads as "ours", and it is
780
+ // not: a person naming a worktree `autobongos-resume-1003904-d29f25` while
781
+ // working on this very feature matched it, and reconciliation released their live
782
+ // claim out from under them. A human at a keyboard picks readable names; the
783
+ // runner picks `autobongos-<task id>-<6 hex>` and nothing else. Matching the
784
+ // generator's own shape is the difference between "probably ours" and "ours".
785
+ //
786
+ // Derived FROM worktreeName so the two cannot drift: change the name format and
787
+ // this regex is what stops the next reconciliation from quietly matching nothing.
788
+ const CLAIM_PREFIX = 'autobongos-';
789
+ const RUNNER_TREE_RE = /^autobongos-\d+-[0-9a-f]{6}$/;
790
+ const isRunnerTree = (name) => RUNNER_TREE_RE.test(String(name || ''));
791
+
792
+ // ── the heartbeat, and why reconciliation needs one ──────────────────────────
793
+ //
794
+ // FOUND BY RUNNING IT. The first live run of reconcileLeftoverClaims released a
795
+ // claim that was very much alive — the one held by the session writing this code.
796
+ // It was right by its own rules (an `autobongos-` tree, a task sitting at
797
+ // `active`), and that is the problem: THE LEDGER CANNOT TELL A LIVE RUN FROM A
798
+ // DEAD ONE. Both look like a held claim. A reconciler that guesses wrong in one
799
+ // direction leaves a task locked forever; in the other it yanks a claim out from
800
+ // under a worker mid-build and strands whatever it had committed.
801
+ //
802
+ // So the runner says, on disk, that it is alive. A heartbeat file carries the pid
803
+ // and a timestamp; reconciliation refuses to touch anything while one is FRESH
804
+ // and its pid still exists. Both halves are needed — a stale file from a power
805
+ // cut must not veto recovery forever, and a fresh file whose process is gone is
806
+ // just litter. This is also what stops two runners on one machine from fighting
807
+ // over each other's claims.
808
+ const HEARTBEAT_STALE_MS = 10 * 60 * 1000;
809
+
810
+ function heartbeatPath() {
811
+ if (process.env.AUTOBONGOS_HEARTBEAT_FILE) return process.env.AUTOBONGOS_HEARTBEAT_FILE;
812
+ try { return require('../../src/instance-config.js').configPath('autobongos-heartbeat.json'); }
813
+ catch (_) { return path.join(REPO_ROOT, '.autobongos-heartbeat.json'); }
814
+ }
815
+
816
+ // Best-effort in both directions: a runner that cannot write its heartbeat must
817
+ // still run (it only loses the guard), and one that cannot read it must assume
818
+ // nothing is alive — the file's absence is the common case, on every first boot.
819
+ //
820
+ // DO NOT point AUTOBONGOS_HEARTBEAT_FILE UNDER /proc TO TEST THE FAILURE PATH (task
821
+ // 1004052). The mkdirSync below is recursive, and on Linux a recursive mkdir under
822
+ // /proc never returns — measured 10s+ with no result, where the same call throws
823
+ // EACCES instantly under /sys or /, and the NON-recursive form throws ENOENT instantly
824
+ // under /proc itself. macOS has no /proc, so it fails fast there. A test that used it
825
+ // was green on every developer machine and hung the Ubuntu CI runner for 90s with no
826
+ // output, reddening `unit` on main and blocking every PR. Use a regular FILE as the
827
+ // parent directory instead: mkdir under it is ENOTDIR immediately, everywhere, and it
828
+ // does not depend on the caller's permissions.
829
+ function writeHeartbeat(now = Date.now(), runnerState = RUNNER_STATE) {
830
+ try {
831
+ const p = heartbeatPath();
832
+ fs.mkdirSync(path.dirname(p), { recursive: true });
833
+ // `head` is what this process is RUNNING, not what is on disk (task 1004374).
834
+ // Alive and alive-on-stale-code look identical from a check-in age alone.
835
+ // `disk_head` appears only when the checkout was refreshed in place past what
836
+ // is running (task 1004406): "up to date on disk, old supervisor" is visible.
837
+ const disk = runnerState && runnerState.diskHead && runnerState.diskHead !== LOADED_HEAD ? runnerState.diskHead : undefined;
838
+ fs.writeFileSync(p, JSON.stringify({ pid: process.pid, at: now, head: LOADED_HEAD, ...(disk ? { disk_head: disk } : {}) }));
839
+ return true;
840
+ } catch (_) { return false; }
841
+ }
842
+
843
+ // postHeartbeat — tell the SERVER we are alive (task 1003905).
844
+ //
845
+ // The file above guards against two runners on this machine; this is the half an
846
+ // owner can see from a web page in another country. Both matter and neither
847
+ // replaces the other: a file is unreadable on exactly the day the machine is off.
848
+ //
849
+ // FAILS SILENTLY, ON PURPOSE. A runner that cannot check in must keep working —
850
+ // letting the watching mechanism take down the thing it watches is a strictly
851
+ // worse outcome than a gap in the log. The gap reports itself anyway: the hall
852
+ // reads the AGE of the last check-in, so a failed post shows up as silence, which
853
+ // is the signal.
854
+ const RUNNER_STARTED_AT = new Date().toISOString();
855
+
856
+ // claudeAccountLabel — WHICH Claude account this machine's workers spend
857
+ // (task 1004407), as a label and never a secret. Workers inherit
858
+ // ANTHROPIC_API_KEY and CLAUDE_CODE_OAUTH_TOKEN from this process
859
+ // (WORKER_ENV_ALLOW), and either one outranks the stored login, so those are
860
+ // named first, by the variable that is set and never by its value. Otherwise it
861
+ // is the login Claude Code itself records in ~/.claude.json (oauthAccount): the
862
+ // email, plus the organisation when it has one. Read on every beat, so signing
863
+ // a different account in shows up without a restart; null when nothing can be
864
+ // read, which the card leaves blank rather than guessing.
865
+ function claudeAccountLabel({ env = process.env, readFile = (p) => fs.readFileSync(p, 'utf8') } = {}) {
866
+ if (env.ANTHROPIC_API_KEY) return 'an API key (ANTHROPIC_API_KEY)';
867
+ if (env.CLAUDE_CODE_OAUTH_TOKEN) return 'a Claude token (CLAUDE_CODE_OAUTH_TOKEN)';
868
+ try {
869
+ const dir = env.CLAUDE_CONFIG_DIR || os.homedir();
870
+ const acct = JSON.parse(readFile(path.join(dir, '.claude.json'))).oauthAccount || {};
871
+ const email = typeof acct.emailAddress === 'string' ? acct.emailAddress.trim() : '';
872
+ if (!email) return null;
873
+ const org = typeof acct.organizationName === 'string' ? acct.organizationName.trim() : '';
874
+ return (org ? `${email} · ${org}` : email).slice(0, 200);
875
+ } catch (_) { return null; }
876
+ }
877
+
878
+ // heartbeatIdentity — the fields that say which code and which account (task
879
+ // 1004407). Undefined fields are dropped, so a runner that cannot read its own
880
+ // commit sends nothing for it rather than an empty string the route would refuse.
881
+ function heartbeatIdentity(deps = {}) {
882
+ const st = deps.state || RUNNER_STATE;
883
+ const out = {
884
+ head: LOADED_HEAD || undefined,
885
+ disk_head: st.diskHead && st.diskHead !== LOADED_HEAD ? st.diskHead : undefined,
886
+ main_head: st.mainHead || undefined,
887
+ claude_account: (deps.claudeAccountLabel || claudeAccountLabel)() || undefined,
888
+ };
889
+ for (const k of Object.keys(out)) if (out[k] === undefined) delete out[k];
890
+ return out;
891
+ }
892
+
893
+ async function postHeartbeat(fields = {}, deps = {}) {
894
+ try {
895
+ const api = deps.api || await (require('./cli-lib').cliClient)();
896
+ await api.autonomy.postAutonomyHeartbeat({
897
+ body: {
898
+ host: os.hostname(),
899
+ pid: process.pid,
900
+ started_at: RUNNER_STARTED_AT,
901
+ ...heartbeatIdentity(deps),
902
+ ...fields,
903
+ },
904
+ });
905
+ return true;
906
+ } catch (_) { return false; }
907
+ }
908
+
909
+ function readHeartbeat() {
910
+ try { return JSON.parse(fs.readFileSync(heartbeatPath(), 'utf8')); }
911
+ catch (_) { return null; }
912
+ }
913
+
914
+ // pidAlive — `kill(pid, 0)` signals nothing and throws ESRCH when the process is
915
+ // gone. EPERM means it exists and belongs to someone else, which still counts as
916
+ // alive: the question is "is something running", not "is it mine".
917
+ function pidAlive(pid) {
918
+ if (!Number.isInteger(pid) || pid <= 0) return false;
919
+ try { process.kill(pid, 0); return true; }
920
+ catch (e) { return e && e.code === 'EPERM'; }
921
+ }
922
+
923
+ // anotherRunnerIsAlive — the veto. Fresh file AND a live pid AND not us.
924
+ function anotherRunnerIsAlive({ now = Date.now(), hb = readHeartbeat() } = {}) {
925
+ if (!hb || !Number.isFinite(Number(hb.at))) return false;
926
+ if (Number(hb.pid) === process.pid) return false; // our own beat
927
+ if (now - Number(hb.at) > HEARTBEAT_STALE_MS) return false; // a power cut leaves a stale file
928
+ return pidAlive(Number(hb.pid));
929
+ }
930
+
931
+ async function reconcileLeftoverClaims(deps = {}) {
932
+ const api = deps.api || await (require('./cli-lib').cliClient)();
933
+ const log = deps.record || record;
934
+ const verify = deps.verifyShip || verifyShip;
935
+ const runCmd = deps.run || run;
936
+ const isAlive = deps.anotherRunnerIsAlive || anotherRunnerIsAlive;
937
+
938
+ // Refuse outright while another runner is beating. Releasing a claim a live
939
+ // worker is building against strands whatever it has committed — the same harm
940
+ // as leaving one locked, pointed the other way.
941
+ if (isAlive()) return log({ event: 'boot_reconcile', ok: true, skipped: 'another runner is alive', leftover: null });
942
+
943
+ let claims = [];
944
+ try {
945
+ const me = await api.me.getMe();
946
+ if (!me || !me.ok) return log({ event: 'boot_reconcile', ok: false, reason: `GET /me → ${me ? me.status : 'no response'}` });
947
+ claims = (me.data.active_claims || []).filter((c) => isRunnerTree(c.worktree_name));
948
+ } catch (e) {
949
+ // Unreadable is NOT "nothing to reconcile". Say so and let the cadence treat
950
+ // it as a failure, rather than starting work on top of an unknown lock.
951
+ return log({ event: 'boot_reconcile', ok: false, reason: e && e.message ? e.message : String(e) });
952
+ }
953
+
954
+ if (!claims.length) return log({ event: 'boot_reconcile', ok: true, leftover: 0 });
955
+
956
+ const resolved = [];
957
+ for (const c of claims) {
958
+ const wtPath = path.join(REPO_ROOT, '.claude', 'worktrees', c.worktree_name);
959
+ const out = await verify(
960
+ { taskId: c.task_id, taskTitle: c.title, worker: { outcome: 'interrupted', reason: 'a previous run did not finish this claim' } },
961
+ {
962
+ api,
963
+ // The tree may be gone — a power cut leaves the claim, not necessarily the
964
+ // checkout. verifyShip only uses cwd for the artifact probe, which degrades
965
+ // to `checked: false` rather than failing, so a missing path is survivable.
966
+ cwd: fs.existsSync(wtPath) ? wtPath : REPO_ROOT,
967
+ release: (id, reason) => runCmd(process.execPath,
968
+ [path.join(REPO_ROOT, 'scripts', 'bongos', 'release.js'), String(id), '--reason', reason],
969
+ { cwd: fs.existsSync(wtPath) ? wtPath : REPO_ROOT }),
970
+ },
971
+ );
972
+ resolved.push({ task_id: String(c.task_id), worktree: c.worktree_name, shape: out.shape, released: !!out.released, blocker_id: out.blocker?.blockerId ?? null });
973
+ }
974
+ return log({ event: 'boot_reconcile', ok: true, leftover: claims.length, resolved });
975
+ }
976
+
977
+ // pollSignals — the cheap facts whose change makes waiting pointless.
978
+ //
979
+ // Three reads, all small, all failing SILENTLY to null. A failed probe is not a
980
+ // signal: treating it as one would turn an unreachable instance into a busy loop
981
+ // hammering it, which is the exact opposite of backing off.
982
+ async function pollSignals(deps = {}) {
983
+ const api = deps.api || await (require('./cli-lib').cliClient)();
984
+ let head = null; let fenceUpdatedAt = null; let claimableCount = null;
985
+ try {
986
+ const r = await runFetchHead(deps);
987
+ if (r) head = r;
988
+ } catch (_) { /* null */ }
989
+ try {
990
+ const f = await api.autonomy.getAutonomyFence();
991
+ if (f && f.ok) fenceUpdatedAt = f.data.updated_at || null;
992
+ } catch (_) { /* null */ }
993
+ try {
994
+ const ids = await seq.fetchClaimableIds(api);
995
+ if (ids) claimableCount = ids.size;
996
+ } catch (_) { /* null */ }
997
+ return cadence.signalFingerprint({ head, fenceUpdatedAt, claimableCount });
998
+ }
999
+
1000
+ // UPGRADE_EXIT_CODE — the one exit `--forever` is allowed to make (task 1004374).
1001
+ //
1002
+ // THE PROBLEM. autobongos-service.cmd refreshes the checkout with git fetch +
1003
+ // reset --hard origin/main BEFORE launching node, and only then. `--forever`
1004
+ // never returns, by design (task 1003904): a stopped daemon on an always-on
1005
+ // machine is indistinguishable from a working one. Together those mean a
1006
+ // process never re-reads its code, so a shipped fix reaches the disk and never
1007
+ // reaches the runner, and nothing restarts it — not stopping IS the design. On
1008
+ // the host this ran week-old code for four days across three landed fixes,
1009
+ // while the heartbeat said alive and the hall showed a healthy runner.
1010
+ //
1011
+ // WHY AN EXIT IS SAFE HERE, when task 1003904 forbids exiting. That rule exists
1012
+ // so a machine nobody watches cannot look idle while it is dead. This exit is
1013
+ // the opposite: it is deliberate, it is logged as `upgrade_exit`, and the
1014
+ // WRAPPER loops on this specific code — re-running the fetch + reset and
1015
+ // relaunching — so the runner is not depending on Task Scheduler noticing.
1016
+ // Every other exit still falls through to the scheduler exactly as before.
1017
+ const UPGRADE_EXIT_CODE = 75;
1018
+
1019
+ // MIN_UPTIME_BEFORE_UPGRADE_MS — the guard against a restart storm.
1020
+ //
1021
+ // The wrapper's `git reset --hard origin/main` is BEST EFFORT: a fetch that
1022
+ // fails leaves the checkout behind on purpose, because being a commit behind
1023
+ // beats not running at all. Without this guard that becomes a spin — the runner
1024
+ // starts behind, sees drift on its first loop, exits, and the wrapper relaunches
1025
+ // it into the same state as fast as the machine allows. One minute of required
1026
+ // uptime turns a failing fetch into a slow retry instead.
1027
+ const MIN_UPTIME_BEFORE_UPGRADE_MS = 60_000;
1028
+
1029
+ // loadedHead — the commit this PROCESS is running, read once. Not re-read: the
1030
+ // point is to compare what is executing against what has landed, and re-reading
1031
+ // would just track the disk, which the wrapper already moves.
1032
+ let LOADED_HEAD = null;
1033
+ async function loadedHead(deps = {}) {
1034
+ if (LOADED_HEAD !== null) return LOADED_HEAD;
1035
+ const runCmd = deps.run || run;
1036
+ try {
1037
+ const r = await runCmd('git', ['rev-parse', 'HEAD'], { cwd: REPO_ROOT });
1038
+ LOADED_HEAD = r && r.ok ? String(r.stdout || '').trim() || null : null;
1039
+ } catch (_) { LOADED_HEAD = null; }
1040
+ return LOADED_HEAD;
1041
+ }
1042
+
1043
+ // codeDrifted — has main moved past the code this process loaded?
1044
+ //
1045
+ // Fails CLOSED in the "keep running" direction: an unreadable local head or an
1046
+ // unreachable origin returns false, so a network blip never cycles the runner.
1047
+ // The cost of a missed upgrade is one more loop; the cost of a false positive is
1048
+ // a restart storm.
1049
+ async function codeDrifted(deps = {}) {
1050
+ // Injectable like every other collaborator here: the module-level cache is
1051
+ // right for production (read the running commit ONCE) and would otherwise make
1052
+ // the comparison untestable in isolation.
1053
+ const mine = deps.loadedHead ? await deps.loadedHead(deps) : await loadedHead(deps);
1054
+ if (!mine) return null;
1055
+ // Measured from what is on DISK once the checkout has been refreshed in place
1056
+ // (task 1004406), or every loop after a refresh would see the same drift again.
1057
+ const base = ((deps.state || RUNNER_STATE).diskHead) || mine;
1058
+ let tip = null;
1059
+ try { tip = await runFetchHead(deps); } catch (_) { return null; }
1060
+ if (!tip) return null;
1061
+ // Kept for the heartbeat (task 1004407), so the hall can say "behind main"
1062
+ // without the server ever reaching GitHub itself.
1063
+ (deps.state || RUNNER_STATE).mainHead = tip;
1064
+ return tip !== base ? { from: base.slice(0, 8), to: String(tip).slice(0, 8) } : false;
1065
+ }
1066
+
1067
+ // ── pull always, restart rarely (task 1004406) ──────────────────────────────
1068
+ //
1069
+ // Owner-approved 2026-09-30. Main moves every time ANY session lands, and a
1070
+ // relaunch per merge meant a busy day of restarts (four in fourteen minutes on
1071
+ // 2026-09-29). But a restart only refreshes code THIS process holds in memory:
1072
+ // every worker, and every claim.js / worktree.js / release.js the loop shells
1073
+ // out to, is a fresh process that runs whatever is on disk. So on drift the
1074
+ // checkout is updated in place, and the process exits for the wrapper only when
1075
+ // a change touches code it has actually loaded.
1076
+ //
1077
+ // SUPERVISOR_PATH_RES catch the supervisor's own files even before they are
1078
+ // required (autobongos-verify.js is loaded lazily on the first ship), so a change
1079
+ // to a file the loop is ABOUT to load cannot mix old callers with a new callee.
1080
+ const SUPERVISOR_PATH_RES = [/^scripts\/(?:gds|bongos)\/autobongos-[^/]+$/, /^modules\/autonomy\//];
1081
+
1082
+ // The repo files this process has loaded, repo-relative with forward slashes.
1083
+ function loadedFiles() {
1084
+ const root = REPO_ROOT + path.sep;
1085
+ const nm = path.sep + 'node_modules' + path.sep;
1086
+ return Object.keys(require.cache)
1087
+ .filter((p) => p.startsWith(root) && !p.includes(nm))
1088
+ .map((p) => path.relative(REPO_ROOT, p).split(path.sep).join('/'));
1089
+ }
1090
+
1091
+ // The changed files that force a restart: ones this process holds, or ones under
1092
+ // the supervisor's own paths. Everything else is picked up by the next child.
1093
+ function supervisorTouched(changed = [], loaded = loadedFiles()) {
1094
+ const held = new Set(loaded);
1095
+ return changed.filter((f) => held.has(f) || SUPERVISOR_PATH_RES.some((re) => re.test(f)));
1096
+ }
1097
+
1098
+ // refreshCheckout — the wrapper's fetch + reset, done from inside the process.
1099
+ //
1100
+ // THE MAIN CHECKOUT ONLY. It runs `git reset --hard`, and a linked worktree is a
1101
+ // claim somebody is building in; resetting one would destroy their work. The
1102
+ // check compares git-dir to git-common-dir, which are equal only in the main
1103
+ // checkout. Armed only by main() (`opts.refreshInPlace`), so a test driving
1104
+ // forever() can never reach it — in CI that reset would wipe the code under test.
1105
+ //
1106
+ // The diff is from the LOADED commit, not the last refresh, so a supervisor
1107
+ // change that landed several refreshes ago still forces the restart it needs.
1108
+ async function refreshCheckout(deps = {}) {
1109
+ const runCmd = deps.run || run;
1110
+ const git = (args) => runCmd('git', args, { cwd: REPO_ROOT });
1111
+ try {
1112
+ const [gd, cd] = await Promise.all([git(['rev-parse', '--git-dir']), git(['rev-parse', '--git-common-dir'])]);
1113
+ if (!gd.ok || !cd.ok) return { ok: false, reason: 'could not tell which checkout this is' };
1114
+ if (path.resolve(REPO_ROOT, String(gd.stdout).trim()) !== path.resolve(REPO_ROOT, String(cd.stdout).trim())) {
1115
+ return { ok: false, reason: 'not the main checkout — refusing to reset a linked worktree' };
1116
+ }
1117
+ const loaded = deps.loadedHead ? await deps.loadedHead(deps) : await loadedHead(deps);
1118
+ if (!loaded) return { ok: false, reason: 'the running commit is unknown' };
1119
+ if (!(await git(['fetch', '--quiet', 'origin', 'main'])).ok) return { ok: false, reason: 'fetch failed' };
1120
+ const fh = await git(['rev-parse', 'FETCH_HEAD']);
1121
+ const to = fh.ok ? String(fh.stdout).trim() : '';
1122
+ if (!/^[0-9a-f]{40}$/.test(to)) return { ok: false, reason: 'could not read the fetched commit' };
1123
+ const diff = await git(['diff', '--name-only', loaded, to]);
1124
+ if (!diff.ok) return { ok: false, reason: 'could not diff the running commit against main' };
1125
+ if (!(await git(['reset', '--quiet', '--hard', to])).ok) return { ok: false, reason: 'reset failed' };
1126
+ const changed = String(diff.stdout).split(/\r?\n/).map((l) => l.trim()).filter(Boolean);
1127
+ return { ok: true, to, changed };
1128
+ } catch (e) {
1129
+ return { ok: false, reason: e && e.message ? e.message : String(e) };
1130
+ }
1131
+ }
1132
+
1133
+ // The head of origin/main, or null. `git ls-remote` rather than `fetch`: it moves
1134
+ // no refs and writes nothing, so polling it every few minutes cannot interfere
1135
+ // with a worker building in a tree beside it.
1136
+ async function runFetchHead(deps = {}) {
1137
+ const runCmd = deps.run || run;
1138
+ const r = await runCmd('git', ['ls-remote', 'origin', 'refs/heads/main']);
1139
+ if (!r.ok) return null;
1140
+ const m = /^([0-9a-f]{40})/.exec(String(r.stdout).trim());
1141
+ return m ? m[1] : null;
1142
+ }
1143
+
1144
+ // waitOrJump — sleep, but wake early if the world moved.
1145
+ //
1146
+ // Polls at most every `pollEveryS`, so a thirty-minute backoff costs six cheap
1147
+ // probes rather than a spin. `sleep` is injected so a test can drive an hour of
1148
+ // wall clock in a millisecond.
1149
+ async function waitOrJump(waitS, deps = {}, cfg = {}) {
1150
+ if (!(waitS > 0)) return { waited: 0, jumped: false };
1151
+ const pollEveryS = cfg.pollEveryS ?? 60;
1152
+ const sleep = deps.sleep || ((ms) => new Promise((r) => setTimeout(r, ms)));
1153
+ const poll = deps.pollSignals || pollSignals;
1154
+
1155
+ const before = await poll(deps);
1156
+ let waited = 0;
1157
+ while (waited < waitS) {
1158
+ const chunk = Math.min(pollEveryS, waitS - waited);
1159
+ await sleep(chunk * 1000);
1160
+ waited += chunk;
1161
+ // Beat DURING the wait. A thirty-minute backoff is the runner working exactly
1162
+ // as designed, and it must not be indistinguishable from a machine that fell
1163
+ // over at the start of it.
1164
+ if (deps.beat) { try { await deps.beat({ last_event: 'waiting' }); } catch (_) { /* never break a wait */ } }
1165
+ if (waited >= waitS) break;
1166
+ const now = await poll(deps);
1167
+ if (cadence.shouldJumpWait(before, now)) return { waited, jumped: true, signal: now };
1168
+ }
1169
+ return { waited, jumped: false };
1170
+ }
1171
+
1172
+ // forever — the loop that has no terminal stop (task 1003904, ADR 0307 §5).
1173
+ //
1174
+ // It is a `while (true)` on purpose and the exceptions are the interesting part:
1175
+ // NOTHING in here returns. Not an unreachable instance, not an expired token, not
1176
+ // the kill switch. The only exits are a signal from the operating system and
1177
+ // `--max-loops`, which exists so a test can run the machine to completion.
1178
+ //
1179
+ // What varies is the SPEED, and the speed is decided entirely by
1180
+ // modules/autonomy/cadence.js from the row the last iteration recorded. This
1181
+ // function holds no policy — it turns a `waitS` into a wait and a `takeWork` into
1182
+ // an iteration, so the rules stay somewhere a test can reach without a clock.
1183
+ async function forever(opts, deps = {}) {
1184
+ const log = deps.record || record;
1185
+ const iterate = deps.iteration || iteration;
1186
+ const reconcile = deps.reconcileLeftoverClaims || reconcileLeftoverClaims;
1187
+ const wait = deps.waitOrJump || waitOrJump;
1188
+ const emit = deps.emit || ((row) => {
1189
+ if (opts.json) console.log(JSON.stringify(row));
1190
+ else console.log(`${row.event}${row.task_id ? ` task ${row.task_id}` : ''}${row.outcome ? ` → ${row.outcome}` : ''}${row.reason ? `: ${row.reason}` : ''}`);
1191
+ });
1192
+
1193
+ // Claim the machine BEFORE reconciling: a second runner starting a moment later
1194
+ // must see this one alive rather than deciding its claims are litter.
1195
+ // Both halves of "I am alive": the local file (which stops a second runner
1196
+ // treating this one's claims as litter) and the server row (which is the only
1197
+ // one an owner can see from anywhere else).
1198
+ const beatFile = deps.writeHeartbeat || writeHeartbeat;
1199
+ const beatServer = deps.postHeartbeat || postHeartbeat;
1200
+ // WRAPPED AT THE CALL SITE, not just inside postHeartbeat. The guarantee is
1201
+ // "reporting that I am alive can never be what kills me", and that has to hold
1202
+ // for whatever beat implementation is in play — a future one, an injected one —
1203
+ // not only for the well-behaved default. Letting the watching mechanism take
1204
+ // down the thing it watches is strictly worse than a gap in the log, and the gap
1205
+ // reports itself anyway: the hall reads the AGE of the last check-in, so a
1206
+ // failed beat shows up as silence, which is the signal.
1207
+ // How long this runner has been idle on a setting the owner can fix (task
1208
+ // 1004539). Past that setting's grace, every beat that is not about a task says
1209
+ // `config_idle:<code>` instead of "waiting", so the hall shows the fix rather
1210
+ // than "alive" for ten hours. Any row that is not that refusal ends the stretch.
1211
+ let idle = null;
1212
+ const clock = () => (deps.now ? deps.now() : Date.now());
1213
+ const beat = async (rawFields) => {
1214
+ const fields = configIdle.markBeat(rawFields, idle, clock());
1215
+ // The runner state is passed, not defaulted: the file names `disk_head` from
1216
+ // it (task 1004406), and an injected state must reach the beat that reports it.
1217
+ try { beatFile(Date.now(), deps.state || RUNNER_STATE); } catch (_) { /* a runner that cannot write its file still runs */ }
1218
+ try { await beatServer(fields, deps); } catch (_) { /* and one that cannot reach the instance still runs */ }
1219
+ };
1220
+ // The running commit, read ONCE, BEFORE the first beat (task 1004397). It used
1221
+ // to be read lazily by codeDrifted(), which sits behind the one-minute uptime
1222
+ // floor, so every beat in a process's first minute said head:null — the window
1223
+ // in which a crash-looping or repeatedly-restarted runner is being looked at.
1224
+ // The floor exists to stop a restart STORM, not to avoid this read: one local
1225
+ // rev-parse. Fails soft to null inside loadedHead(), and a null is retried by
1226
+ // the drift check later, so an unreadable head never stops the runner.
1227
+ try { await (deps.loadedHead ? deps.loadedHead(deps) : loadedHead(deps)); } catch (_) { /* head stays null */ }
1228
+ await beat({ last_event: 'boot' });
1229
+
1230
+ // BEFORE ANY WORK. A claim left locked by a previous run is the worst thing
1231
+ // this loop produces, and taking new work on top of one compounds it.
1232
+ emit(await reconcile(deps));
1233
+
1234
+ let state = { ...cadence.START };
1235
+ const maxLoops = Number.isFinite(Number(opts.maxLoops)) ? Number(opts.maxLoops) : Infinity;
1236
+
1237
+ for (let loop = 0; loop < maxLoops; loop++) {
1238
+ // Every loop, so a crash leaves a heartbeat that goes stale on its own — the
1239
+ // runner never has to notice it is dying for its death to become visible.
1240
+ await beat({ mode: state.mode, consecutive_failures: state.consecutiveFailures, last_event: 'loop' });
1241
+ // Slow lands (task 1004538): re-probe shipped tasks still waiting on main, and
1242
+ // close no-artifact blockers whose commit has since landed. Armed only by
1243
+ // main() (or an injected stub), like refreshInPlace, so no test harness that
1244
+ // predates it can fall through to the network. It can never stop the loop.
1245
+ if (opts.recheckLands || deps.recheckLands) {
1246
+ try { await (deps.recheckLands || recheckPendingLands)(deps); } catch (e) {
1247
+ log({ event: 'land_recheck_failed', errors: [e && e.message ? e.message : String(e)] });
1248
+ }
1249
+ }
1250
+ // In `probing` the runner takes exactly ONE task and only after its wait, so
1251
+ // a broken window costs a handful of cheap requests rather than a night of
1252
+ // failing spawns. `maxTasks` still bounds a full-speed burst.
1253
+ const budget = state.mode === 'probing' ? 1 : opts.maxTasks;
1254
+ let row = null;
1255
+
1256
+ for (let i = 0; i < budget; i++) {
1257
+ row = await iterate(opts, deps);
1258
+ emit(row);
1259
+ idle = configIdle.trackIdle(idle, row, clock());
1260
+ // Carry the task id so the hall can tell "quiet because it is building
1261
+ // task 1234" from "quiet because it is dead". A worker may hold the loop for
1262
+ // ninety minutes, and without this every honest hour of work looks like a
1263
+ // corpse.
1264
+ await beat({ mode: state.mode, last_event: row.event, working_task_id: Number(row.task_id) || undefined, working_goal_id: Number(row.goal_id) || undefined });
1265
+ const seen = cadence.classifyEvent(row);
1266
+ // A hold that names its reset SECOND waits until that second (task 1004454).
1267
+ // classifyEvent carries it as an absolute epoch; the cadence has no clock of
1268
+ // its own, so the conversion to a wait lives here beside the one clock read.
1269
+ // Without it every hold waited the fixed idle and the "wake at the reset"
1270
+ // the goal asks for was only ever as accurate as the poll.
1271
+ if (Number.isFinite(Number(seen.sleepUntil)) && seen.sleepUntil !== null) {
1272
+ const nowS = Math.floor((deps.now ? deps.now() : Date.now()) / 1000);
1273
+ seen.sleepUntilS = Math.max(0, Number(seen.sleepUntil) - nowS);
1274
+ }
1275
+ state = cadence.nextCadence(state, seen, opts.cadence);
1276
+ log({ event: 'cadence', mode: state.mode, consecutive_failures: state.consecutiveFailures, wait_s: state.waitS, class: seen.class, why: state.why });
1277
+ // A burst continues only while work is actually landing. Anything else ends
1278
+ // the burst and hands the decision to the cadence, which is the only thing
1279
+ // allowed to say how long to wait.
1280
+ if (seen.class !== 'progress') break;
1281
+ }
1282
+
1283
+ // AFTER the burst, never during one: a worker mid-task must not be abandoned
1284
+ // to pick up a fix. Before the wait, because waiting is where the runner
1285
+ // spends nearly all of its time and an upgrade should not sit behind it.
1286
+ const upMs = (deps.now ? deps.now() : Date.now()) - Date.parse(RUNNER_STARTED_AT);
1287
+ const mayUpgrade = upMs >= MIN_UPTIME_BEFORE_UPGRADE_MS;
1288
+ let drift = mayUpgrade
1289
+ ? (deps.codeDrifted ? await deps.codeDrifted(deps) : await codeDrifted(deps))
1290
+ : false;
1291
+ if (drift) {
1292
+ // Pull always, restart rarely (task 1004406). Only main() arms the refresh.
1293
+ let why = 'exiting so the wrapper can relaunch on the new code';
1294
+ if (opts.refreshInPlace) {
1295
+ const refreshed = await (deps.refreshCheckout || refreshCheckout)(deps);
1296
+ if (refreshed && refreshed.ok) {
1297
+ const touched = supervisorTouched(refreshed.changed, deps.loadedFiles ? deps.loadedFiles() : loadedFiles());
1298
+ if (!touched.length) {
1299
+ (deps.state || RUNNER_STATE).diskHead = refreshed.to;
1300
+ log({ event: 'code_refreshed', from: drift.from, to: refreshed.to.slice(0, 8), changed: refreshed.changed.length,
1301
+ reason: `main moved from ${drift.from} to ${refreshed.to.slice(0, 8)} — checkout updated in place; none of the ${refreshed.changed.length} changed file(s) is code this process runs, so no restart` });
1302
+ await beat({ mode: state.mode, last_event: 'code_refreshed' });
1303
+ drift = null;
1304
+ } else {
1305
+ const more = touched.length > 5 ? `, +${touched.length - 5} more` : '';
1306
+ why = `it changed code this process runs (${touched.slice(0, 5).join(', ')}${more}) — exiting so the wrapper can relaunch on it`;
1307
+ }
1308
+ } else {
1309
+ why = `the in-place refresh did not run (${(refreshed && refreshed.reason) || 'no result'}) — exiting so the wrapper's own refresh can`;
1310
+ }
1311
+ }
1312
+ if (drift) {
1313
+ log({ event: 'upgrade_exit', from: drift.from, to: drift.to, reason: `main moved from ${drift.from} to ${drift.to} — ${why}` });
1314
+ await beat({ mode: state.mode, last_event: 'upgrade_exit' });
1315
+ return UPGRADE_EXIT_CODE;
1316
+ }
1317
+ }
1318
+
1319
+ const { waited, jumped } = await wait(state.waitS, { ...deps, beat }, opts.cadence);
1320
+ if (jumped) log({ event: 'cadence', mode: state.mode, jumped: true, waited_s: waited, why: 'a new signal arrived — main moved, the fence changed, or the queue did' });
1321
+ }
1322
+ return 0;
1323
+ }
1324
+
1325
+ async function main(argv) {
1326
+ const opts = readArgv(argv);
1327
+ // No "name a goal" refusal here any more. It used to be the only allowlist, and
1328
+ // it lived on the machine being fenced; the database owns that now, and an empty
1329
+ // `--goal` means "every allowlisted goal" rather than "anything claimable". The
1330
+ // refusal did not disappear — it moved somewhere the runner host cannot edit.
1331
+ if (opts.forever) return forever({ ...opts, refreshInPlace: true, recheckLands: true });
1332
+
1333
+ // The one-shot path, kept for an operator running a single task by hand. It
1334
+ // still reconciles first: a leftover claim is a leftover claim whoever is
1335
+ // watching.
1336
+ const boot = await reconcileLeftoverClaims();
1337
+ if (opts.json) console.log(JSON.stringify(boot));
1338
+ for (let i = 0; i < opts.maxTasks; i++) {
1339
+ const row = await iteration(opts);
1340
+ if (opts.json) console.log(JSON.stringify(row));
1341
+ else console.log(`${row.event}${row.task_id ? ` task ${row.task_id}` : ''}${row.outcome ? ` → ${row.outcome}` : ''}${row.reason ? `: ${row.reason}` : ''}`);
1342
+ if (row.event !== 'worked') break;
1343
+ }
1344
+ return 0;
1345
+ }
1346
+
1347
+ if (require.main === module) {
1348
+ main(process.argv.slice(2)).then((c) => process.exit(c)).catch((e) => {
1349
+ console.error(`autobongos-run: ${e && e.message ? e.message : e}`);
1350
+ process.exit(1);
1351
+ });
1352
+ }
1353
+
1354
+ module.exports = {
1355
+ readArgv, pickTask, iteration, record, logPath, spawnWorker, workerEnv, WORKER_ENV_ALLOW, resolveWorkerBin,
1356
+ worktreeName, readFence, gradeLedgerPath, gradeCapReader, reconcileLeftoverClaims, pollSignals, waitOrJump, forever, CLAIM_PREFIX, codeDrifted, loadedHead, UPGRADE_EXIT_CODE, MIN_UPTIME_BEFORE_UPGRADE_MS,
1357
+ heartbeatPath, writeHeartbeat, readHeartbeat, pidAlive, anotherRunnerIsAlive, HEARTBEAT_STALE_MS,
1358
+ isRunnerTree, RUNNER_TREE_RE, postHeartbeat, claudeAccountLabel, RUNNER_STARTED_AT, failureReason,
1359
+ newRunnerState, loadedFiles, supervisorTouched, refreshCheckout, LIMIT_UNKNOWN_RESET_MS, QUEUE_GATED_EXIT, CLAIM_SET_ASIDE_MS, MAX_CLAIM_ATTEMPTS, owedTaskIds,
1360
+ readRunLogRows, recheckPendingLands, LAND_SWEEP_MS,
1361
+ };