@bongos/core 1.19.1072 → 1.19.1074

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 (297) hide show
  1. package/.bongos-core.json +320 -465
  2. package/.claude/skills/feedback/SKILL.md +2 -2
  3. package/clients/bongos-client/README.md +1 -1
  4. package/clients/bongos-client/bongos-client.global.js +4 -60
  5. package/clients/bongos-client/index.cjs +4 -60
  6. package/clients/bongos-client/index.d.ts +5 -90
  7. package/clients/bongos-client/index.mjs +4 -60
  8. package/config/branding.neutral.json +1 -5
  9. package/config/modules.neutral.json +2 -3
  10. package/config/scheduled-routines.json +0 -2
  11. package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +1 -0
  12. package/docs/adr/0285-a-shared-box-holds-about-twelve-projects-per-gb-and-memory-is-the-wall.md +1 -0
  13. package/docs/adr/0323-hosting-is-three-shapes-and-we-are-not-the-landlord.md +1 -1
  14. package/docs/adr/0327-a-cloud-host-runs-on-the-owners-account-and-the-key-is-borrowed.md +1 -1
  15. package/docs/adr/0341-the-page-is-the-unit-of-tweak-mode.md +6 -2
  16. package/docs/adr/0345-we-host-every-projects-hall-and-its-app-deploys-where-the-owner-chooses.md +94 -0
  17. package/docs/adr/README.md +2 -1
  18. package/docs/api/openapi.json +171 -1661
  19. package/docs/api-reference.md +9 -41
  20. package/docs/architecture.md +16 -1
  21. package/docs/branding-contract.md +0 -3
  22. package/docs/copy-inventory.md +454 -479
  23. package/docs/copy-registry.json +746 -978
  24. package/docs/file-map.md +5 -34
  25. package/docs/module-api-changelog.md +4 -0
  26. package/docs/modules-contract.md +13 -1
  27. package/docs/onboarding/diagrams/04-architecture.mmd +11 -22
  28. package/docs/onboarding/diagrams/README.md +3 -3
  29. package/docs/onboarding/diagrams/assertions.json +2 -22
  30. package/docs/onboarding/primer.md +9 -28
  31. package/docs/page-inventory.json +4 -1
  32. package/docs/page-readings.json +1032 -1077
  33. package/docs/recipes/render-pilot.md +29 -10
  34. package/migrations/core_257_module_store_registry.sql +87 -0
  35. package/migrations/core_258_drop_dev_box_tables.sql +55 -0
  36. package/modules/agents/module.json +1 -0
  37. package/modules/autonomy/module.json +1 -0
  38. package/modules/builder-settings/module.json +1 -0
  39. package/modules/builder-settings/render-prefs.js +4 -5
  40. package/modules/copy-desk/docx.js +78 -5
  41. package/modules/copy-desk/module.json +1 -0
  42. package/modules/copy-desk/routes/copy-desk.js +9 -9
  43. package/modules/copy-desk/tests/copy_docx.mjs +107 -1
  44. package/modules/copy-desk/tests/fixtures/word-docx.mjs +30 -0
  45. package/modules/discord/module.json +1 -0
  46. package/modules/economy/module.json +1 -0
  47. package/modules/economy/routes/credits.js +1 -2
  48. package/modules/government/catalog.js +13 -17
  49. package/modules/government/migrations/government_019_retire_box_permissions.sql +33 -0
  50. package/modules/government/module.json +1 -0
  51. package/modules/government/protected-surfaces.json +3 -11
  52. package/modules/government/resolver.js +3 -46
  53. package/modules/government/routes/government.js +0 -2
  54. package/modules/government/session-scopes.js +43 -83
  55. package/modules/government/session-scopes.json +8 -18
  56. package/modules/grading/module.json +1 -0
  57. package/modules/hall-ui/module.json +1 -0
  58. package/modules/hall-ui/public/board-lib.js +2 -2
  59. package/modules/hall-ui/public/builders.js +29 -40
  60. package/modules/hall-ui/public/collab.html +1 -1
  61. package/modules/hall-ui/public/collab.js +1 -1
  62. package/modules/hall-ui/public/diagrams.html +3 -3
  63. package/modules/hall-ui/public/dom-utils.js +1 -1
  64. package/modules/hall-ui/public/gate.js +2 -2
  65. package/modules/hall-ui/public/gate.states.json +1 -1
  66. package/modules/hall-ui/public/hall-render.js +43 -79
  67. package/modules/hall-ui/public/index.html +5 -1
  68. package/modules/hall-ui/public/modules.js +1 -0
  69. package/modules/hall-ui/public/oversight.css +5 -5
  70. package/modules/hall-ui/public/palette.js +0 -11
  71. package/modules/hall-ui/public/primer.js +1 -1
  72. package/modules/hall-ui/public/sessions.html +1 -1
  73. package/modules/hall-ui/public/settings-sessions.js +1 -1
  74. package/modules/hall-ui/public/settings.css +0 -1
  75. package/modules/hall-ui/public/settings.html +4 -33
  76. package/modules/hall-ui/public/settings.js +3 -33
  77. package/modules/hall-ui/public/settings.states.json +2 -2
  78. package/modules/hall-ui/public/studio.html +1 -1
  79. package/modules/hall-ui/public/style.css +10 -13
  80. package/modules/hall-ui/public/task.html +4 -1
  81. package/modules/hall-ui/public/task.js +36 -1
  82. package/modules/hall-ui/public/tweak-editor-lib.js +18 -1
  83. package/modules/hall-ui/public/tweak-editor.css +16 -0
  84. package/modules/hall-ui/public/tweak-editor.html +26 -3
  85. package/modules/hall-ui/public/tweak-editor.js +32 -1
  86. package/modules/hall-ui/public/work.js +1 -1
  87. package/modules/hall-ui/records/tweak-editor.md +1 -0
  88. package/modules/ideas/module.json +1 -0
  89. package/modules/lifecycle/db-claim-reads.js +1 -58
  90. package/modules/lifecycle/db-ship.js +0 -5
  91. package/modules/lifecycle/db.js +0 -4
  92. package/modules/lifecycle/kickoff-checklist.js +0 -4
  93. package/modules/lifecycle/lifecycle.js +0 -8
  94. package/modules/lifecycle/module.json +1 -0
  95. package/modules/lifecycle/routes/tasks.js +5 -7
  96. package/modules/memory/module.json +1 -0
  97. package/modules/npm-release/module.json +1 -0
  98. package/modules/onboarding/module.json +1 -0
  99. package/modules/onboarding/onboarding-state.js +17 -36
  100. package/modules/onboarding/routes/access-requests.js +3 -3
  101. package/modules/platform-identity/module.json +1 -0
  102. package/modules/platform-identity/platform-identity.js +13 -5
  103. package/modules/platform-identity/routes/sso.js +2 -2
  104. package/modules/platform-identity/tests/platform-identity.mjs +17 -3
  105. package/modules/provisioning/module.json +1 -0
  106. package/modules/provisioning/provisioning.js +2 -2
  107. package/modules/provisioning/starter-bundles.js +5 -25
  108. package/modules/public-landing/module.json +1 -0
  109. package/modules/public-landing/public/assets/cosmos.css +1 -1
  110. package/modules/public-landing/public/contact.html +1 -1
  111. package/modules/public-landing/public/privacy.html +1 -1
  112. package/modules/public-landing/public/projects.html +101 -32
  113. package/modules/public-landing/public/projects.probes.json +2 -2
  114. package/modules/public-landing/public/projects.states.json +4 -3
  115. package/modules/public-landing/public/terms.html +1 -1
  116. package/modules/security/module.json +1 -0
  117. package/modules/sessions/module.json +1 -0
  118. package/modules/specialities/module.json +1 -0
  119. package/modules/status-ui/module.json +1 -0
  120. package/modules/ui-design/module.json +1 -0
  121. package/package-lock.json +2 -2
  122. package/package.json +1 -1
  123. package/release-notes.json +84 -0
  124. package/scripts/gds/artifact-format.js +203 -0
  125. package/scripts/gds/audit-authorship.sh +1 -13
  126. package/scripts/gds/claim.js +0 -15
  127. package/scripts/gds/cli-lib.js +8 -8
  128. package/scripts/gds/diagram-facts.js +12 -23
  129. package/scripts/gds/do-api.js +13 -80
  130. package/scripts/gds/doc-cli-guard.js +2 -0
  131. package/scripts/gds/doctor.js +1 -1
  132. package/scripts/gds/feedback-latest.js +139 -9
  133. package/scripts/gds/fitness-checks-identity.js +2 -7
  134. package/scripts/gds/fitness-checks-write-validation.js +4 -0
  135. package/scripts/gds/fitness-ratchets.js +4 -4
  136. package/scripts/gds/fitness.js +10 -10
  137. package/scripts/gds/gen-diagrams.js +49 -71
  138. package/scripts/gds/http-api-client.js +12 -19
  139. package/scripts/gds/init.js +1 -1
  140. package/scripts/gds/lint-infra-exec.js +1 -1
  141. package/scripts/gds/local-preview-lib.js +8 -39
  142. package/scripts/gds/local-preview.js +2 -15
  143. package/scripts/gds/migration-namespace.js +3 -3
  144. package/scripts/gds/module-artifact.js +212 -0
  145. package/scripts/gds/module.js +95 -6
  146. package/scripts/gds/package-core.js +5 -116
  147. package/scripts/gds/provision-config.js +2 -2
  148. package/scripts/gds/provision-net.js +2 -3
  149. package/scripts/gds/provision.js +9 -9
  150. package/scripts/gds/publish-manifest.js +1 -2
  151. package/scripts/gds/regen-instance-docs.js +1 -1
  152. package/scripts/gds/run-unit-tests.js +2 -16
  153. package/scripts/gds/sandbox-stage.js +39 -341
  154. package/scripts/gds/ship-flow.js +6 -6
  155. package/scripts/gds/ship-land.js +3 -4
  156. package/scripts/gds/ship-regen.js +10 -41
  157. package/scripts/gds/ship.js +4 -24
  158. package/scripts/gds/start.js +0 -15
  159. package/scripts/hall-preview/README.md +5 -5
  160. package/scripts/hall-preview/server.js +6 -6
  161. package/scripts/render-diagrams.sh +1 -1
  162. package/src/bongos/api-errors.js +1 -1
  163. package/src/bongos/auth-github.js +2 -3
  164. package/src/bongos/auth.js +51 -126
  165. package/src/bongos/db-kernel.js +2 -3
  166. package/src/bongos/db.js +5 -28
  167. package/src/bongos/module-scope-map.js +14 -29
  168. package/src/bongos/module-store.js +141 -0
  169. package/src/bongos/route-rank-check.js +3 -16
  170. package/src/bongos/routes/auth.js +0 -116
  171. package/src/bongos/routes/builders.js +5 -15
  172. package/src/bongos/routes/instance.js +8 -14
  173. package/src/bongos/routes/me.js +6 -22
  174. package/src/bongos/routes/modules.js +83 -0
  175. package/src/bongos/routes.js +5 -0
  176. package/src/module-api.js +13 -6
  177. package/src/module-loader/catalog.js +3 -0
  178. package/src/module-loader/loader.js +4 -4
  179. package/src/module-loader/manifest-schema.js +15 -7
  180. package/src/module-seams.js +2 -3
  181. package/src/modules.js +42 -14
  182. package/tests/agents_spend_guard.mjs +1 -1
  183. package/tests/api_client.mjs +0 -15
  184. package/tests/auth_page_gate.mjs +10 -10
  185. package/tests/canonical_profile_url.mjs +1 -3
  186. package/tests/claim_action.mjs +4 -1
  187. package/tests/claim_from_task_and_home.mjs +127 -0
  188. package/tests/consumer_layout_boot.mjs +2 -0
  189. package/tests/copy_desk_page_docx.mjs +33 -2
  190. package/tests/core_upgrade_runner.mjs +6 -6
  191. package/tests/deploy_divergence_line.mjs +11 -11
  192. package/tests/diagram_facts_offset.mjs +1 -1
  193. package/tests/do_api.mjs +106 -0
  194. package/tests/feedback_latest.mjs +122 -0
  195. package/tests/fitness.mjs +44 -42
  196. package/tests/gate_approvals.mjs +0 -1
  197. package/tests/go_live.mjs +3 -3
  198. package/tests/government_abuse_matrix.mjs +20 -19
  199. package/tests/government_ownership_scope.mjs +33 -35
  200. package/tests/government_parity.mjs +2 -2
  201. package/tests/government_protected_surfaces.mjs +56 -37
  202. package/tests/government_require_permission.mjs +3 -3
  203. package/tests/government_seed.mjs +37 -4
  204. package/tests/government_session_scope.mjs +92 -366
  205. package/tests/hall_error_envelope.mjs +4 -0
  206. package/tests/hall_landing_boot.mjs +4 -1
  207. package/tests/hall_palette.mjs +1 -16
  208. package/tests/hall_record_world.mjs +6 -0
  209. package/tests/hall_tweak_editor.mjs +52 -1
  210. package/tests/host_topology_skips.mjs +1 -2
  211. package/tests/html_comment_nesting.mjs +137 -0
  212. package/tests/infra_exec_paths.mjs +9 -10
  213. package/tests/init.mjs +4 -5
  214. package/tests/instance_manifest.mjs +18 -25
  215. package/tests/kickoff_checklist.mjs +1 -1
  216. package/tests/lib_sh_resolution.mjs +0 -221
  217. package/tests/local_preview.mjs +0 -12
  218. package/tests/module-scope-map.mjs +9 -9
  219. package/tests/module_catalog.mjs +1 -1
  220. package/tests/module_cli.mjs +15 -15
  221. package/tests/module_contributions.mjs +6 -6
  222. package/tests/module_loader.mjs +6 -6
  223. package/tests/module_manifest.mjs +13 -4
  224. package/tests/module_store_publish.mjs +307 -0
  225. package/tests/module_store_publish_route.mjs +121 -0
  226. package/tests/module_store_registry_migration.mjs +70 -0
  227. package/tests/modules.mjs +56 -26
  228. package/tests/onboarding_route_signals.mjs +21 -31
  229. package/tests/onboarding_state.mjs +35 -49
  230. package/tests/permission_path.mjs +0 -3
  231. package/tests/platform_boot.mjs +1 -2
  232. package/tests/profile_route.mjs +1 -6
  233. package/tests/projects_hub.mjs +5 -5
  234. package/tests/projects_hub_app_step.mjs +138 -0
  235. package/tests/projects_hub_module_picker.mjs +2 -2
  236. package/tests/projects_hub_pre_uat.mjs +4 -5
  237. package/tests/provision.mjs +7 -7
  238. package/tests/provisioning_starter_bundles.mjs +0 -22
  239. package/tests/publish_branch_route.mjs +10 -18
  240. package/tests/publish_manifest.mjs +1 -2
  241. package/tests/rank_tier_single_source.mjs +1 -13
  242. package/tests/repo_map.mjs +3 -4
  243. package/tests/runner_drift.mjs +3 -21
  244. package/tests/sandbox_stage.mjs +57 -390
  245. package/tests/session_rename_fallback.mjs +0 -21
  246. package/tests/ship_error_shape.mjs +1 -1
  247. package/tests/task_visual_slots.mjs +31 -0
  248. package/tests/terms_acceptance.mjs +1 -1
  249. package/tests/upgrade.mjs +4 -4
  250. package/tests/watch_sealed_floor.mjs +0 -1
  251. package/tests/wizard_draft_resume.mjs +2 -2
  252. package/tests/wizard_intent_resume.mjs +21 -10
  253. package/tests/wizard_preselect_why.mjs +18 -18
  254. package/docs/onboarding/browser-terminal-guide.md +0 -73
  255. package/docs/recipes/managed-settings-remote-control.md +0 -416
  256. package/modules/dev-box/CLAUDE.md +0 -15
  257. package/modules/dev-box/box-access.js +0 -623
  258. package/modules/dev-box/box-credential.js +0 -94
  259. package/modules/dev-box/box-onboard.js +0 -486
  260. package/modules/dev-box/boxes.js +0 -1038
  261. package/modules/dev-box/db.js +0 -39
  262. package/modules/dev-box/module.json +0 -19
  263. package/modules/dev-box/routes/box.js +0 -1223
  264. package/scripts/gds/box-auth-check.js +0 -160
  265. package/scripts/gds/box-infra.js +0 -321
  266. package/scripts/gds/box-sync.js +0 -216
  267. package/scripts/gds/box.js +0 -1332
  268. package/scripts/gds/cf-tunnel.js +0 -558
  269. package/scripts/gds/smoke-box.sh +0 -150
  270. package/scripts/gds/tree-preflight.js +0 -241
  271. package/src/bongos/app-pair.js +0 -172
  272. package/tests/app_pair.mjs +0 -168
  273. package/tests/box_access.mjs +0 -578
  274. package/tests/box_auth_check.mjs +0 -114
  275. package/tests/box_code_staleness.mjs +0 -129
  276. package/tests/box_connect_e2e.mjs +0 -196
  277. package/tests/box_cost.mjs +0 -70
  278. package/tests/box_credential.mjs +0 -125
  279. package/tests/box_dns_repoint.mjs +0 -153
  280. package/tests/box_env.mjs +0 -64
  281. package/tests/box_host_keys.mjs +0 -126
  282. package/tests/box_infra_resolve.mjs +0 -246
  283. package/tests/box_onboard.mjs +0 -317
  284. package/tests/box_scope_session.mjs +0 -119
  285. package/tests/box_sweep_docs.mjs +0 -119
  286. package/tests/box_sync.mjs +0 -55
  287. package/tests/box_sync_scope_report.mjs +0 -126
  288. package/tests/box_task_scope.mjs +0 -169
  289. package/tests/box_task_scope_pause.mjs +0 -66
  290. package/tests/box_terminal_ssrf.mjs +0 -96
  291. package/tests/boxes.mjs +0 -1585
  292. package/tests/cf_ruleset_preflight.mjs +0 -142
  293. package/tests/cf_tunnel.mjs +0 -496
  294. package/tests/docs_scrubber_damage.mjs +0 -111
  295. package/tests/module_scope_active_claims.mjs +0 -94
  296. package/tests/ship_api_client_pathspec.mjs +0 -100
  297. 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 };