@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.
- package/.bongos-core.json +404 -549
- package/.claude/skills/feedback/SKILL.md +2 -2
- package/bin/bongos.js +1 -3
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -60
- package/clients/bongos-client/index.cjs +4 -60
- package/clients/bongos-client/index.d.ts +5 -90
- package/clients/bongos-client/index.mjs +4 -60
- package/config/branding.neutral.json +1 -5
- package/config/modules.neutral.json +2 -3
- package/config/scheduled-routines.json +0 -2
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +1 -0
- package/docs/adr/0285-a-shared-box-holds-about-twelve-projects-per-gb-and-memory-is-the-wall.md +1 -0
- package/docs/adr/0323-hosting-is-three-shapes-and-we-are-not-the-landlord.md +1 -1
- package/docs/adr/0327-a-cloud-host-runs-on-the-owners-account-and-the-key-is-borrowed.md +1 -1
- package/docs/adr/0341-the-page-is-the-unit-of-tweak-mode.md +2 -0
- package/docs/adr/0345-we-host-every-projects-hall-and-its-app-deploys-where-the-owner-chooses.md +94 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +175 -1665
- package/docs/api-reference.md +9 -41
- package/docs/architecture.md +16 -1
- package/docs/branding-contract.md +0 -3
- package/docs/copy-inventory.md +454 -479
- package/docs/copy-registry.json +746 -978
- package/docs/file-map.md +5 -34
- package/docs/module-api-changelog.md +4 -0
- package/docs/modules-contract.md +13 -1
- package/docs/onboarding/diagrams/04-architecture.mmd +11 -22
- package/docs/onboarding/diagrams/README.md +3 -3
- package/docs/onboarding/diagrams/assertions.json +2 -22
- package/docs/onboarding/primer.md +9 -28
- package/docs/page-inventory.json +4 -1
- package/docs/page-readings.json +1032 -1077
- package/docs/recipes/render-pilot.md +29 -10
- package/migrations/core_257_module_store_registry.sql +87 -0
- package/migrations/core_258_drop_dev_box_tables.sql +55 -0
- package/modules/agents/module.json +1 -0
- package/modules/autonomy/module.json +1 -0
- package/modules/builder-settings/module.json +1 -0
- package/modules/builder-settings/render-prefs.js +4 -5
- package/modules/copy-desk/docx.js +78 -5
- package/modules/copy-desk/module.json +1 -0
- package/modules/copy-desk/routes/copy-desk.js +10 -10
- package/modules/copy-desk/tests/copy_docx.mjs +107 -1
- package/modules/copy-desk/tests/fixtures/word-docx.mjs +30 -0
- package/modules/discord/module.json +1 -0
- package/modules/discord/ship-broadcast.js +3 -3
- package/modules/economy/credits.js +2 -2
- package/modules/economy/module.json +1 -0
- package/modules/economy/routes/credits.js +1 -2
- package/modules/government/catalog.js +13 -17
- package/modules/government/migrations/government_019_retire_box_permissions.sql +33 -0
- package/modules/government/module.json +1 -0
- package/modules/government/protected-surfaces.json +3 -11
- package/modules/government/resolver.js +3 -46
- package/modules/government/routes/government.js +0 -2
- package/modules/government/session-scopes.js +43 -83
- package/modules/government/session-scopes.json +8 -18
- package/modules/grading/module.json +1 -0
- package/modules/hall-ui/module.json +1 -0
- package/modules/hall-ui/public/board-lib.js +2 -2
- package/modules/hall-ui/public/builders.js +29 -40
- package/modules/hall-ui/public/collab.html +1 -1
- package/modules/hall-ui/public/collab.js +1 -1
- package/modules/hall-ui/public/diagrams.html +3 -3
- package/modules/hall-ui/public/dom-utils.js +1 -1
- package/modules/hall-ui/public/gate.js +2 -2
- package/modules/hall-ui/public/gate.states.json +1 -1
- package/modules/hall-ui/public/hall-render.js +43 -79
- package/modules/hall-ui/public/index.html +5 -1
- package/modules/hall-ui/public/modules.js +1 -0
- package/modules/hall-ui/public/oversight.css +5 -5
- package/modules/hall-ui/public/palette.js +0 -11
- package/modules/hall-ui/public/primer.js +1 -1
- package/modules/hall-ui/public/sessions.html +1 -1
- package/modules/hall-ui/public/settings-sessions.js +1 -1
- package/modules/hall-ui/public/settings.css +0 -1
- package/modules/hall-ui/public/settings.html +4 -33
- package/modules/hall-ui/public/settings.js +3 -33
- package/modules/hall-ui/public/settings.states.json +2 -2
- package/modules/hall-ui/public/studio.html +1 -1
- package/modules/hall-ui/public/style.css +10 -13
- package/modules/hall-ui/public/task.html +4 -1
- package/modules/hall-ui/public/task.js +36 -1
- package/modules/hall-ui/public/tweak-editor-lib.js +18 -1
- package/modules/hall-ui/public/tweak-editor.css +16 -0
- package/modules/hall-ui/public/tweak-editor.html +26 -3
- package/modules/hall-ui/public/tweak-editor.js +32 -1
- package/modules/hall-ui/public/work.js +1 -1
- package/modules/hall-ui/records/tweak-editor.md +1 -0
- package/modules/ideas/module.json +1 -0
- package/modules/ideas/projection.js +1 -1
- package/modules/lifecycle/db-claim-reads.js +1 -58
- package/modules/lifecycle/db-ship.js +4 -9
- package/modules/lifecycle/db.js +0 -4
- package/modules/lifecycle/github-push.js +12 -14
- package/modules/lifecycle/kickoff-checklist.js +0 -4
- package/modules/lifecycle/lifecycle.js +0 -8
- package/modules/lifecycle/module.json +1 -0
- package/modules/lifecycle/publish-reconciler.js +10 -10
- package/modules/lifecycle/routes/tasks.js +13 -15
- package/modules/lifecycle/ship-card.js +1 -1
- package/modules/lifecycle/task-visuals.js +2 -2
- package/modules/memory/module.json +1 -0
- package/modules/memory/routes/memory.js +2 -2
- package/modules/npm-release/module.json +1 -0
- package/modules/onboarding/module.json +1 -0
- package/modules/onboarding/onboarding-state.js +17 -36
- package/modules/onboarding/routes/access-requests.js +3 -3
- package/modules/platform-identity/module.json +1 -0
- package/modules/platform-identity/platform-identity.js +13 -5
- package/modules/platform-identity/routes/sso.js +5 -4
- package/modules/platform-identity/tests/platform-identity.mjs +17 -3
- package/modules/provisioning/capacity.js +1 -1
- package/modules/provisioning/module.json +1 -0
- package/modules/provisioning/provisioning.js +6 -5
- package/modules/provisioning/routes/provisioning.js +4 -4
- package/modules/provisioning/starter-bundles.js +5 -25
- package/modules/public-landing/module.json +1 -0
- package/modules/public-landing/public/assets/cosmos.css +1 -1
- package/modules/public-landing/public/contact.html +1 -1
- package/modules/public-landing/public/privacy.html +1 -1
- package/modules/public-landing/public/projects.html +101 -32
- package/modules/public-landing/public/projects.probes.json +2 -2
- package/modules/public-landing/public/projects.states.json +4 -3
- package/modules/public-landing/public/terms.html +1 -1
- package/modules/security/module.json +1 -0
- package/modules/sessions/db.js +1 -1
- package/modules/sessions/module.json +1 -0
- package/modules/specialities/module.json +1 -0
- package/modules/status-ui/module.json +1 -0
- package/modules/ui-design/module.json +1 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +84 -0
- package/scripts/gds/artifact-format.js +203 -0
- package/scripts/gds/artifact-staleness.js +2 -2
- package/scripts/gds/audit-authorship.sh +1 -13
- package/scripts/gds/backfill-task-rewards.js +5 -5
- package/scripts/gds/claim.js +0 -15
- package/scripts/gds/claude-materialize.js +2 -2
- package/scripts/gds/cli-lib.js +15 -15
- package/scripts/gds/codemod-rename-src-gds.js +1 -1
- package/scripts/gds/context-pack.js +5 -7
- package/scripts/gds/diagram-facts.js +12 -23
- package/scripts/gds/do-api.js +13 -80
- package/scripts/gds/doc-cli-guard.js +2 -0
- package/scripts/gds/doctor.js +4 -4
- package/scripts/gds/feedback-latest.js +139 -9
- package/scripts/gds/fitness-checks-identity.js +2 -7
- package/scripts/gds/fitness-checks-packaging.js +4 -4
- package/scripts/gds/fitness-checks-write-validation.js +4 -0
- package/scripts/gds/fitness-ratchets.js +5 -5
- package/scripts/gds/fitness.js +10 -10
- package/scripts/gds/gen-api-client.js +4 -4
- package/scripts/gds/gen-api-docs.js +1 -1
- package/scripts/gds/gen-diagrams.js +49 -71
- package/scripts/gds/gen-repo-map.js +13 -14
- package/scripts/gds/gen-session-index.js +8 -8
- package/scripts/gds/http-api-client.js +12 -19
- package/scripts/gds/init.js +1 -1
- package/scripts/gds/leak-scan-allowlist.js +1 -1
- package/scripts/gds/lint-infra-exec.js +1 -1
- package/scripts/gds/local-preview-lib.js +8 -39
- package/scripts/gds/local-preview.js +2 -15
- package/scripts/gds/migration-namespace.js +3 -3
- package/scripts/gds/module-artifact.js +212 -0
- package/scripts/gds/module.js +95 -6
- package/scripts/gds/package-core.js +5 -116
- package/scripts/gds/plain-cards.js +1 -1
- package/scripts/gds/provision-config.js +2 -2
- package/scripts/gds/provision-net.js +2 -3
- package/scripts/gds/provision.js +9 -9
- package/scripts/gds/publish-manifest.js +1 -2
- package/scripts/gds/push-path-brief.js +10 -10
- package/scripts/gds/regen-instance-docs.js +1 -1
- package/scripts/gds/rename-history-check.js +1 -1
- package/scripts/gds/run-unit-tests.js +2 -16
- package/scripts/gds/sandbox-stage.js +39 -341
- package/scripts/gds/session-digest-build.js +2 -2
- package/scripts/gds/ship-deploy-target.js +13 -13
- package/scripts/gds/ship-flow.js +7 -7
- package/scripts/gds/ship-land.js +9 -10
- package/scripts/gds/ship-merge.js +4 -4
- package/scripts/gds/ship-preflight-steps.js +4 -4
- package/scripts/gds/ship-regen.js +15 -49
- package/scripts/gds/ship.js +13 -33
- package/scripts/gds/skill-preflight.js +9 -8
- package/scripts/gds/start.js +0 -15
- package/scripts/hall-preview/README.md +5 -5
- package/scripts/hall-preview/server.js +6 -6
- package/scripts/render-diagrams.sh +1 -1
- package/src/bongos/api-errors.js +1 -1
- package/src/bongos/api-prefix.js +4 -4
- package/src/bongos/auth-github.js +2 -3
- package/src/bongos/auth.js +51 -126
- package/src/bongos/db-kernel.js +2 -3
- package/src/bongos/db.js +5 -28
- package/src/bongos/module-scope-map.js +14 -29
- package/src/bongos/module-store.js +141 -0
- package/src/bongos/platform-visibility-gate.js +1 -1
- package/src/bongos/route-rank-check.js +3 -16
- package/src/bongos/routes/auth.js +0 -116
- package/src/bongos/routes/builders.js +5 -15
- package/src/bongos/routes/instance.js +8 -14
- package/src/bongos/routes/me.js +7 -23
- package/src/bongos/routes/modules.js +83 -0
- package/src/bongos/routes/security.js +3 -3
- package/src/bongos/routes.js +7 -2
- package/src/bongos/serve-internal.js +5 -6
- package/src/bongos-downloads.js +1 -6
- package/src/branding.js +2 -2
- package/src/build-info.js +4 -6
- package/src/instance-config.js +2 -2
- package/src/module-api.js +13 -6
- package/src/module-loader/catalog.js +3 -0
- package/src/module-loader/loader.js +4 -4
- package/src/module-loader/manifest-schema.js +16 -8
- package/src/module-seams.js +2 -3
- package/src/modules.js +42 -14
- package/tests/agents_spend_guard.mjs +1 -1
- package/tests/api_alias_caller_ratchet.mjs +1 -1
- package/tests/api_alias_exceptions.mjs +1 -1
- package/tests/api_client.mjs +1 -16
- package/tests/api_path_404.mjs +1 -1
- package/tests/auth_page_gate.mjs +10 -10
- package/tests/backfill_task_rewards.mjs +1 -1
- package/tests/canonical_profile_url.mjs +1 -3
- package/tests/claim_action.mjs +4 -1
- package/tests/claim_from_task_and_home.mjs +127 -0
- package/tests/{box_ship_permissions.mjs → cli_allowlist_permissions.mjs} +5 -5
- package/tests/cli_sessions.mjs +1 -1
- package/tests/consumer_layout_boot.mjs +2 -0
- package/tests/context_pack.mjs +13 -13
- package/tests/copy_desk_page_docx.mjs +33 -2
- package/tests/copy_inventory.mjs +7 -7
- package/tests/core_upgrade_runner.mjs +6 -6
- package/tests/credit_grant.mjs +2 -2
- package/tests/criterion_suggest.mjs +1 -1
- package/tests/deploy_divergence_line.mjs +11 -11
- package/tests/design_tokens_sync.mjs +3 -2
- package/tests/diagram_facts_offset.mjs +1 -1
- package/tests/do_api.mjs +106 -0
- package/tests/feedback_latest.mjs +122 -0
- package/tests/fitness.mjs +44 -42
- package/tests/fitness_ratchets.mjs +2 -2
- package/tests/gate_approvals.mjs +0 -1
- package/tests/github_push_land_proof.mjs +1 -1
- package/tests/go_live.mjs +3 -3
- package/tests/goal_advisory.mjs +3 -3
- package/tests/goal_suggest.mjs +3 -3
- package/tests/government_abuse_matrix.mjs +21 -19
- package/tests/government_ownership_scope.mjs +33 -35
- package/tests/government_parity.mjs +2 -2
- package/tests/government_protected_surfaces.mjs +56 -37
- package/tests/government_require_permission.mjs +3 -3
- package/tests/government_seed.mjs +37 -4
- package/tests/government_session_scope.mjs +92 -366
- package/tests/hall_audit.mjs +1 -1
- package/tests/hall_error_envelope.mjs +4 -0
- package/tests/hall_landing_boot.mjs +4 -1
- package/tests/hall_palette.mjs +1 -16
- package/tests/hall_record_world.mjs +6 -0
- package/tests/hall_tweak_editor.mjs +52 -1
- package/tests/helpers.mjs +1 -1
- package/tests/host_topology_skips.mjs +3 -4
- package/tests/html_comment_nesting.mjs +137 -0
- package/tests/infra_exec_paths.mjs +9 -10
- package/tests/init.mjs +4 -5
- package/tests/instance_manifest.mjs +18 -25
- package/tests/kickoff_checklist.mjs +1 -1
- package/tests/lib_sh_resolution.mjs +0 -221
- package/tests/local_preview.mjs +0 -12
- package/tests/migration_namespace.mjs +6 -6
- package/tests/module-scope-map.mjs +9 -9
- package/tests/module_api.mjs +2 -2
- package/tests/module_catalog.mjs +1 -1
- package/tests/module_cli.mjs +20 -20
- package/tests/module_contributions.mjs +6 -6
- package/tests/module_loader.mjs +6 -6
- package/tests/module_manifest.mjs +26 -17
- package/tests/module_route_rank.mjs +2 -2
- package/tests/module_store_publish.mjs +307 -0
- package/tests/module_store_publish_route.mjs +121 -0
- package/tests/module_store_registry_migration.mjs +70 -0
- package/tests/modules.mjs +56 -26
- package/tests/modules_route_wiring.mjs +1 -1
- package/tests/onboarding_route_signals.mjs +21 -31
- package/tests/onboarding_state.mjs +35 -49
- package/tests/paste_token_session_store.mjs +1 -1
- package/tests/permission_path.mjs +0 -3
- package/tests/platform_boot.mjs +1 -2
- package/tests/platform_visibility_gate.mjs +1 -1
- package/tests/profile_route.mjs +1 -6
- package/tests/project_modules_ui.mjs +17 -17
- package/tests/projects_hub.mjs +5 -5
- package/tests/projects_hub_app_step.mjs +138 -0
- package/tests/projects_hub_module_picker.mjs +77 -76
- package/tests/projects_hub_pre_uat.mjs +4 -5
- package/tests/provision.mjs +7 -7
- package/tests/provisioning_capacity.mjs +1 -1
- package/tests/provisioning_recommendations.mjs +2 -1
- package/tests/provisioning_starter_bundles.mjs +0 -22
- package/tests/publish_branch_route.mjs +11 -19
- package/tests/publish_manifest.mjs +2 -3
- package/tests/publish_reconciler.mjs +8 -8
- package/tests/push_path_brief.mjs +10 -9
- package/tests/rank_tier_single_source.mjs +1 -13
- package/tests/regrade_eligibility.mjs +1 -1
- package/tests/rename_history_restraint.mjs +1 -1
- package/tests/repo_map.mjs +12 -13
- package/tests/runner_drift.mjs +3 -21
- package/tests/sandbox_stage.mjs +57 -390
- package/tests/seam_wiring_guard.mjs +11 -11
- package/tests/search_isolation.mjs +3 -3
- package/tests/session_records.mjs +1 -1
- package/tests/session_rename_fallback.mjs +1 -22
- package/tests/session_start_freshness.mjs +3 -3
- package/tests/session_token_hash_db.mjs +1 -1
- package/tests/ship_card.mjs +1 -1
- package/tests/ship_ci_deploy.mjs +17 -17
- package/tests/ship_error_shape.mjs +1 -1
- package/tests/ship_premerge.mjs +1 -1
- package/tests/ship_resume.mjs +1 -1
- package/tests/skill_preflight.mjs +2 -2
- package/tests/skip_is_not_pass.mjs +1 -1
- package/tests/task_visual_slots.mjs +31 -0
- package/tests/terms_acceptance.mjs +2 -2
- package/tests/upgrade.mjs +4 -4
- package/tests/watch_sealed_floor.mjs +0 -1
- package/tests/wizard_draft_resume.mjs +2 -2
- package/tests/wizard_intent_resume.mjs +21 -10
- package/tests/wizard_preselect_why.mjs +18 -18
- package/docs/onboarding/browser-terminal-guide.md +0 -73
- package/docs/recipes/managed-settings-remote-control.md +0 -416
- package/modules/dev-box/CLAUDE.md +0 -15
- package/modules/dev-box/box-access.js +0 -623
- package/modules/dev-box/box-credential.js +0 -94
- package/modules/dev-box/box-onboard.js +0 -486
- package/modules/dev-box/boxes.js +0 -1038
- package/modules/dev-box/db.js +0 -39
- package/modules/dev-box/module.json +0 -19
- package/modules/dev-box/routes/box.js +0 -1223
- package/scripts/gds/box-auth-check.js +0 -160
- package/scripts/gds/box-infra.js +0 -321
- package/scripts/gds/box-sync.js +0 -216
- package/scripts/gds/box.js +0 -1332
- package/scripts/gds/cf-tunnel.js +0 -558
- package/scripts/gds/smoke-box.sh +0 -150
- package/scripts/gds/tree-preflight.js +0 -241
- package/src/bongos/app-pair.js +0 -172
- package/tests/app_pair.mjs +0 -168
- package/tests/box_access.mjs +0 -578
- package/tests/box_auth_check.mjs +0 -114
- package/tests/box_code_staleness.mjs +0 -129
- package/tests/box_connect_e2e.mjs +0 -196
- package/tests/box_cost.mjs +0 -70
- package/tests/box_credential.mjs +0 -125
- package/tests/box_dns_repoint.mjs +0 -153
- package/tests/box_env.mjs +0 -64
- package/tests/box_host_keys.mjs +0 -126
- package/tests/box_infra_resolve.mjs +0 -246
- package/tests/box_onboard.mjs +0 -317
- package/tests/box_scope_session.mjs +0 -119
- package/tests/box_sweep_docs.mjs +0 -119
- package/tests/box_sync.mjs +0 -55
- package/tests/box_sync_scope_report.mjs +0 -126
- package/tests/box_task_scope.mjs +0 -169
- package/tests/box_task_scope_pause.mjs +0 -66
- package/tests/box_terminal_ssrf.mjs +0 -96
- package/tests/boxes.mjs +0 -1585
- package/tests/cf_ruleset_preflight.mjs +0 -142
- package/tests/cf_tunnel.mjs +0 -496
- package/tests/docs_scrubber_damage.mjs +0 -111
- package/tests/module_scope_active_claims.mjs +0 -94
- package/tests/ship_api_client_pathspec.mjs +0 -100
- package/tests/tree_preflight.mjs +0 -243
|
@@ -8,9 +8,9 @@
|
|
|
8
8
|
// 05-versioning ← live versions (id/status)
|
|
9
9
|
// 03-drachmae-karma ← per-piece backing-task status + seeded-achievement count
|
|
10
10
|
// 04-architecture ← per-piece backing-task status: the ADR 0024 memory
|
|
11
|
-
// chain + the
|
|
12
|
-
//
|
|
13
|
-
//
|
|
11
|
+
// chain + the machine → prod ship flow, in one
|
|
12
|
+
// "complete architecture" map (consolidated under
|
|
13
|
+
// task 1059)
|
|
14
14
|
//
|
|
15
15
|
// It writes each .mmd from a template, renders the SVG (crisp, pannable) + PNG
|
|
16
16
|
// (fallback) via scripts/render-diagrams.sh, and rewrites the data-driven slices
|
|
@@ -332,17 +332,18 @@ function drachmaeKarmaMmd(f) {
|
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
// 04-architecture. The complete picture: where a builder's work runs and how it
|
|
335
|
-
// reaches production, with the per-builder memory layer (ADR 0024) folded in
|
|
336
|
-
//
|
|
337
|
-
//
|
|
338
|
-
//
|
|
339
|
-
// backing Bongos task is 'shipped', dotted/PLANNED otherwise — so the map is an
|
|
340
|
-
// honest snapshot that flips itself as pieces ship (or regresses if one is
|
|
335
|
+
// reaches production, with the per-builder memory layer (ADR 0024) folded in
|
|
336
|
+
// (task 1059). Conceptual like 03: every feature-piece + flow edge is LIVE/solid
|
|
337
|
+
// iff its backing Bongos task is 'shipped', dotted/PLANNED otherwise — so the map
|
|
338
|
+
// is an honest snapshot that flips itself as pieces ship (or regresses if one is
|
|
341
339
|
// reopened). Pieces → live task ids:
|
|
342
340
|
// memory layer : 273 schema · 274 sync-on-ship · 275 pull-on-start · 276 isolation
|
|
343
|
-
//
|
|
344
|
-
//
|
|
345
|
-
//
|
|
341
|
+
// ship flow : 1025 publish-via-server · 1028 GitHub App push credential
|
|
342
|
+
// Work runs on the builder's own machine, in a clone of the instance repo. It
|
|
343
|
+
// reaches main one of two ways (ship-deploy-target.js `pushVia`): a machine
|
|
344
|
+
// signed in to GitHub pushes its branch and opens the PR itself; a checkout with
|
|
345
|
+
// no push credential uploads the branch as a git bundle and the SERVER pushes it
|
|
346
|
+
// with its own credential (ADR 0055).
|
|
346
347
|
function architectureMmd(f) {
|
|
347
348
|
const c = f.conceptual;
|
|
348
349
|
const { host } = brand();
|
|
@@ -370,16 +371,16 @@ function architectureMmd(f) {
|
|
|
370
371
|
? 'SRVMEM -->|"pull on session start"| LOCAL'
|
|
371
372
|
: 'SRVMEM -.->|"pull on session start — PLANNED"| LOCAL';
|
|
372
373
|
|
|
373
|
-
// ---
|
|
374
|
+
// --- ship flow: the server's push credential + closing note ---
|
|
374
375
|
const pushCred = shipped(1028)
|
|
375
376
|
? 'GitHub App, short-lived tokens'
|
|
376
377
|
: 'standing push PAT (GitHub App pending — 1028)';
|
|
377
|
-
//
|
|
378
|
-
//
|
|
379
|
-
//
|
|
380
|
-
const chainLive = [
|
|
378
|
+
// Both ways onto main LIVE? NB the deploy leg is the standalone AUTO-PULL
|
|
379
|
+
// (ADR 0108/0129), not a task-gated GitHub-Actions CI job — so 859 (CI deploy)
|
|
380
|
+
// is intentionally NOT in this set.
|
|
381
|
+
const chainLive = [1025, 1028].every(shipped);
|
|
381
382
|
const closingNote = chainLive
|
|
382
|
-
? '
|
|
383
|
+
? 'Both ways onto main work today: a machine signed in to GitHub pushes its own branch, and a checkout without a push credential uploads it for the server to push. Either way the instance auto-pulls and redeploys.'
|
|
383
384
|
: `Still landing (PLANNED): the server-mediated publish (${tag(1025)} · 1025) and the GitHub App push credential (${tag(1028)} · 1028).`;
|
|
384
385
|
|
|
385
386
|
// Product-neutral runtime label: the instance's own product name (branding),
|
|
@@ -389,30 +390,22 @@ function architectureMmd(f) {
|
|
|
389
390
|
const appLabel = productName && productName !== 'Cloud Bongos' ? productName : 'app';
|
|
390
391
|
|
|
391
392
|
// Layout: ELK engine, top-down (task 1066). ELK minimizes edge crossings far
|
|
392
|
-
// better than the default renderer
|
|
393
|
-
//
|
|
394
|
-
//
|
|
395
|
-
//
|
|
396
|
-
//
|
|
397
|
-
// memory
|
|
398
|
-
//
|
|
399
|
-
//
|
|
400
|
-
//
|
|
401
|
-
//
|
|
402
|
-
//
|
|
403
|
-
//
|
|
404
|
-
//
|
|
405
|
-
//
|
|
406
|
-
//
|
|
407
|
-
//
|
|
408
|
-
// instead of detouring the full height past a mid-stack GitHub. The deploy is
|
|
409
|
-
// the STANDALONE auto-pull (ADR 0108/0129): merge to the instance's own main →
|
|
410
|
-
// the server pulls its own repo → migrate/regenerate/restart → the live app —
|
|
411
|
-
// NOT a GitHub-Actions push-deploy (that was the reference monorepo's model).
|
|
412
|
-
// NOTE on direction: we keep TB,
|
|
413
|
-
// not a repo-on-the-left LR/RL — the flow is an ~8-deep linear chain, so a
|
|
414
|
-
// sideways layout stretches into an unreadable ~5:1 strip; top-down keeps a
|
|
415
|
-
// legible aspect.
|
|
393
|
+
// better than the default renderer. Two declutter moves: (1) the INTRA-cluster
|
|
394
|
+
// wiring (worker→its files, api→db/rank, db→memory-store) is dropped —
|
|
395
|
+
// co-location inside a labelled subgraph already says "these belong together";
|
|
396
|
+
// only the CROSS-cluster flow (the numbered ship steps, memory sync,
|
|
397
|
+
// claim/ship) is drawn. (2) Low-signal annotation edges (DB-is-king,
|
|
398
|
+
// memory-follows-you) are folded into node labels. WATERFALL ordering (task
|
|
399
|
+
// 1073, off Lars's "put the GitHub box last"): subgraphs are declared in flow
|
|
400
|
+
// order MACHINE→SERVER→GH, and the live app (the instance's product runtime)
|
|
401
|
+
// is pulled OUT of the SERVER cluster into its own terminal node at the very
|
|
402
|
+
// bottom (annotated "same server · same Node process" so it stays honest), so
|
|
403
|
+
// the deploy is the LAST forward step instead of an edge looping back UP into
|
|
404
|
+
// the server. The deploy is the STANDALONE auto-pull (ADR 0108/0129): merge to
|
|
405
|
+
// the instance's own main → the server pulls its own repo →
|
|
406
|
+
// migrate/regenerate/restart → the live app — NOT a GitHub-Actions push-deploy
|
|
407
|
+
// (that was the reference monorepo's model). NOTE on direction: we keep TB,
|
|
408
|
+
// not LR — a sideways layout stretches the chain into an unreadable strip.
|
|
416
409
|
const lines = [
|
|
417
410
|
'---',
|
|
418
411
|
'title: The complete architecture — where your work runs and how it reaches production (AUTO-GENERATED from live facts — do not hand-edit; see scripts/gds/gen-diagrams.js)',
|
|
@@ -420,18 +413,10 @@ function architectureMmd(f) {
|
|
|
420
413
|
' layout: elk',
|
|
421
414
|
'---',
|
|
422
415
|
'flowchart TB',
|
|
423
|
-
' subgraph
|
|
424
|
-
'
|
|
425
|
-
'
|
|
426
|
-
'',
|
|
427
|
-
' subgraph BOX["DEV BOX — a machine WE create on DigitalOcean (gated · revocable · audited; Metic+ may instead clone locally)"]',
|
|
428
|
-
' WORKER["Claude Code WORKER\\n(opens files · runs commands · runs the /builder-* skills)"]',
|
|
429
|
-
` CODE["the code — git clone + per-builder worktrees (.claude/worktrees/*)\\nfor sub-Metic builders it lives ONLY here · CLAUDE.md is DESCRIPTIVE only"]`,
|
|
416
|
+
' subgraph MACHINE["YOUR MACHINE — a clone of the instance repo"]',
|
|
417
|
+
' WORKER["Claude Code — the desktop app or the terminal\\n(opens files · runs commands · runs the /builder-* skills)"]',
|
|
418
|
+
' CODE["the code — git clone + per-task worktrees (.claude/worktrees/*)\\nCLAUDE.md is DESCRIPTIVE only"]',
|
|
430
419
|
' LOCAL["local ~/.claude memory\\nMAP = MEMORY.md — a one-line index loaded EVERY session\\n(a guard + auto-tidy keep it light; ADR 0074)\\n+ drawer of full notes, loaded only on demand"]',
|
|
431
|
-
' ORIGIN["credential-less git origin\\n(NO GitHub push secret on the box — by design)"]',
|
|
432
|
-
` BOXTOK["box-scoped Bongos token\\n(deny-by-default: bootstrap endpoints only;\\nrejected for branch upload → re-auth first — ${tag(919)})"]`,
|
|
433
|
-
` PREVIEW["sandbox preview server on :3000\\n→ a per-builder sandbox URL (${tag(897)})"]`,
|
|
434
|
-
` SWITCH["on / off + browser terminal\\n(desktop app ${tag(904)} · ttyd-over-tunnel ${tag(774)})"]`,
|
|
435
420
|
' end',
|
|
436
421
|
'',
|
|
437
422
|
` subgraph SERVER["THE INSTANCE SERVER — ${host} (the authority AND production)"]`,
|
|
@@ -440,7 +425,7 @@ function architectureMmd(f) {
|
|
|
440
425
|
' DB["Postgres — tasks · claims · versions · builders.rank\\ncredit_log · grades · idea_inbox · builder_memory\\n(KING for work-state + permissions; CLAUDE.md only describes it)"]',
|
|
441
426
|
' RANK["auth.requireRank — checked per request, NO caching\\n(ADR 0016: a demotion takes effect on the next request)"]',
|
|
442
427
|
` SRVMEM["server-side builder_memory store\\n${memLead}: per-builder · isolated · forensic read at Metic+ (ADR 0157)\\nyour memory follows you across machines & worktrees\\n/recall fetches only the relevant subset (ADR 0060)\\n(${memStatus})"]`,
|
|
443
|
-
` PUSHTOK["server-held push credential\\n(${pushCred} —
|
|
428
|
+
` PUSHTOK["server-held push credential\\n(${pushCred} — for a checkout that has none of its own)"]`,
|
|
444
429
|
' DEPLOY["auto-pull deploy (ADR 0129)\\na timer pulls THIS instance repo every ~2 min →\\nnpm ci if the pin changed → migrate → regenerate docs → restart → healthz"]',
|
|
445
430
|
' end',
|
|
446
431
|
'',
|
|
@@ -450,17 +435,14 @@ function architectureMmd(f) {
|
|
|
450
435
|
'',
|
|
451
436
|
` LIVEAPP["the live ${appLabel} — ${host}\\n(same server · same Node process as /api/bongos/*)"]`,
|
|
452
437
|
'',
|
|
453
|
-
'
|
|
454
|
-
'
|
|
455
|
-
'
|
|
456
|
-
'
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
' MAIN -->|"6 · the instance auto-pulls its own main"| DEPLOY',
|
|
460
|
-
' DEPLOY -->|"7 · migrate · regenerate docs · restart"| LIVEAPP',
|
|
438
|
+
' WORKER -->|"1 · edit + commit"| CODE',
|
|
439
|
+
' WORKER -->|"2 · push the branch + open a PR (a machine signed in to GitHub)"| MAIN',
|
|
440
|
+
flow('WORKER', 1025, '2 · or upload the branch as a git bundle (no push credential here)', 'API'),
|
|
441
|
+
flow('API', 1025, `3 · the server pushes it + opens the PR (${tag(1025)})`, 'MAIN'),
|
|
442
|
+
' MAIN -->|"4 · the instance auto-pulls its own main"| DEPLOY',
|
|
443
|
+
' DEPLOY -->|"5 · migrate · regenerate docs · restart"| LIVEAPP',
|
|
461
444
|
' CORE --- API',
|
|
462
445
|
' PUSHTOK -.-> API',
|
|
463
|
-
' ORIGIN -. "direct push blocked" .-> MAIN',
|
|
464
446
|
' API -. "claim / ship / cost" .-> WORKER',
|
|
465
447
|
` ${pushEdge}`,
|
|
466
448
|
` ${pullEdge}`,
|
|
@@ -500,20 +482,16 @@ function rebuildAssertions(prev, f) {
|
|
|
500
482
|
pending_tasks: ids.filter((id) => !shipped(id)).map(entry),
|
|
501
483
|
});
|
|
502
484
|
|
|
503
|
-
// 04-architecture — the ADR 0024 memory chain + the
|
|
504
|
-
// flow
|
|
505
|
-
const arch = split([273, 274, 275, 276,
|
|
485
|
+
// 04-architecture — the ADR 0024 memory chain + the machine → prod ship
|
|
486
|
+
// flow (task 1059). A piece is LIVE iff its backing task is shipped.
|
|
487
|
+
const arch = split([273, 274, 275, 276, 1025, 1028]);
|
|
506
488
|
next.architecture = {
|
|
507
489
|
diagram: '04-architecture',
|
|
508
490
|
_comment:
|
|
509
|
-
"Pieces of 04-architecture gated on a backing Bongos task. A piece is LIVE iff its task is 'shipped'; live_tasks must ALL be shipped, pending_tasks must NOT yet be. Rebuilt by scripts/gds/gen-diagrams.js in lockstep with the diagram, so this is the drift checker's backstop. The
|
|
491
|
+
"Pieces of 04-architecture gated on a backing Bongos task. A piece is LIVE iff its task is 'shipped'; live_tasks must ALL be shipped, pending_tasks must NOT yet be. Rebuilt by scripts/gds/gen-diagrams.js in lockstep with the diagram, so this is the drift checker's backstop. The machine/server/GitHub topology is structural (not task-gated); these are the LIVE/PLANNED markers. MEMORY layer (ADR 0024): 273 schema / 274 sync-on-ship / 275 pull-on-start / 276 isolation. Ship flow: 1025 (server-mediated publish, for a checkout with no push credential), 1028 (GitHub App push credential). The deploy leg is the standalone AUTO-PULL (ADR 0108/0129), not a task-gated GitHub-Actions CI job, so 859 is intentionally absent.",
|
|
510
492
|
live_tasks: arch.live_tasks,
|
|
511
493
|
pending_tasks: arch.pending_tasks,
|
|
512
494
|
};
|
|
513
|
-
// Drop the two slices this diagram replaced so the file (and drift checker)
|
|
514
|
-
// never carry stale keys after the 04+06 consolidation.
|
|
515
|
-
delete next.server_repo_memory;
|
|
516
|
-
delete next.dev_box;
|
|
517
495
|
|
|
518
496
|
// 03-drachmae-karma — bounty + karma pieces (D_SHIP/D_ACH have no task gate).
|
|
519
497
|
const dk = split([284, 286, 282, 245, 248, 246]);
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
// interpretive prose stays put while the file list / signatures can't silently drift.
|
|
12
12
|
//
|
|
13
13
|
// Zero-dependency on purpose: the codebase is CommonJS JS, and a portable-core capability must
|
|
14
|
-
// regenerate in CI and on
|
|
14
|
+
// regenerate in CI and on any checkout with no native build / no node-gyp / no WASM grammar to
|
|
15
15
|
// fetch (the whole point of Paths B+C is keeping every instance navigable cheaply). A line+regex
|
|
16
16
|
// extractor is accurate enough for an *advisory* navigation aid (it is not a compiler input). A
|
|
17
17
|
// richer tree-sitter/WASM backend can slot in behind extractFile() later for polyglot instances
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
// node scripts/gds/gen-repo-map.js --check-block # exit 2 only if a TRACKED nested block would change (the CI gate)
|
|
26
26
|
// node scripts/gds/gen-repo-map.js --check-whole # exit 2 only if docs/repo-map.md would change
|
|
27
27
|
// node scripts/gds/gen-repo-map.js --whole-only # WRITE docs/repo-map.md only; never touch the
|
|
28
|
-
// # tracked nested blocks (what a SPARSE
|
|
28
|
+
// # tracked nested blocks (what a SPARSE
|
|
29
29
|
// # checkout must use — task 1002962)
|
|
30
|
-
// docs/repo-map.md is GITIGNORED + regenerated at deploy
|
|
30
|
+
// docs/repo-map.md is GITIGNORED + regenerated at deploy since ADR 0110 (task 1926);
|
|
31
31
|
// only the nested-doc symbol blocks stay tracked, so CI gates the block bucket, not the whole file.
|
|
32
32
|
// node scripts/gds/gen-repo-map.js --json # print the extracted model as JSON (debug)
|
|
33
33
|
|
|
@@ -458,7 +458,7 @@ function injectBlock(existing, block) {
|
|
|
458
458
|
function main() {
|
|
459
459
|
// Two artifact BUCKETS, gated separately since ADR 0110 (task 1926):
|
|
460
460
|
// • 'whole' — docs/repo-map.md, which is now GITIGNORED and regenerated at
|
|
461
|
-
// deploy
|
|
461
|
+
// deploy (the gen-atlas.js model), so it carries no
|
|
462
462
|
// committed copy and two parallel branches can never collide on it.
|
|
463
463
|
// • 'block' — the generated symbol BLOCK inside each nested CLAUDE.md, which
|
|
464
464
|
// stays hand-written prose + a tracked block, so it MUST stay fresh in git.
|
|
@@ -472,16 +472,15 @@ function main() {
|
|
|
472
472
|
// 1002962). --whole-only regenerates the GITIGNORED docs/repo-map.md and leaves
|
|
473
473
|
// the TRACKED nested blocks alone.
|
|
474
474
|
//
|
|
475
|
-
// WHY a caller ever needs this: a
|
|
476
|
-
//
|
|
477
|
-
//
|
|
478
|
-
//
|
|
479
|
-
//
|
|
480
|
-
//
|
|
481
|
-
//
|
|
482
|
-
//
|
|
483
|
-
//
|
|
484
|
-
// checkout may produce them.
|
|
475
|
+
// WHY a caller ever needs this: a SPARSE checkout materializes only part of the
|
|
476
|
+
// tree. The block ordering is `b.refs - a.refs || name`, and `refs` counts
|
|
477
|
+
// references across the VISIBLE corpus — so a checkout with 7 of 20 modules
|
|
478
|
+
// computes different counts and emits a legitimately different block. Written
|
|
479
|
+
// into a tracked file that dirties the working tree, and the NEXT `git pull`
|
|
480
|
+
// aborts with "local changes would be overwritten" — a silent, permanent sync
|
|
481
|
+
// deadlock (one checkout sat 257 commits behind for three days). A sparse
|
|
482
|
+
// checkout CONSUMES these blocks; they arrive correct with the pull, generated
|
|
483
|
+
// by CI from the whole tree. Only a full checkout may produce them.
|
|
485
484
|
const wholeOnly = process.argv.includes('--whole-only');
|
|
486
485
|
const model = buildModel();
|
|
487
486
|
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
// node scripts/gds/gen-session-index.js --check-block # exit 2 only if the tracked CLAUDE.md §13 snippet drifts (CI gate)
|
|
27
27
|
// node scripts/gds/gen-session-index.js --check-whole # exit 2 only if docs/session-log-index.md drifts
|
|
28
28
|
// node scripts/gds/gen-session-index.js --whole-only # WRITE the index only; never touch the tracked
|
|
29
|
-
// # CLAUDE.md snippet (sparse
|
|
30
|
-
// docs/session-log-index.md is GITIGNORED + regenerated at deploy
|
|
29
|
+
// # CLAUDE.md snippet (sparse-checkout use; task 1002962)
|
|
30
|
+
// docs/session-log-index.md is GITIGNORED + regenerated at deploy since ADR 0110 (task 1926).
|
|
31
31
|
// node scripts/gds/gen-session-index.js --json # print the parsed entries as JSON (debug)
|
|
32
32
|
|
|
33
33
|
const fs = require('node:fs');
|
|
@@ -164,7 +164,7 @@ function computeWrites() {
|
|
|
164
164
|
const writes = [];
|
|
165
165
|
|
|
166
166
|
// Two buckets (ADR 0110, task 1926): 'whole' = docs/session-log-index.md, now
|
|
167
|
-
// GITIGNORED + regenerated at deploy
|
|
167
|
+
// GITIGNORED + regenerated at deploy (no committed copy → no branch
|
|
168
168
|
// collisions); 'block' = the bounded CLAUDE.md §13 snippet, still tracked, so it
|
|
169
169
|
// stays a HARD CI gate. main() gates them separately (--check-block vs --check-whole).
|
|
170
170
|
const idxNext = renderIndex(entries);
|
|
@@ -197,11 +197,11 @@ function main() {
|
|
|
197
197
|
return;
|
|
198
198
|
}
|
|
199
199
|
// WRITE-side bucket selection — the sibling of the --check-* flags (task 1002962,
|
|
200
|
-
// the gen-repo-map --whole-only twin).
|
|
201
|
-
//
|
|
202
|
-
//
|
|
203
|
-
//
|
|
204
|
-
//
|
|
200
|
+
// the gen-repo-map --whole-only twin). On a SPARSE checkout, writing the TRACKED
|
|
201
|
+
// bucket dirties the tree and the next `git pull` aborts on "local changes would
|
|
202
|
+
// be overwritten" — a silent, permanent sync deadlock. A sparse checkout
|
|
203
|
+
// regenerates only the gitignored artifact; the tracked CLAUDE.md §13 snippet
|
|
204
|
+
// arrives with the pull, generated from the whole tree.
|
|
205
205
|
const wholeOnly = process.argv.includes('--whole-only');
|
|
206
206
|
const all = computeWrites().writes;
|
|
207
207
|
const writes = wholeOnly ? all.filter((w) => w.bucket === 'whole') : all;
|
|
@@ -1,24 +1,18 @@
|
|
|
1
|
-
// scripts/gds/http-api-client.js — the
|
|
2
|
-
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// (do-api.js's design note: the box subsystem keeps "ONE shape for every external
|
|
6
|
-
// API"). This base IS that one shape.
|
|
1
|
+
// scripts/gds/http-api-client.js — the request skeleton behind the control
|
|
2
|
+
// plane's JSON-over-HTTP client, scripts/gds/do-api.js (DoApi, DigitalOcean): a
|
|
3
|
+
// thin, injectable-transport, dry-run-by-default wrapper. It is kept apart from
|
|
4
|
+
// do-api.js so the ONE request shape stays reusable by any future client.
|
|
7
5
|
//
|
|
8
|
-
//
|
|
9
|
-
// - the constructor's OWN live-mode validation (
|
|
10
|
-
//
|
|
11
|
-
// - requestInit() — extra fetch options (Cloudflare pins an IPv4 dispatcher,
|
|
12
|
-
// #771; DigitalOcean sends none);
|
|
6
|
+
// Per-API differences go in a subclass via three small hooks:
|
|
7
|
+
// - the constructor's OWN live-mode validation (its "missing X" messages);
|
|
8
|
+
// - requestInit() — extra fetch options (DigitalOcean sends none);
|
|
13
9
|
// - detectError() — what counts as a failure + how the message is extracted
|
|
14
|
-
// (DigitalOcean = non-2xx → message/id
|
|
15
|
-
// envelope and joins errors[]).
|
|
10
|
+
// (DigitalOcean = non-2xx → message/id).
|
|
16
11
|
//
|
|
17
|
-
//
|
|
18
|
-
// tests/cf_tunnel.mjs (CfTunnelApi).
|
|
12
|
+
// Pinned by tests/do_api.mjs.
|
|
19
13
|
|
|
20
14
|
// Build a distinct, named API-error class. Each client makes its own so the
|
|
21
|
-
// `instanceof` checks the tests rely on (DoApiError
|
|
15
|
+
// `instanceof` checks the tests rely on (DoApiError) stay meaningful
|
|
22
16
|
// and the `.name` / `.code` carried on every thrown error survive unchanged.
|
|
23
17
|
function makeApiError(name, code) {
|
|
24
18
|
return class ApiError extends Error {
|
|
@@ -46,13 +40,12 @@ class JsonHttpApi {
|
|
|
46
40
|
this._ErrorClass = ErrorClass;
|
|
47
41
|
}
|
|
48
42
|
|
|
49
|
-
// Extra fetch init merged into every LIVE request. Base sends none
|
|
50
|
-
// overrides to pin the IPv4 dispatcher (its token is IP-locked, #771).
|
|
43
|
+
// Extra fetch init merged into every LIVE request. Base sends none.
|
|
51
44
|
requestInit() { return {}; }
|
|
52
45
|
|
|
53
46
|
// Inspect a completed response. Return an error MESSAGE string to throw, or null
|
|
54
47
|
// to accept. Base fails on a non-2xx HTTP status (DigitalOcean surfaces
|
|
55
|
-
// message/id)
|
|
48
|
+
// message/id).
|
|
56
49
|
detectError(res, json) {
|
|
57
50
|
if (!res.ok) return (json && (json.message || json.id)) || `HTTP ${res.status}`;
|
|
58
51
|
return null;
|
package/scripts/gds/init.js
CHANGED
|
@@ -79,7 +79,7 @@ const { detectStack, formatStackSummary } = require('./adopt-detect'); // ADR 01
|
|
|
79
79
|
const { resolveBacklogTasks, DEFAULT_MAX: BACKLOG_MAX } = require('./adopt-import'); // ADR 0121 §Decision 3 (task 2044): import an existing backlog
|
|
80
80
|
const { preflightAdopt, formatPreflight } = require('./adopt-preflight'); // ADR 0121 §Decision 5 (task 2045): the accept-gated conflict pre-flight
|
|
81
81
|
|
|
82
|
-
const KNOWN_MODULES = ['game', 'art-pipeline', 'discord'
|
|
82
|
+
const KNOWN_MODULES = ['game', 'art-pipeline', 'discord'];
|
|
83
83
|
|
|
84
84
|
// The provisioning hosting shapes — a small mirror of modules/provisioning's
|
|
85
85
|
// HOSTING_SHAPES. init deliberately does NOT import the (optional) provisioning
|
|
@@ -167,7 +167,7 @@ const FILE_ALLOWLIST = [
|
|
|
167
167
|
path: 'tests/lib_sh_resolution.mjs',
|
|
168
168
|
classes: ['token'],
|
|
169
169
|
reason:
|
|
170
|
-
'Carries the host-identity scan pattern it runs over the
|
|
170
|
+
'Carries the host-identity scan pattern it runs over the bash smoke scripts — a detector '
|
|
171
171
|
+ 'pattern, the same case as fitness-checks-identity.js.',
|
|
172
172
|
},
|
|
173
173
|
{
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// lint-infra-exec.js — task 2137 (ADR 0108 configurable-root). The dry-run/lint that proves every
|
|
4
4
|
// host systemd unit running a CORE script still resolves AFTER the R89 split.
|
|
5
5
|
//
|
|
6
|
-
// The units (
|
|
6
|
+
// The units (cohost-*, provision-*, search-index-db) keep living in the instance repo
|
|
7
7
|
// (infra/ is host topology) while scripts/gds/ moves into node_modules/@bongos/core, so each
|
|
8
8
|
// ExecStart runs through infra/core-node.sh, which resolves the script under the instance root OR
|
|
9
9
|
// its node_modules/@bongos/core (both layouts). "Resolves in a consumer layout" is provable from
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
// scripts/gds/local-preview-lib.js — core of the LOCAL sandbox launcher (task 1056).
|
|
2
2
|
//
|
|
3
|
-
// Gives a builder working on a LOCAL full clone
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
// BuildersHall), degraded-DB exactly like the box sandbox.
|
|
3
|
+
// Gives a builder working on a LOCAL full clone a private game preview (ADR
|
|
4
|
+
// 0044/0046/0052) served at http://localhost:<port> on their OWN machine: no
|
|
5
|
+
// public URL, $0. It runs the ADR 0052 game-only entry (src/preview-server.js),
|
|
6
|
+
// which serves ONLY the playable game (no /api/bongos, no BuildersHall),
|
|
7
|
+
// degraded-DB.
|
|
9
8
|
//
|
|
10
|
-
// The preview is a long-running DETACHED background process
|
|
11
|
-
//
|
|
12
|
-
// box: edit -> restart -> refresh the browser tab.
|
|
9
|
+
// The preview is a long-running DETACHED background process. The edit loop is:
|
|
10
|
+
// edit -> restart -> refresh the browser tab.
|
|
13
11
|
//
|
|
14
12
|
// Everything is pure + injectable (deps.fs / deps.spawn / deps.kill /
|
|
15
13
|
// deps.fetchImpl / deps.env / deps.*Path) so tests/local_preview.mjs can exercise
|
|
@@ -25,18 +23,6 @@ const path = require('node:path');
|
|
|
25
23
|
const DEFAULT_PORT = 3100;
|
|
26
24
|
const HOST = '127.0.0.1';
|
|
27
25
|
|
|
28
|
-
// Box-only markers (ADR 0031/0044). ANY one ⇒ this is a provisioned dev box, NOT
|
|
29
|
-
// a laptop. Deliberately broader than /etc/otb/box.env alone: a box whose box.env
|
|
30
|
-
// was lost or is unreadable must still be recognized as a box, never mistaken for
|
|
31
|
-
// a laptop — because the laptop path hands back a http://localhost preview URL,
|
|
32
|
-
// which is unreachable from the builder's own browser when the server is on a
|
|
33
|
-
// remote box (the task-1443 footgun: "the link is giving me localhost"). box.env
|
|
34
|
-
// is the canonical marker; box-preview (the preview control command) and the
|
|
35
|
-
// box-game-preview.service unit are written on every box and survive an
|
|
36
|
-
// unreadable/empty box.env, so they're the resilient backstops.
|
|
37
|
-
const BOX_ENV_PATH = '/etc/otb/box.env';
|
|
38
|
-
const BOX_PREVIEW_WRAPPER = '/usr/local/bin/box-preview';
|
|
39
|
-
const BOX_SERVICE_UNIT = '/etc/systemd/system/box-game-preview.service';
|
|
40
26
|
// scripts/gds/ -> repo root. Absolute + cwd-independent so staging works no
|
|
41
27
|
// matter where ship.js is invoked from.
|
|
42
28
|
const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
@@ -62,22 +48,6 @@ function hasGameEntry(deps = {}) {
|
|
|
62
48
|
return f.existsSync(previewEntry(deps));
|
|
63
49
|
}
|
|
64
50
|
|
|
65
|
-
// Is this a provisioned dev box (ADR 0031/0044), i.e. NOT a laptop? True if any
|
|
66
|
-
// box-only marker is present. Pure + injectable (deps.fs + per-marker path
|
|
67
|
-
// overrides) like everything else here, and honors the dep names sandbox-stage.js
|
|
68
|
-
// already injects (deps.boxEnvPath / deps.previewWrapper) so a single call site
|
|
69
|
-
// drives both. Used to keep the localhost local-preview path from EVER being
|
|
70
|
-
// chosen on a box — see the BOX_* marker note above (task 1443).
|
|
71
|
-
function onBox(deps = {}) {
|
|
72
|
-
const f = deps.fs || fs;
|
|
73
|
-
const markers = [
|
|
74
|
-
deps.boxEnvPath || BOX_ENV_PATH,
|
|
75
|
-
deps.previewWrapper || BOX_PREVIEW_WRAPPER,
|
|
76
|
-
deps.boxServiceUnit || BOX_SERVICE_UNIT,
|
|
77
|
-
];
|
|
78
|
-
return markers.some((p) => { try { return f.existsSync(p); } catch { return false; } });
|
|
79
|
-
}
|
|
80
|
-
|
|
81
51
|
function readPid(deps = {}) {
|
|
82
52
|
const f = deps.fs || fs;
|
|
83
53
|
try {
|
|
@@ -152,8 +122,7 @@ async function health(deps = {}) {
|
|
|
152
122
|
|
|
153
123
|
module.exports = {
|
|
154
124
|
DEFAULT_PORT, HOST, REPO_ROOT,
|
|
155
|
-
BOX_ENV_PATH, BOX_PREVIEW_WRAPPER, BOX_SERVICE_UNIT,
|
|
156
125
|
previewPort, localUrl, healthUrl, previewEntry, pidPath, logPath,
|
|
157
|
-
hasGameEntry,
|
|
126
|
+
hasGameEntry, readPid, pidAlive, isRunning,
|
|
158
127
|
start, stop, restart, health,
|
|
159
128
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// scripts/gds/local-preview.js — the builder's control for the LOCAL game
|
|
3
|
-
// preview (task 1056
|
|
4
|
-
//
|
|
3
|
+
// preview (task 1056, ADR 0044). Runs the ADR 0052 game-only entry privately at
|
|
4
|
+
// http://localhost:<port>.
|
|
5
5
|
//
|
|
6
6
|
// npm run preview # start it (then open the URL)
|
|
7
7
|
// node scripts/gds/local-preview.js status is it up + the URL (default)
|
|
@@ -27,21 +27,8 @@ async function pollHealthy(ms = 20_000) {
|
|
|
27
27
|
|
|
28
28
|
const HINT = `Open ${lib.localUrl()} — your PRIVATE copy of the game (degraded DB, nothing shipped).`;
|
|
29
29
|
|
|
30
|
-
// This launcher is the LAPTOP analogue of box-preview. On a dev box it's the
|
|
31
|
-
// wrong tool: it binds http://localhost, which the builder's browser can't reach
|
|
32
|
-
// when the server is on a remote box — the "the link is giving me localhost"
|
|
33
|
-
// footgun (task 1443). Warn loudly and point at the box's HOSTED sandbox; warn,
|
|
34
|
-
// don't hard-fail, so an operator who really wants a box-local loopback still can.
|
|
35
|
-
function warnIfOnBox() {
|
|
36
|
-
if (!lib.onBox()) return;
|
|
37
|
-
console.error('⚠ You appear to be on a dev box. This LOCAL preview binds http://localhost —');
|
|
38
|
-
console.error(' your browser cannot reach the box\'s localhost. Your sandbox is the HOSTED url:');
|
|
39
|
-
console.error(' run /builder-stage (or box-preview status ) to get https://sandbox-<login>.<host> and refresh that tab.');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
30
|
(async () => {
|
|
43
31
|
const cmd = process.argv[2] || 'status';
|
|
44
|
-
if (cmd === 'start' || cmd === 'restart' || cmd === 'status' || cmd === 'url') warnIfOnBox();
|
|
45
32
|
switch (cmd) {
|
|
46
33
|
case 'start': {
|
|
47
34
|
const r = lib.start();
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// DISCIPLINE. Every migration SOURCE owns a distinct filename namespace, so stems can
|
|
15
15
|
// never collide across sources and each source's allocator counts only its own numbers:
|
|
16
16
|
// • CORE (the @bongos/core package's migrations/*.sql) → core_NNN_slug.sql
|
|
17
|
-
// • MODULE (modules/<key>/migrations/*.sql) → <key>_NNN_slug.sql (key:
|
|
17
|
+
// • MODULE (modules/<key>/migrations/*.sql) → <key>_NNN_slug.sql (key: art-pipeline → art_pipeline_)
|
|
18
18
|
// • INSTANCE (the host repo's migrations/instance/*.sql) → NNN_slug.sql (BARE — the instance owns the bare namespace)
|
|
19
19
|
//
|
|
20
20
|
// The core prefix ALONE is enough to break stem-equality with a bare instance file
|
|
@@ -42,7 +42,7 @@ const INSTANCE_NS = 'instance';
|
|
|
42
42
|
// Reserved namespace words a module key may not be (they name the core/instance sources).
|
|
43
43
|
const RESERVED_NS = new Set([CORE_NS, INSTANCE_NS]);
|
|
44
44
|
|
|
45
|
-
// SQL/filename-safe namespace prefix for a module key:
|
|
45
|
+
// SQL/filename-safe namespace prefix for a module key: art-pipeline → art_pipeline (matches
|
|
46
46
|
// fitness.js moduleNamespace + the existing economy_/lifecycle_ files).
|
|
47
47
|
function sqlNamespace(moduleKey) {
|
|
48
48
|
return String(moduleKey == null ? '' : moduleKey).replace(/-/g, '_');
|
|
@@ -70,7 +70,7 @@ const RENAMED_MODULE_PREFIXES = { government: new Set(['governance']) };
|
|
|
70
70
|
|
|
71
71
|
const BARE_RE = /^(\d{3,})_(.+)\.sql$/;
|
|
72
72
|
// A prefix is a lowercase word (letters/digits/underscores) starting with a letter,
|
|
73
|
-
// then `_NNN_`. Lazy so `
|
|
73
|
+
// then `_NNN_`. Lazy so `art_pipeline_003_x` splits as prefix=art_pipeline, num=003 (not art/pipeline).
|
|
74
74
|
const PREFIXED_RE = /^([a-z][a-z0-9_]*?)_(\d{3,})_(.+)\.sql$/;
|
|
75
75
|
|
|
76
76
|
// Parse a migration basename into { prefix, number, slug, bare, ok }. A non-migration
|