@bongos/core 1.19.1073 → 1.19.1075

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 (377) hide show
  1. package/.bongos-core.json +404 -549
  2. package/.claude/skills/feedback/SKILL.md +2 -2
  3. package/bin/bongos.js +1 -3
  4. package/clients/bongos-client/README.md +1 -1
  5. package/clients/bongos-client/bongos-client.global.js +4 -60
  6. package/clients/bongos-client/index.cjs +4 -60
  7. package/clients/bongos-client/index.d.ts +5 -90
  8. package/clients/bongos-client/index.mjs +4 -60
  9. package/config/branding.neutral.json +1 -5
  10. package/config/modules.neutral.json +2 -3
  11. package/config/scheduled-routines.json +0 -2
  12. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +1 -0
  13. package/docs/adr/0285-a-shared-box-holds-about-twelve-projects-per-gb-and-memory-is-the-wall.md +1 -0
  14. package/docs/adr/0323-hosting-is-three-shapes-and-we-are-not-the-landlord.md +1 -1
  15. package/docs/adr/0327-a-cloud-host-runs-on-the-owners-account-and-the-key-is-borrowed.md +1 -1
  16. package/docs/adr/0341-the-page-is-the-unit-of-tweak-mode.md +2 -0
  17. package/docs/adr/0345-we-host-every-projects-hall-and-its-app-deploys-where-the-owner-chooses.md +94 -0
  18. package/docs/adr/README.md +1 -0
  19. package/docs/api/openapi.json +175 -1665
  20. package/docs/api-reference.md +9 -41
  21. package/docs/architecture.md +16 -1
  22. package/docs/branding-contract.md +0 -3
  23. package/docs/copy-inventory.md +454 -479
  24. package/docs/copy-registry.json +746 -978
  25. package/docs/file-map.md +5 -34
  26. package/docs/module-api-changelog.md +4 -0
  27. package/docs/modules-contract.md +13 -1
  28. package/docs/onboarding/diagrams/04-architecture.mmd +11 -22
  29. package/docs/onboarding/diagrams/README.md +3 -3
  30. package/docs/onboarding/diagrams/assertions.json +2 -22
  31. package/docs/onboarding/primer.md +9 -28
  32. package/docs/page-inventory.json +4 -1
  33. package/docs/page-readings.json +1032 -1077
  34. package/docs/recipes/render-pilot.md +29 -10
  35. package/migrations/core_257_module_store_registry.sql +87 -0
  36. package/migrations/core_258_drop_dev_box_tables.sql +55 -0
  37. package/modules/agents/module.json +1 -0
  38. package/modules/autonomy/module.json +1 -0
  39. package/modules/builder-settings/module.json +1 -0
  40. package/modules/builder-settings/render-prefs.js +4 -5
  41. package/modules/copy-desk/docx.js +78 -5
  42. package/modules/copy-desk/module.json +1 -0
  43. package/modules/copy-desk/routes/copy-desk.js +10 -10
  44. package/modules/copy-desk/tests/copy_docx.mjs +107 -1
  45. package/modules/copy-desk/tests/fixtures/word-docx.mjs +30 -0
  46. package/modules/discord/module.json +1 -0
  47. package/modules/discord/ship-broadcast.js +3 -3
  48. package/modules/economy/credits.js +2 -2
  49. package/modules/economy/module.json +1 -0
  50. package/modules/economy/routes/credits.js +1 -2
  51. package/modules/government/catalog.js +13 -17
  52. package/modules/government/migrations/government_019_retire_box_permissions.sql +33 -0
  53. package/modules/government/module.json +1 -0
  54. package/modules/government/protected-surfaces.json +3 -11
  55. package/modules/government/resolver.js +3 -46
  56. package/modules/government/routes/government.js +0 -2
  57. package/modules/government/session-scopes.js +43 -83
  58. package/modules/government/session-scopes.json +8 -18
  59. package/modules/grading/module.json +1 -0
  60. package/modules/hall-ui/module.json +1 -0
  61. package/modules/hall-ui/public/board-lib.js +2 -2
  62. package/modules/hall-ui/public/builders.js +29 -40
  63. package/modules/hall-ui/public/collab.html +1 -1
  64. package/modules/hall-ui/public/collab.js +1 -1
  65. package/modules/hall-ui/public/diagrams.html +3 -3
  66. package/modules/hall-ui/public/dom-utils.js +1 -1
  67. package/modules/hall-ui/public/gate.js +2 -2
  68. package/modules/hall-ui/public/gate.states.json +1 -1
  69. package/modules/hall-ui/public/hall-render.js +43 -79
  70. package/modules/hall-ui/public/index.html +5 -1
  71. package/modules/hall-ui/public/modules.js +1 -0
  72. package/modules/hall-ui/public/oversight.css +5 -5
  73. package/modules/hall-ui/public/palette.js +0 -11
  74. package/modules/hall-ui/public/primer.js +1 -1
  75. package/modules/hall-ui/public/sessions.html +1 -1
  76. package/modules/hall-ui/public/settings-sessions.js +1 -1
  77. package/modules/hall-ui/public/settings.css +0 -1
  78. package/modules/hall-ui/public/settings.html +4 -33
  79. package/modules/hall-ui/public/settings.js +3 -33
  80. package/modules/hall-ui/public/settings.states.json +2 -2
  81. package/modules/hall-ui/public/studio.html +1 -1
  82. package/modules/hall-ui/public/style.css +10 -13
  83. package/modules/hall-ui/public/task.html +4 -1
  84. package/modules/hall-ui/public/task.js +36 -1
  85. package/modules/hall-ui/public/tweak-editor-lib.js +18 -1
  86. package/modules/hall-ui/public/tweak-editor.css +16 -0
  87. package/modules/hall-ui/public/tweak-editor.html +26 -3
  88. package/modules/hall-ui/public/tweak-editor.js +32 -1
  89. package/modules/hall-ui/public/work.js +1 -1
  90. package/modules/hall-ui/records/tweak-editor.md +1 -0
  91. package/modules/ideas/module.json +1 -0
  92. package/modules/ideas/projection.js +1 -1
  93. package/modules/lifecycle/db-claim-reads.js +1 -58
  94. package/modules/lifecycle/db-ship.js +4 -9
  95. package/modules/lifecycle/db.js +0 -4
  96. package/modules/lifecycle/github-push.js +12 -14
  97. package/modules/lifecycle/kickoff-checklist.js +0 -4
  98. package/modules/lifecycle/lifecycle.js +0 -8
  99. package/modules/lifecycle/module.json +1 -0
  100. package/modules/lifecycle/publish-reconciler.js +10 -10
  101. package/modules/lifecycle/routes/tasks.js +13 -15
  102. package/modules/lifecycle/ship-card.js +1 -1
  103. package/modules/lifecycle/task-visuals.js +2 -2
  104. package/modules/memory/module.json +1 -0
  105. package/modules/memory/routes/memory.js +2 -2
  106. package/modules/npm-release/module.json +1 -0
  107. package/modules/onboarding/module.json +1 -0
  108. package/modules/onboarding/onboarding-state.js +17 -36
  109. package/modules/onboarding/routes/access-requests.js +3 -3
  110. package/modules/platform-identity/module.json +1 -0
  111. package/modules/platform-identity/platform-identity.js +13 -5
  112. package/modules/platform-identity/routes/sso.js +5 -4
  113. package/modules/platform-identity/tests/platform-identity.mjs +17 -3
  114. package/modules/provisioning/capacity.js +1 -1
  115. package/modules/provisioning/module.json +1 -0
  116. package/modules/provisioning/provisioning.js +6 -5
  117. package/modules/provisioning/routes/provisioning.js +4 -4
  118. package/modules/provisioning/starter-bundles.js +5 -25
  119. package/modules/public-landing/module.json +1 -0
  120. package/modules/public-landing/public/assets/cosmos.css +1 -1
  121. package/modules/public-landing/public/contact.html +1 -1
  122. package/modules/public-landing/public/privacy.html +1 -1
  123. package/modules/public-landing/public/projects.html +101 -32
  124. package/modules/public-landing/public/projects.probes.json +2 -2
  125. package/modules/public-landing/public/projects.states.json +4 -3
  126. package/modules/public-landing/public/terms.html +1 -1
  127. package/modules/security/module.json +1 -0
  128. package/modules/sessions/db.js +1 -1
  129. package/modules/sessions/module.json +1 -0
  130. package/modules/specialities/module.json +1 -0
  131. package/modules/status-ui/module.json +1 -0
  132. package/modules/ui-design/module.json +1 -0
  133. package/package-lock.json +2 -2
  134. package/package.json +1 -1
  135. package/release-notes.json +84 -0
  136. package/scripts/gds/artifact-format.js +203 -0
  137. package/scripts/gds/artifact-staleness.js +2 -2
  138. package/scripts/gds/audit-authorship.sh +1 -13
  139. package/scripts/gds/backfill-task-rewards.js +5 -5
  140. package/scripts/gds/claim.js +0 -15
  141. package/scripts/gds/claude-materialize.js +2 -2
  142. package/scripts/gds/cli-lib.js +15 -15
  143. package/scripts/gds/codemod-rename-src-gds.js +1 -1
  144. package/scripts/gds/context-pack.js +5 -7
  145. package/scripts/gds/diagram-facts.js +12 -23
  146. package/scripts/gds/do-api.js +13 -80
  147. package/scripts/gds/doc-cli-guard.js +2 -0
  148. package/scripts/gds/doctor.js +4 -4
  149. package/scripts/gds/feedback-latest.js +139 -9
  150. package/scripts/gds/fitness-checks-identity.js +2 -7
  151. package/scripts/gds/fitness-checks-packaging.js +4 -4
  152. package/scripts/gds/fitness-checks-write-validation.js +4 -0
  153. package/scripts/gds/fitness-ratchets.js +5 -5
  154. package/scripts/gds/fitness.js +10 -10
  155. package/scripts/gds/gen-api-client.js +4 -4
  156. package/scripts/gds/gen-api-docs.js +1 -1
  157. package/scripts/gds/gen-diagrams.js +49 -71
  158. package/scripts/gds/gen-repo-map.js +13 -14
  159. package/scripts/gds/gen-session-index.js +8 -8
  160. package/scripts/gds/http-api-client.js +12 -19
  161. package/scripts/gds/init.js +1 -1
  162. package/scripts/gds/leak-scan-allowlist.js +1 -1
  163. package/scripts/gds/lint-infra-exec.js +1 -1
  164. package/scripts/gds/local-preview-lib.js +8 -39
  165. package/scripts/gds/local-preview.js +2 -15
  166. package/scripts/gds/migration-namespace.js +3 -3
  167. package/scripts/gds/module-artifact.js +212 -0
  168. package/scripts/gds/module.js +95 -6
  169. package/scripts/gds/package-core.js +5 -116
  170. package/scripts/gds/plain-cards.js +1 -1
  171. package/scripts/gds/provision-config.js +2 -2
  172. package/scripts/gds/provision-net.js +2 -3
  173. package/scripts/gds/provision.js +9 -9
  174. package/scripts/gds/publish-manifest.js +1 -2
  175. package/scripts/gds/push-path-brief.js +10 -10
  176. package/scripts/gds/regen-instance-docs.js +1 -1
  177. package/scripts/gds/rename-history-check.js +1 -1
  178. package/scripts/gds/run-unit-tests.js +2 -16
  179. package/scripts/gds/sandbox-stage.js +39 -341
  180. package/scripts/gds/session-digest-build.js +2 -2
  181. package/scripts/gds/ship-deploy-target.js +13 -13
  182. package/scripts/gds/ship-flow.js +7 -7
  183. package/scripts/gds/ship-land.js +9 -10
  184. package/scripts/gds/ship-merge.js +4 -4
  185. package/scripts/gds/ship-preflight-steps.js +4 -4
  186. package/scripts/gds/ship-regen.js +15 -49
  187. package/scripts/gds/ship.js +13 -33
  188. package/scripts/gds/skill-preflight.js +9 -8
  189. package/scripts/gds/start.js +0 -15
  190. package/scripts/hall-preview/README.md +5 -5
  191. package/scripts/hall-preview/server.js +6 -6
  192. package/scripts/render-diagrams.sh +1 -1
  193. package/src/bongos/api-errors.js +1 -1
  194. package/src/bongos/api-prefix.js +4 -4
  195. package/src/bongos/auth-github.js +2 -3
  196. package/src/bongos/auth.js +51 -126
  197. package/src/bongos/db-kernel.js +2 -3
  198. package/src/bongos/db.js +5 -28
  199. package/src/bongos/module-scope-map.js +14 -29
  200. package/src/bongos/module-store.js +141 -0
  201. package/src/bongos/platform-visibility-gate.js +1 -1
  202. package/src/bongos/route-rank-check.js +3 -16
  203. package/src/bongos/routes/auth.js +0 -116
  204. package/src/bongos/routes/builders.js +5 -15
  205. package/src/bongos/routes/instance.js +8 -14
  206. package/src/bongos/routes/me.js +7 -23
  207. package/src/bongos/routes/modules.js +83 -0
  208. package/src/bongos/routes/security.js +3 -3
  209. package/src/bongos/routes.js +7 -2
  210. package/src/bongos/serve-internal.js +5 -6
  211. package/src/bongos-downloads.js +1 -6
  212. package/src/branding.js +2 -2
  213. package/src/build-info.js +4 -6
  214. package/src/instance-config.js +2 -2
  215. package/src/module-api.js +13 -6
  216. package/src/module-loader/catalog.js +3 -0
  217. package/src/module-loader/loader.js +4 -4
  218. package/src/module-loader/manifest-schema.js +16 -8
  219. package/src/module-seams.js +2 -3
  220. package/src/modules.js +42 -14
  221. package/tests/agents_spend_guard.mjs +1 -1
  222. package/tests/api_alias_caller_ratchet.mjs +1 -1
  223. package/tests/api_alias_exceptions.mjs +1 -1
  224. package/tests/api_client.mjs +1 -16
  225. package/tests/api_path_404.mjs +1 -1
  226. package/tests/auth_page_gate.mjs +10 -10
  227. package/tests/backfill_task_rewards.mjs +1 -1
  228. package/tests/canonical_profile_url.mjs +1 -3
  229. package/tests/claim_action.mjs +4 -1
  230. package/tests/claim_from_task_and_home.mjs +127 -0
  231. package/tests/{box_ship_permissions.mjs → cli_allowlist_permissions.mjs} +5 -5
  232. package/tests/cli_sessions.mjs +1 -1
  233. package/tests/consumer_layout_boot.mjs +2 -0
  234. package/tests/context_pack.mjs +13 -13
  235. package/tests/copy_desk_page_docx.mjs +33 -2
  236. package/tests/copy_inventory.mjs +7 -7
  237. package/tests/core_upgrade_runner.mjs +6 -6
  238. package/tests/credit_grant.mjs +2 -2
  239. package/tests/criterion_suggest.mjs +1 -1
  240. package/tests/deploy_divergence_line.mjs +11 -11
  241. package/tests/design_tokens_sync.mjs +3 -2
  242. package/tests/diagram_facts_offset.mjs +1 -1
  243. package/tests/do_api.mjs +106 -0
  244. package/tests/feedback_latest.mjs +122 -0
  245. package/tests/fitness.mjs +44 -42
  246. package/tests/fitness_ratchets.mjs +2 -2
  247. package/tests/gate_approvals.mjs +0 -1
  248. package/tests/github_push_land_proof.mjs +1 -1
  249. package/tests/go_live.mjs +3 -3
  250. package/tests/goal_advisory.mjs +3 -3
  251. package/tests/goal_suggest.mjs +3 -3
  252. package/tests/government_abuse_matrix.mjs +21 -19
  253. package/tests/government_ownership_scope.mjs +33 -35
  254. package/tests/government_parity.mjs +2 -2
  255. package/tests/government_protected_surfaces.mjs +56 -37
  256. package/tests/government_require_permission.mjs +3 -3
  257. package/tests/government_seed.mjs +37 -4
  258. package/tests/government_session_scope.mjs +92 -366
  259. package/tests/hall_audit.mjs +1 -1
  260. package/tests/hall_error_envelope.mjs +4 -0
  261. package/tests/hall_landing_boot.mjs +4 -1
  262. package/tests/hall_palette.mjs +1 -16
  263. package/tests/hall_record_world.mjs +6 -0
  264. package/tests/hall_tweak_editor.mjs +52 -1
  265. package/tests/helpers.mjs +1 -1
  266. package/tests/host_topology_skips.mjs +3 -4
  267. package/tests/html_comment_nesting.mjs +137 -0
  268. package/tests/infra_exec_paths.mjs +9 -10
  269. package/tests/init.mjs +4 -5
  270. package/tests/instance_manifest.mjs +18 -25
  271. package/tests/kickoff_checklist.mjs +1 -1
  272. package/tests/lib_sh_resolution.mjs +0 -221
  273. package/tests/local_preview.mjs +0 -12
  274. package/tests/migration_namespace.mjs +6 -6
  275. package/tests/module-scope-map.mjs +9 -9
  276. package/tests/module_api.mjs +2 -2
  277. package/tests/module_catalog.mjs +1 -1
  278. package/tests/module_cli.mjs +20 -20
  279. package/tests/module_contributions.mjs +6 -6
  280. package/tests/module_loader.mjs +6 -6
  281. package/tests/module_manifest.mjs +26 -17
  282. package/tests/module_route_rank.mjs +2 -2
  283. package/tests/module_store_publish.mjs +307 -0
  284. package/tests/module_store_publish_route.mjs +121 -0
  285. package/tests/module_store_registry_migration.mjs +70 -0
  286. package/tests/modules.mjs +56 -26
  287. package/tests/modules_route_wiring.mjs +1 -1
  288. package/tests/onboarding_route_signals.mjs +21 -31
  289. package/tests/onboarding_state.mjs +35 -49
  290. package/tests/paste_token_session_store.mjs +1 -1
  291. package/tests/permission_path.mjs +0 -3
  292. package/tests/platform_boot.mjs +1 -2
  293. package/tests/platform_visibility_gate.mjs +1 -1
  294. package/tests/profile_route.mjs +1 -6
  295. package/tests/project_modules_ui.mjs +17 -17
  296. package/tests/projects_hub.mjs +5 -5
  297. package/tests/projects_hub_app_step.mjs +138 -0
  298. package/tests/projects_hub_module_picker.mjs +77 -76
  299. package/tests/projects_hub_pre_uat.mjs +4 -5
  300. package/tests/provision.mjs +7 -7
  301. package/tests/provisioning_capacity.mjs +1 -1
  302. package/tests/provisioning_recommendations.mjs +2 -1
  303. package/tests/provisioning_starter_bundles.mjs +0 -22
  304. package/tests/publish_branch_route.mjs +11 -19
  305. package/tests/publish_manifest.mjs +2 -3
  306. package/tests/publish_reconciler.mjs +8 -8
  307. package/tests/push_path_brief.mjs +10 -9
  308. package/tests/rank_tier_single_source.mjs +1 -13
  309. package/tests/regrade_eligibility.mjs +1 -1
  310. package/tests/rename_history_restraint.mjs +1 -1
  311. package/tests/repo_map.mjs +12 -13
  312. package/tests/runner_drift.mjs +3 -21
  313. package/tests/sandbox_stage.mjs +57 -390
  314. package/tests/seam_wiring_guard.mjs +11 -11
  315. package/tests/search_isolation.mjs +3 -3
  316. package/tests/session_records.mjs +1 -1
  317. package/tests/session_rename_fallback.mjs +1 -22
  318. package/tests/session_start_freshness.mjs +3 -3
  319. package/tests/session_token_hash_db.mjs +1 -1
  320. package/tests/ship_card.mjs +1 -1
  321. package/tests/ship_ci_deploy.mjs +17 -17
  322. package/tests/ship_error_shape.mjs +1 -1
  323. package/tests/ship_premerge.mjs +1 -1
  324. package/tests/ship_resume.mjs +1 -1
  325. package/tests/skill_preflight.mjs +2 -2
  326. package/tests/skip_is_not_pass.mjs +1 -1
  327. package/tests/task_visual_slots.mjs +31 -0
  328. package/tests/terms_acceptance.mjs +2 -2
  329. package/tests/upgrade.mjs +4 -4
  330. package/tests/watch_sealed_floor.mjs +0 -1
  331. package/tests/wizard_draft_resume.mjs +2 -2
  332. package/tests/wizard_intent_resume.mjs +21 -10
  333. package/tests/wizard_preselect_why.mjs +18 -18
  334. package/docs/onboarding/browser-terminal-guide.md +0 -73
  335. package/docs/recipes/managed-settings-remote-control.md +0 -416
  336. package/modules/dev-box/CLAUDE.md +0 -15
  337. package/modules/dev-box/box-access.js +0 -623
  338. package/modules/dev-box/box-credential.js +0 -94
  339. package/modules/dev-box/box-onboard.js +0 -486
  340. package/modules/dev-box/boxes.js +0 -1038
  341. package/modules/dev-box/db.js +0 -39
  342. package/modules/dev-box/module.json +0 -19
  343. package/modules/dev-box/routes/box.js +0 -1223
  344. package/scripts/gds/box-auth-check.js +0 -160
  345. package/scripts/gds/box-infra.js +0 -321
  346. package/scripts/gds/box-sync.js +0 -216
  347. package/scripts/gds/box.js +0 -1332
  348. package/scripts/gds/cf-tunnel.js +0 -558
  349. package/scripts/gds/smoke-box.sh +0 -150
  350. package/scripts/gds/tree-preflight.js +0 -241
  351. package/src/bongos/app-pair.js +0 -172
  352. package/tests/app_pair.mjs +0 -168
  353. package/tests/box_access.mjs +0 -578
  354. package/tests/box_auth_check.mjs +0 -114
  355. package/tests/box_code_staleness.mjs +0 -129
  356. package/tests/box_connect_e2e.mjs +0 -196
  357. package/tests/box_cost.mjs +0 -70
  358. package/tests/box_credential.mjs +0 -125
  359. package/tests/box_dns_repoint.mjs +0 -153
  360. package/tests/box_env.mjs +0 -64
  361. package/tests/box_host_keys.mjs +0 -126
  362. package/tests/box_infra_resolve.mjs +0 -246
  363. package/tests/box_onboard.mjs +0 -317
  364. package/tests/box_scope_session.mjs +0 -119
  365. package/tests/box_sweep_docs.mjs +0 -119
  366. package/tests/box_sync.mjs +0 -55
  367. package/tests/box_sync_scope_report.mjs +0 -126
  368. package/tests/box_task_scope.mjs +0 -169
  369. package/tests/box_task_scope_pause.mjs +0 -66
  370. package/tests/box_terminal_ssrf.mjs +0 -96
  371. package/tests/boxes.mjs +0 -1585
  372. package/tests/cf_ruleset_preflight.mjs +0 -142
  373. package/tests/cf_tunnel.mjs +0 -496
  374. package/tests/docs_scrubber_damage.mjs +0 -111
  375. package/tests/module_scope_active_claims.mjs +0 -94
  376. package/tests/ship_api_client_pathspec.mjs +0 -100
  377. package/tests/tree_preflight.mjs +0 -243
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env node
2
- // scripts/gds/box-sync.js — BV1.R96 (goal 1000051): "sync now".
3
- //
4
- // Re-run the box's source-fetch ON DEMAND so a freshly-claimed task's code
5
- // materializes within seconds, instead of waiting for the ~10-min cron (which
6
- // stays the backstop). Because the box's fetch calls GET /box/source-access —
7
- // which since BV1.R94 returns the sparse set for the builder's ACTIVE CLAIM
8
- // (task/module scope, ADR 0148) — re-running it RE-SCOPES the box to whatever the
9
- // builder just claimed. So `/builder-claim N` then `box-sync` = the box holds
10
- // exactly task N's module code, seconds later.
11
- //
12
- // Runs ON THE BOX, where infra/box-source-fetch.sh lives (it is in the box's BASE
13
- // sparse set). OFF a box there is no fetch script — the source IS the local
14
- // checkout — so it says so plainly and exits non-zero rather than failing opaquely.
15
- //
16
- // Usage: node scripts/gds/box-sync.js # re-fetch now
17
- // node scripts/gds/box-sync.js --dry-run # print what it WOULD run
18
- // node scripts/gds/box-sync.js --widen <dir> # keep <dir> across ticks
19
- // node scripts/gds/box-sync.js --unwiden <dir> # stop keeping it
20
- // node scripts/gds/box-sync.js --widen-list # what is kept, and what is ignored
21
- //
22
- // WHY --widen EXISTS (task 1003087 / idea 1000793). `git sparse-checkout add`
23
- // does not survive: the */10 cron re-applies the SERVER-computed set and deletes
24
- // the addition, sometimes MID-COMMAND — a live test suite died with
25
- // MODULE_NOT_FOUND that read exactly like a code bug. --widen records the
26
- // directory server-side instead, so every fetch (the cron included) returns it
27
- // in the set and it stops being deleted. It is capped, and it can never widen
28
- // past what your RANK already reaches — a request outside it is stored but
29
- // reported as ignored rather than silently applied.
30
-
31
- const fs = require('node:fs');
32
- const path = require('node:path');
33
- const { spawnSync } = require('node:child_process');
34
-
35
- // Reuse box.js's instance-root-first infra resolver (ADR 0150 / R98) so this
36
- // locates infra/ the SAME way provisioning does — the box's fetch script lives
37
- // beside the cloud-init template it validates on.
38
- const { resolveBoxInfraDir } = require('./box.js');
39
-
40
- const FETCH_SCRIPT = 'box-source-fetch.sh';
41
-
42
- // Absolute path to the box source-fetch script, or null when it can't be found
43
- // (i.e. not on a box). Pure: opts thread through to resolveBoxInfraDir for tests.
44
- function resolveFetchScript(opts = {}) {
45
- const infraDir = resolveBoxInfraDir(opts);
46
- if (!infraDir) return null;
47
- const p = path.join(infraDir, FETCH_SCRIPT);
48
- try { return fs.existsSync(p) ? p : null; } catch { return null; }
49
- }
50
-
51
- // valueAfter(argv, flag) — the argument following a flag, or null. Kept tiny and
52
- // pure so the arg handling is testable without spawning anything.
53
- function valueAfter(argv, flag) {
54
- const i = argv.indexOf(flag);
55
- if (i < 0) return null;
56
- const v = argv[i + 1];
57
- return typeof v === 'string' && v && !v.startsWith('--') ? v : null;
58
- }
59
-
60
- // formatWidenReport — PURE. The lines to print for a /box/widen body. Reports
61
- // IGNORED entries loudly: a widen the server accepted into storage but will not
62
- // apply (because it is outside your rank scope) looks identical to a working one
63
- // unless it is said out loud, and a silently-inert widen is exactly the class of
64
- // bug this whole task is about.
65
- function formatWidenReport(body) {
66
- if (!body || typeof body !== 'object' || Array.isArray(body)) {
67
- return ['widen: could not read your widen set.'];
68
- }
69
- const kept = Array.isArray(body.widen_paths) ? body.widen_paths : [];
70
- const ignored = Array.isArray(body.ignored) ? body.ignored : [];
71
- const out = [];
72
- out.push(kept.length
73
- ? `widen: keeping ${kept.length} path(s) across ticks: ${kept.join(', ')}`
74
- : 'widen: nothing kept — the fetch set is whatever your claim scope says.');
75
- if (ignored.length) {
76
- out.push(`widen: IGNORED (outside your rank scope, stored but not applied): ${ignored.join(', ')}`);
77
- }
78
- return out;
79
- }
80
-
81
- // The --widen family. Talks to the control plane, so it works off a box too —
82
- // unlike the fetch itself, the widen set is server state you can inspect and
83
- // edit from anywhere.
84
- async function runWiden(argv) {
85
- const { apiCall } = require('./cli-lib');
86
- const add = valueAfter(argv, '--widen');
87
- const remove = valueAfter(argv, '--unwiden');
88
- const clear = argv.includes('--widen-clear');
89
- const listOnly = !add && !remove && !clear;
90
-
91
- const r = listOnly
92
- ? await apiCall('GET', '/api/bongos/box/widen')
93
- : await apiCall('POST', '/api/bongos/box/widen', {
94
- ...(add ? { add: [add] } : {}),
95
- ...(remove ? { remove: [remove] } : {}),
96
- ...(clear ? { clear: true } : {}),
97
- });
98
-
99
- if (!r || (r.status !== 200 && r.status !== 201)) {
100
- const code = r && r.data && r.data.error ? r.data.error : `HTTP ${r ? r.status : '?'}`;
101
- if (code === 'no_box') {
102
- console.error('widen: you have no dev box — there is nothing to widen. Provision one first.');
103
- } else if (code === 'bad_widen_path') {
104
- const bad = r.data && r.data.rejected ? r.data.rejected.join(', ') : '';
105
- console.error(`widen: refused ${bad} — give a repo-relative DIRECTORY (no leading /, no "..").`);
106
- } else {
107
- console.error(`widen: failed (${code}).`);
108
- }
109
- return 1;
110
- }
111
- for (const line of formatWidenReport(r.data)) console.log(line);
112
- if (!listOnly) console.log('widen: run `box-sync` (no flags) to apply it to the checkout now.');
113
- return 0;
114
- }
115
-
116
- function main(argv = process.argv.slice(2)) {
117
- // The widen family is server state, not a fetch — handled before the on-a-box
118
- // check, so it works from a laptop too.
119
- if (argv.some((a) => a === '--widen' || a === '--unwiden' || a === '--widen-list' || a === '--widen-clear')) {
120
- runWiden(argv).then((code) => process.exit(code), () => process.exit(1));
121
- return;
122
- }
123
- const dryRun = argv.includes('--dry-run') || argv.includes('-n');
124
- const script = resolveFetchScript();
125
- if (!script) {
126
- console.error(
127
- `sync: no infra/${FETCH_SCRIPT} found. This runs ON a dev box (where the box `
128
- + `source-fetch lives). Off a box your source IS your local checkout — nothing to sync.`,
129
- );
130
- process.exit(1);
131
- }
132
- if (dryRun) {
133
- console.log(`sync [dry-run]: would run bash ${script}`);
134
- console.log(' → re-fetches the sparse checkout for your ACTIVE claim (re-scopes in place).');
135
- process.exit(0);
136
- }
137
- console.log(`sync: re-running ${script} — re-scoping the box to your active claim…`);
138
- const r = spawnSync('bash', [script], { stdio: 'inherit' });
139
- if (r.error) {
140
- console.error(`sync: could not run the fetch (${r.error.message})`);
141
- process.exit(1);
142
- }
143
- if (r.status !== 0) process.exit(r.status == null ? 1 : r.status);
144
- console.log('sync: done — your box now holds the code for your active claim.');
145
- // Then say WHAT it holds, so a base-only box is visible instead of silent.
146
- reportScope().then(() => process.exit(0), () => process.exit(0));
147
- }
148
-
149
- // ---------------------------------------------------------------------------
150
- // task 1002731 — say what scope the box ACTUALLY got
151
- // ---------------------------------------------------------------------------
152
-
153
- // The failure this exists for is a SILENT one: a box comes up holding only the
154
- // base slice (no modules/ at all) and nothing anywhere says so. Live, that was
155
- // 247 of 248 source grants — including an Archon with 7 active claims — and the
156
- // only way to see it was reading box_events on the control plane. GET /box/scope
157
- // already returns the resolved decision; nothing ever showed it to a human.
158
- //
159
- // PURE so it is unit-testable without a box or a network: takes the /box/scope
160
- // body, returns the lines to print. null/garbage in → one honest line rather
161
- // than a crash, because this is diagnostic output on an already-degraded path
162
- // and must never be the thing that fails.
163
- function formatScopeReport(scope) {
164
- if (!scope || typeof scope !== 'object' || Array.isArray(scope)) {
165
- return ['scope: could not read your box scope (GET /box/scope did not answer).'];
166
- }
167
- const modules = Array.isArray(scope.modules) ? scope.modules : null;
168
- const paths = Array.isArray(scope.sparse_paths) ? scope.sparse_paths : [];
169
- const out = [];
170
-
171
- if (scope.scope === 'task' && modules && modules.length) {
172
- out.push(`scope: task — your box holds ${modules.length} module(s): ${modules.join(', ')}`);
173
- } else if (scope.scope === 'base') {
174
- out.push('scope: BASE ONLY — your box holds no modules/ code at all.');
175
- out.push(scope.task_scope
176
- ? ' Why: you hold no active claim, so there is no work to scope the box to.'
177
- : ' Why: this instance resolved no claim scope.');
178
- out.push(' Fix: claim a task (/builder-claim N), then re-run this sync.');
179
- } else if (scope.scope === 'full') {
180
- out.push('scope: full — your box holds the whole repo (your rank allows it).');
181
- if (modules && modules.length === 0) {
182
- // The task-1002729 fallback fired: claims held, but their goals declare no
183
- // wall. Worth naming — the box is usable, but task-scoping is doing nothing.
184
- out.push(' Note: your claimed work declares no module scope, so this fell back to');
185
- out.push(" your rank rather than scoping to the task. Setting the goal's");
186
- out.push(' scope_modules would give you a tighter box.');
187
- }
188
- } else if (scope.scope === 'starter') {
189
- out.push('scope: starter — a fixed slice for newcomers, not scoped to your claim.');
190
- } else {
191
- out.push(`scope: ${String(scope.scope || 'unknown')}`);
192
- }
193
- if (paths.length) out.push(` paths: ${paths.length} sparse entr${paths.length === 1 ? 'y' : 'ies'}`);
194
- return out;
195
- }
196
-
197
- // Read the resolved scope and print it. Never throws and never changes the exit
198
- // status — a diagnostic that could fail the sync it reports on would be worse
199
- // than no diagnostic.
200
- async function reportScope() {
201
- try {
202
- const { apiCall } = require('./cli-lib');
203
- const r = await apiCall('GET', '/api/bongos/box/scope');
204
- if (!r || r.status !== 200) {
205
- console.log('scope: could not read your box scope right now (that does not affect the sync above).');
206
- return;
207
- }
208
- for (const line of formatScopeReport(r.data)) console.log(line);
209
- } catch (_) {
210
- console.log('scope: could not read your box scope right now (that does not affect the sync above).');
211
- }
212
- }
213
-
214
- if (require.main === module) main();
215
-
216
- module.exports = { resolveFetchScript, FETCH_SCRIPT, formatScopeReport, formatWidenReport, valueAfter };