@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
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.1075",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.1075",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.1075",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/release-notes.json
CHANGED
|
@@ -7743,5 +7743,89 @@
|
|
|
7743
7743
|
"id": "1004313",
|
|
7744
7744
|
"text": "Tweak Mode is live on cloudbongos.com, and the artist gate is off. Artists can now open the lofi studio, take a whole page, rewrite it (in the studio or in Word), and approve the finished page before it ships. The seven old pe"
|
|
7745
7745
|
}
|
|
7746
|
+
],
|
|
7747
|
+
"1.19.1074": [
|
|
7748
|
+
{
|
|
7749
|
+
"id": "1004361",
|
|
7750
|
+
"text": "Fixed the test that had been blocking every new release of the platform since last evening. A test's sample module was missing the version number that modules now need, so the release step refused to run. With it fixed, the wa"
|
|
7751
|
+
},
|
|
7752
|
+
{
|
|
7753
|
+
"id": "1003895",
|
|
7754
|
+
"text": "The dev box's stored data is removed from the database: its four tables and the leftover dev-box login tokens. A fresh backup was taken first. Nothing else changes for builders."
|
|
7755
|
+
},
|
|
7756
|
+
{
|
|
7757
|
+
"id": "1004351",
|
|
7758
|
+
"text": "New projects now get a step that says we host their Builders Hall and asks where their app should run. Render is shown as coming soon; for now they can decide later."
|
|
7759
|
+
},
|
|
7760
|
+
{
|
|
7761
|
+
"id": "1003894",
|
|
7762
|
+
"text": "The leftover dev-box login tokens can no longer reach anything, and the three dev-box permissions are gone from every rank. Nobody's other permissions change. Sign-in and the rank and permission screens work as before."
|
|
7763
|
+
},
|
|
7764
|
+
{
|
|
7765
|
+
"id": "1004358",
|
|
7766
|
+
"text": "Tweak Mode's before-and-after screenshots can now be attached to a tweak. Every upload was being refused as too large, even though each picture was only about 100 KB, because a general size limit checked the upload before the"
|
|
7767
|
+
},
|
|
7768
|
+
{
|
|
7769
|
+
"id": "1004359",
|
|
7770
|
+
"text": "The Contact, Privacy and Terms pages had a scrap of behind-the-scenes note showing at the very top, above the menu. It came from a hidden note that accidentally closed itself too early. The note is reworded so it stays hidden,"
|
|
7771
|
+
},
|
|
7772
|
+
{
|
|
7773
|
+
"id": "1004311",
|
|
7774
|
+
"text": "The builders' hall no longer mentions dev boxes. Settings loses its Dev box section, the quick-jump menu loses its Dev box entry, and the architecture diagram now shows work running on your own machine. It also fixes a bug on"
|
|
7775
|
+
},
|
|
7776
|
+
{
|
|
7777
|
+
"id": "1004241",
|
|
7778
|
+
"text": "Area 5's task list is now honest: one stale task dropped, 14 rewritten to match the settled decisions, and the two waiting on the credit-economy area put back in backlog."
|
|
7779
|
+
},
|
|
7780
|
+
{
|
|
7781
|
+
"id": "1004354",
|
|
7782
|
+
"text": "A page you download as a Word file, edit in Google Docs and upload back now lands in your draft. Google Docs throws away the hidden details that said which page the file was, so the site used to refuse it as the wrong page. No"
|
|
7783
|
+
},
|
|
7784
|
+
{
|
|
7785
|
+
"id": "1004349",
|
|
7786
|
+
"text": "Decided: we host every project's Builders Hall, and owners choose where their app deploys, starting with Render. Also found and filed a sign-in cookie risk for halls on our addresses."
|
|
7787
|
+
},
|
|
7788
|
+
{
|
|
7789
|
+
"id": "1004356",
|
|
7790
|
+
"text": "The /feedback command works again: Claude Code can load your latest recorded walkthrough and its screenshots."
|
|
7791
|
+
},
|
|
7792
|
+
{
|
|
7793
|
+
"id": "1004142",
|
|
7794
|
+
"text": "A Bongos project now runs on Render, on its owner's own account: it starts, signs in, sets up its database and is backed up by Render, which clears the way to move projects off our server."
|
|
7795
|
+
},
|
|
7796
|
+
{
|
|
7797
|
+
"id": "1003459",
|
|
7798
|
+
"text": "You can now claim a task straight from its own page and from the \"Next up\" list on Home — both used to only tell you to claim it elsewhere. Every claim refusal (rank too low, someone else got there first, etc.) shows the same"
|
|
7799
|
+
},
|
|
7800
|
+
{
|
|
7801
|
+
"id": "1004310",
|
|
7802
|
+
"text": "New builders' setup checklist no longer asks them to connect a cloud dev box, and the sign-in path built for the retired dev box desktop app is gone. The builder guide now describes the one setup that exists: working from a co"
|
|
7803
|
+
},
|
|
7804
|
+
{
|
|
7805
|
+
"id": "1003892",
|
|
7806
|
+
"text": "Removed the dev box feature itself from the platform. Sites that still had it switched on in their settings keep starting normally — they now log a one-line note instead of failing to boot."
|
|
7807
|
+
},
|
|
7808
|
+
{
|
|
7809
|
+
"id": "1004271",
|
|
7810
|
+
"text": "Module authors can now publish a new version of their module to the Bongos module store with one command; the store checks it and keeps it ready for installs."
|
|
7811
|
+
},
|
|
7812
|
+
{
|
|
7813
|
+
"id": "1003893",
|
|
7814
|
+
"text": "Removed the machinery that created, parked and woke builders' cloud dev boxes, plus the scripts that ran on those boxes and the two background jobs that swept them. Nothing a builder uses today changes; the local preview and i"
|
|
7815
|
+
},
|
|
7816
|
+
{
|
|
7817
|
+
"id": "1003812",
|
|
7818
|
+
"text": "The module store now has somewhere to keep its list of modules, each published version, and what each one costs (free included)."
|
|
7819
|
+
},
|
|
7820
|
+
{
|
|
7821
|
+
"id": "1003781",
|
|
7822
|
+
"text": "Every module now has its own version number, shown in the module list and the hall's Modules tab — the first step toward publishing and updating modules through the store."
|
|
7823
|
+
}
|
|
7824
|
+
],
|
|
7825
|
+
"1.19.1075": [
|
|
7826
|
+
{
|
|
7827
|
+
"id": "1003897",
|
|
7828
|
+
"text": "Cleanup: the code, tests and settings no longer describe the dev box as if it still existed, and seven code-quality limits are tightened to today's better numbers. Nothing changes for builders."
|
|
7829
|
+
}
|
|
7746
7830
|
]
|
|
7747
7831
|
}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
// scripts/gds/artifact-format.js — the ONE packaging format Bongos ships code in:
|
|
2
|
+
// a deterministic ustar+gzip tarball plus a compression-independent tree pin
|
|
3
|
+
// (per-file sha256 + tree_sha256). Split out of package-core.js (task 1004271) so the
|
|
4
|
+
// module store (ADR 0338 D1: "no second packaging format") builds and VERIFIES module
|
|
5
|
+
// versions with the exact functions the core release uses — and so the always-on
|
|
6
|
+
// server can read a tarball without loading package-core.js's release machinery.
|
|
7
|
+
// Pure: no I/O beyond zlib/crypto, no git, no network.
|
|
8
|
+
|
|
9
|
+
const zlib = require('node:zlib');
|
|
10
|
+
const crypto = require('node:crypto');
|
|
11
|
+
|
|
12
|
+
function sha256hex(buf) {
|
|
13
|
+
return crypto.createHash('sha256').update(buf).digest('hex');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// The PIN. A canonical, compression-independent digest of a packaged tree: one
|
|
17
|
+
// "path\0mode\0filesha256\n" line per file, byte-sorted by path. A consumer
|
|
18
|
+
// recomputes this from the unpacked tree to prove an install matches the pin.
|
|
19
|
+
// `files` = [{ path, mode, sha256 }]. Modes are normalized so the pin is stable
|
|
20
|
+
// regardless of the checkout's umask.
|
|
21
|
+
function canonicalTreeHash(files) {
|
|
22
|
+
const lines = (files || [])
|
|
23
|
+
.map((f) => `${f.path}\u0000${normalizeMode(f.mode)}\u0000${f.sha256}`)
|
|
24
|
+
.sort();
|
|
25
|
+
return sha256hex(Buffer.from(lines.join('\n') + '\n', 'utf8'));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Collapse ANY mode form — git's 100644/100755, our canonical 0000644/0000755, or a
|
|
29
|
+
// raw filesystem octal string like "755" — to two canonical tar modes, keyed only on
|
|
30
|
+
// the executable bit. IDEMPOTENT (normalizeMode(normalizeMode(x)) === normalizeMode(x))
|
|
31
|
+
// AND exec-aware, so the tree pin reproduces byte-identically whether a consumer
|
|
32
|
+
// recomputes it from the manifest's files[] (already-canonical modes) or from the
|
|
33
|
+
// unpacked tree's stat() modes. Expects a STRING (git mode / canonical mode / octal).
|
|
34
|
+
function normalizeMode(mode) {
|
|
35
|
+
const s = String(mode);
|
|
36
|
+
if (s === '100755' || s === '0000755' || s === '755') return '0000755';
|
|
37
|
+
const n = parseInt(s, 8);
|
|
38
|
+
if (Number.isFinite(n) && (n & 0o111)) return '0000755';
|
|
39
|
+
return '0000644';
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ---- a minimal, correct, DETERMINISTIC ustar+gzip writer (node-only, #686) ----
|
|
43
|
+
// Deterministic (fixed mtime/uid/gid, normalized mode, sorted entries) so the same
|
|
44
|
+
// source yields byte-identical bytes — a bonus over the tree_sha256 pin. Long paths
|
|
45
|
+
// use the ustar name/prefix split, falling back to a GNU 'L' longname entry (read
|
|
46
|
+
// by GNU tar, bsdtar/macOS, and node-tar) for the rare path that won't split.
|
|
47
|
+
|
|
48
|
+
function octal(n, width) {
|
|
49
|
+
// width-1 octal digits, zero-padded, then a NUL — the classic numeric field.
|
|
50
|
+
return Buffer.from(n.toString(8).padStart(width - 1, '0').slice(-(width - 1)) + '\0', 'ascii');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function tarChecksum(block) {
|
|
54
|
+
let sum = 0;
|
|
55
|
+
for (let i = 0; i < 512; i++) sum += (i >= 148 && i < 156) ? 0x20 : block[i];
|
|
56
|
+
return sum;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Build one 512-byte ustar header. `name`/`prefix` must already fit (<=100 / <=155).
|
|
60
|
+
function ustarHeader({ name, prefix = '', mode, size, typeflag }) {
|
|
61
|
+
const h = Buffer.alloc(512, 0);
|
|
62
|
+
h.write(name, 0, 100, 'utf8');
|
|
63
|
+
octal(mode, 8).copy(h, 100);
|
|
64
|
+
octal(0, 8).copy(h, 108); // uid
|
|
65
|
+
octal(0, 8).copy(h, 116); // gid
|
|
66
|
+
octal(size, 12).copy(h, 124);
|
|
67
|
+
octal(0, 12).copy(h, 136); // mtime = 0 (determinism)
|
|
68
|
+
h.write(typeflag, 156, 1, 'ascii');
|
|
69
|
+
h.write('ustar\0', 257, 6, 'ascii');
|
|
70
|
+
h.write('00', 263, 2, 'ascii');
|
|
71
|
+
if (prefix) h.write(prefix, 345, 155, 'utf8');
|
|
72
|
+
// checksum field: 6 octal digits + NUL + space, computed with the field = spaces.
|
|
73
|
+
const cksum = tarChecksum(h);
|
|
74
|
+
h.write(cksum.toString(8).padStart(6, '0').slice(-6) + '\0 ', 148, 8, 'ascii');
|
|
75
|
+
return h;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Split a >100-byte path into { name<=100, prefix<=155 } at a '/' boundary, or
|
|
79
|
+
// return null if no split fits (→ caller uses the GNU longname fallback).
|
|
80
|
+
function splitUstarName(fullPath) {
|
|
81
|
+
const bytes = Buffer.byteLength(fullPath, 'utf8');
|
|
82
|
+
if (bytes <= 100) return { name: fullPath, prefix: '' };
|
|
83
|
+
// Find the LAST '/' such that the tail (after it) is <=100 and the head <=155.
|
|
84
|
+
for (let i = fullPath.length - 1; i > 0; i--) {
|
|
85
|
+
if (fullPath[i] !== '/') continue;
|
|
86
|
+
const prefix = fullPath.slice(0, i);
|
|
87
|
+
const name = fullPath.slice(i + 1);
|
|
88
|
+
if (Buffer.byteLength(name, 'utf8') <= 100 && Buffer.byteLength(prefix, 'utf8') <= 155) {
|
|
89
|
+
return { name, prefix };
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function padTo512(buf) {
|
|
96
|
+
const rem = buf.length % 512;
|
|
97
|
+
return rem === 0 ? buf : Buffer.concat([buf, Buffer.alloc(512 - rem, 0)]);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// GNU longname pseudo-entry: a header (typeflag 'L', name '././@LongLink') whose
|
|
101
|
+
// BODY is the full path (incl. trailing NUL), immediately followed by the real
|
|
102
|
+
// file entry. Read by GNU tar, bsdtar/macOS, and node-tar.
|
|
103
|
+
function gnuLongName(fullPath) {
|
|
104
|
+
const payload = Buffer.from(fullPath + '\0', 'utf8');
|
|
105
|
+
const hdr = ustarHeader({ name: '././@LongLink', mode: 0o644, size: payload.length, typeflag: 'L' });
|
|
106
|
+
return Buffer.concat([hdr, padTo512(payload)]);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// entries: [{ name, mode, buf }] — `name` includes the TAR_ROOT prefix. Returns a
|
|
110
|
+
// gzip'd tar Buffer. Pure + deterministic given sorted entries.
|
|
111
|
+
function buildTar(entries) {
|
|
112
|
+
const sorted = [...entries].sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
|
|
113
|
+
const chunks = [];
|
|
114
|
+
for (const e of sorted) {
|
|
115
|
+
const mode = e.mode & 0o7777;
|
|
116
|
+
const split = splitUstarName(e.name);
|
|
117
|
+
if (split) {
|
|
118
|
+
chunks.push(ustarHeader({ name: split.name, prefix: split.prefix, mode, size: e.buf.length, typeflag: '0' }));
|
|
119
|
+
} else {
|
|
120
|
+
chunks.push(gnuLongName(e.name));
|
|
121
|
+
chunks.push(ustarHeader({ name: e.name.slice(0, 100), mode, size: e.buf.length, typeflag: '0' }));
|
|
122
|
+
}
|
|
123
|
+
chunks.push(padTo512(e.buf));
|
|
124
|
+
}
|
|
125
|
+
// two zero blocks terminate the archive
|
|
126
|
+
chunks.push(Buffer.alloc(1024, 0));
|
|
127
|
+
const tar = Buffer.concat(chunks);
|
|
128
|
+
return zlib.gzipSync(tar, { level: 9 });
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
// ---- the matching READER (task 1004271) -------------------------------------
|
|
134
|
+
// Reads back exactly what buildTar writes — plain ustar file entries (name/prefix
|
|
135
|
+
// split) and GNU 'L' longname entries — into [{ name, mode, buf }]. It is the store's
|
|
136
|
+
// side of the format, so it is strict rather than permissive: any other entry type
|
|
137
|
+
// (a directory, a symlink, a pax header), a size or count over the caps, a truncated
|
|
138
|
+
// archive or a bad header checksum is a THROWN error, never a skipped entry. A server
|
|
139
|
+
// that verifies uploads must not quietly accept a shape it did not check.
|
|
140
|
+
//
|
|
141
|
+
// Two entry points over one parser: readTar (sync — the CLI and tests) and
|
|
142
|
+
// readTarAsync, which inflates on libuv's thread pool so a server verifying an upload
|
|
143
|
+
// does not hold the event loop for the decompression. The parse itself is a single
|
|
144
|
+
// linear pass over the inflated bytes.
|
|
145
|
+
const DEFAULT_READ_LIMITS = { maxUnpackedBytes: 64 * 1024 * 1024, maxFiles: 5000 };
|
|
146
|
+
const gunzipAsync = require('node:util').promisify(zlib.gunzip);
|
|
147
|
+
|
|
148
|
+
const unreadable = (maxUnpackedBytes, e) =>
|
|
149
|
+
new Error(`not a readable gzip tarball within ${maxUnpackedBytes} bytes (${e.code || e.message})`);
|
|
150
|
+
|
|
151
|
+
function readTar(tgz, { maxUnpackedBytes = DEFAULT_READ_LIMITS.maxUnpackedBytes, maxFiles = DEFAULT_READ_LIMITS.maxFiles } = {}) {
|
|
152
|
+
let tar;
|
|
153
|
+
try { tar = zlib.gunzipSync(tgz, { maxOutputLength: maxUnpackedBytes }); }
|
|
154
|
+
catch (e) { throw unreadable(maxUnpackedBytes, e); }
|
|
155
|
+
return parseTar(tar, { maxFiles });
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
async function readTarAsync(tgz, { maxUnpackedBytes = DEFAULT_READ_LIMITS.maxUnpackedBytes, maxFiles = DEFAULT_READ_LIMITS.maxFiles } = {}) {
|
|
159
|
+
let tar;
|
|
160
|
+
try { tar = await gunzipAsync(tgz, { maxOutputLength: maxUnpackedBytes }); }
|
|
161
|
+
catch (e) { throw unreadable(maxUnpackedBytes, e); }
|
|
162
|
+
return parseTar(tar, { maxFiles });
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function parseTar(tar, { maxFiles }) {
|
|
166
|
+
const cstr = (b, from, len) => {
|
|
167
|
+
const s = b.subarray(from, from + len);
|
|
168
|
+
const z = s.indexOf(0);
|
|
169
|
+
return (z < 0 ? s : s.subarray(0, z)).toString('utf8');
|
|
170
|
+
};
|
|
171
|
+
const out = [];
|
|
172
|
+
let off = 0;
|
|
173
|
+
let longName = null;
|
|
174
|
+
while (true) {
|
|
175
|
+
if (off + 512 > tar.length) throw new Error('tarball is truncated (no end-of-archive marker)');
|
|
176
|
+
const h = tar.subarray(off, off + 512);
|
|
177
|
+
if (h.every((x) => x === 0)) break;
|
|
178
|
+
const stored = parseInt(cstr(h, 148, 8).trim(), 8);
|
|
179
|
+
if (stored !== tarChecksum(h)) throw new Error(`tar header checksum mismatch at byte ${off}`);
|
|
180
|
+
const size = parseInt(cstr(h, 124, 12).trim() || '0', 8);
|
|
181
|
+
if (!Number.isFinite(size) || size < 0) throw new Error(`bad entry size at byte ${off}`);
|
|
182
|
+
const type = String.fromCharCode(h[156] || 48);
|
|
183
|
+
const bodyStart = off + 512;
|
|
184
|
+
const bodyEnd = bodyStart + size;
|
|
185
|
+
if (bodyEnd > tar.length) throw new Error('tarball is truncated mid-entry');
|
|
186
|
+
const body = tar.subarray(bodyStart, bodyEnd);
|
|
187
|
+
off = bodyStart + size + ((512 - (size % 512)) % 512);
|
|
188
|
+
if (type === 'L') { longName = cstr(body, 0, body.length); continue; }
|
|
189
|
+
if (type !== '0' && type !== '\u0000') throw new Error(`unsupported tar entry type "${type}" — only regular files are allowed`);
|
|
190
|
+
const prefix = cstr(h, 345, 155);
|
|
191
|
+
const name = longName || (prefix ? `${prefix}/${cstr(h, 0, 100)}` : cstr(h, 0, 100));
|
|
192
|
+
longName = null;
|
|
193
|
+
out.push({ name, mode: parseInt(cstr(h, 100, 8).trim() || '0', 8), buf: Buffer.from(body) });
|
|
194
|
+
if (out.length > maxFiles) throw new Error(`tarball has more than ${maxFiles} files`);
|
|
195
|
+
}
|
|
196
|
+
return out;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
module.exports = {
|
|
200
|
+
sha256hex, canonicalTreeHash, normalizeMode,
|
|
201
|
+
octal, tarChecksum, ustarHeader, splitUstarName, padTo512, gnuLongName, buildTar,
|
|
202
|
+
readTar, readTarAsync,
|
|
203
|
+
};
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
//
|
|
33
33
|
// ── WHERE THIS MAY RUN — read before scheduling it anywhere new ───────────────
|
|
34
34
|
//
|
|
35
|
-
// ONLY where the artifacts are SUPPOSED to already exist: a deployed instance
|
|
36
|
-
//
|
|
35
|
+
// ONLY where the artifacts are SUPPOSED to already exist: a deployed instance after its
|
|
36
|
+
// source-fetch regen. NEVER in CI. A fresh `git clone` legitimately
|
|
37
37
|
// has no `docs/repo-map.md` — it is gitignored, so it is not in the repository at all
|
|
38
38
|
// — and this check would report it absent on every single run. A monitor that is red
|
|
39
39
|
// every run teaches its reader to ignore it, which is the exact failure ADR 0110's
|
|
@@ -151,13 +151,6 @@ ALLOWLIST=(
|
|
|
151
151
|
# hardcoded in code.
|
|
152
152
|
'CODEOWNERS'
|
|
153
153
|
|
|
154
|
-
# Dev Box app distribution (#904, ADR 0044): the PUBLIC releases repo lives
|
|
155
|
-
# under the same GitHub account that owns the main repo — repo-hosting
|
|
156
|
-
# identity (same nature as provision-staging.sh above), not a builder
|
|
157
|
-
# identity. The test pins the committed config's repo string.
|
|
158
|
-
'config/devbox-app.json'
|
|
159
|
-
'tests/devbox_downloads.mjs'
|
|
160
|
-
|
|
161
154
|
# This audit script's own self-reference (it documents what it's looking for).
|
|
162
155
|
'scripts/gds/audit-authorship.sh'
|
|
163
156
|
|
|
@@ -173,21 +166,18 @@ ALLOWLIST=(
|
|
|
173
166
|
|
|
174
167
|
# Test DATA that pins a real contract (task 1002640) — identity in an
|
|
175
168
|
# assertion IS the contract, not a mis-attribution: owner approval RECORDS
|
|
176
|
-
# the Archon's login (gate_approvals),
|
|
177
|
-
# term-<login> hostnames (box_terminal_ssrf), packaging/provisioning tests
|
|
169
|
+
# the Archon's login (gate_approvals), packaging/provisioning tests
|
|
178
170
|
# exercise the real repo owner + the mirror-redaction floor. Listed per file
|
|
179
171
|
# (never a blanket tests/ exclusion) so a NEW test file is still scanned.
|
|
180
172
|
'tests/provision.mjs'
|
|
181
173
|
'tests/package_core.mjs'
|
|
182
174
|
'tests/init.mjs'
|
|
183
|
-
'tests/box_terminal_ssrf.mjs'
|
|
184
175
|
'tests/gate_approvals.mjs'
|
|
185
176
|
'tests/publish_reconciler.mjs'
|
|
186
177
|
'tests/dev_lib.mjs'
|
|
187
178
|
'tests/ship_card.mjs'
|
|
188
179
|
'tests/scrubber_corpus.mjs'
|
|
189
180
|
'tests/module_submissions.mjs'
|
|
190
|
-
'tests/boxes.mjs'
|
|
191
181
|
'tests/provisioning_onboard_mode.mjs'
|
|
192
182
|
'tests/instance_manifest.mjs'
|
|
193
183
|
'tests/bongos_downloads.mjs'
|
|
@@ -199,10 +189,8 @@ ALLOWLIST=(
|
|
|
199
189
|
'tests/currency_label.mjs'
|
|
200
190
|
'tests/cloud_bongos_pack.mjs'
|
|
201
191
|
'tests/bump_version.mjs'
|
|
202
|
-
'tests/box_scope_session.mjs'
|
|
203
192
|
'tests/auth_inactive_builder.mjs'
|
|
204
193
|
'tests/auth_anthropic_identity.mjs'
|
|
205
|
-
'modules/dev-box/app/test/unit.mjs'
|
|
206
194
|
|
|
207
195
|
# The mirror-redaction floor: PRIOR_INSTANCE_FLOOR carries the prior
|
|
208
196
|
# instance's owner literal precisely so packaging can SCRUB it from every
|
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
// scripts/gds/backfill-task-rewards.js — retroactive drachmae backfill for
|
|
5
5
|
// shipped tasks that paid 0 reward (task 1672, ADR 0097).
|
|
6
6
|
//
|
|
7
|
-
// THE GAP. A task's `credits_reward` defaults to 0; many early
|
|
7
|
+
// THE GAP. A task's `credits_reward` defaults to 0; many early and CI ships
|
|
8
8
|
// never had an author-estimated reward set, so the kind-multiplied task-confirm
|
|
9
9
|
// credit (modules/economy/credits.js insertMultipliedConfirmCredit) computed
|
|
10
10
|
// `0 × multiplier = 0` and minted nothing. The cost-plus *session* reward
|
|
11
11
|
// (reason='session.token_reward', ADR 0054) was supposed to backstop those, but
|
|
12
|
-
// it pays ~0 for
|
|
12
|
+
// it pays ~0 for CI agent ships (no priced model usage uploaded), so
|
|
13
13
|
// those builders earned nothing for real shipped work. This script lets an
|
|
14
14
|
// Archon retroactively pay a *fair, reviewed* per-task amount — once, safely.
|
|
15
15
|
//
|
|
@@ -133,7 +133,7 @@ function planForBuilder(builderId, taskRewards, costPlusAlreadyPaid, alreadyBack
|
|
|
133
133
|
// =========================================================================
|
|
134
134
|
|
|
135
135
|
function loadPool() {
|
|
136
|
-
// Lazy + guarded: a builder
|
|
136
|
+
// Lazy + guarded: a builder machine has no DATABASE_URL / no peer-auth Postgres,
|
|
137
137
|
// so --help and --dry-run must not crash here. We only reach for the pool when
|
|
138
138
|
// we actually need to read/write the DB, and we report a clean message if the
|
|
139
139
|
// connection is unavailable rather than throwing a raw stack.
|
|
@@ -230,7 +230,7 @@ async function buildPlan(pool, mapping, defaultRaw) {
|
|
|
230
230
|
// session-level (task_id NULL), so we net at the BUILDER level — the audit
|
|
231
231
|
// question is "did the cost-plus stream already compensate this builder for
|
|
232
232
|
// the work these tasks represent". The dry-run surfaces this number so the
|
|
233
|
-
// Archon can see whether it actually fired (it pays ~0 for
|
|
233
|
+
// Archon can see whether it actually fired (it pays ~0 for CI ships).
|
|
234
234
|
const { rows: costPlusRows } = await pool.query(
|
|
235
235
|
`SELECT builder_id, COALESCE(SUM(delta), 0)::int AS paid
|
|
236
236
|
FROM credit_log
|
|
@@ -334,7 +334,7 @@ async function main() {
|
|
|
334
334
|
try {
|
|
335
335
|
pool = loadPool();
|
|
336
336
|
} catch (err) {
|
|
337
|
-
console.error('No DB connection available (expected on a builder
|
|
337
|
+
console.error('No DB connection available (expected on a builder machine with no prod credentials).');
|
|
338
338
|
console.error('This script is inert here — run --help for usage. Detail:', err.message);
|
|
339
339
|
process.exit(2);
|
|
340
340
|
}
|
package/scripts/gds/claim.js
CHANGED
|
@@ -7,21 +7,6 @@
|
|
|
7
7
|
// On success: prints the claim id, the task title, and the touches[] so the
|
|
8
8
|
// builder knows the parallel-safety boundary they're working within.
|
|
9
9
|
|
|
10
|
-
// TREE PREFLIGHT (task 1003098). A task-scoped dev box carries scripts/ and
|
|
11
|
-
// src/bongos/ but not every modules/ directory, so the requires below can fail —
|
|
12
|
-
// and Node's loader names only the FIRST missing one, which turned recovery into
|
|
13
|
-
// guess-read-fix-repeat. This enumerates every missing requirement in one message
|
|
14
|
-
// and exits before the first such require runs. It must stay ABOVE them.
|
|
15
|
-
//
|
|
16
|
-
// A PRE-REQUEST hard exit, like the usage banner and worktree guard: nothing has
|
|
17
|
-
// been sent yet, so there is no in-flight request for cliExit to drain.
|
|
18
|
-
const { action: _surfaceAction } = require('./surface.js');
|
|
19
|
-
const { checkTree: _checkTree } = require('./tree-preflight.js');
|
|
20
|
-
{
|
|
21
|
-
const _fault = _checkTree(__filename, { command: _surfaceAction("claim") });
|
|
22
|
-
if (_fault) { console.error(_fault); process.exit(1); }
|
|
23
|
-
}
|
|
24
|
-
|
|
25
10
|
const { execSync } = require('node:child_process');
|
|
26
11
|
const fs = require('node:fs');
|
|
27
12
|
const path = require('node:path');
|
|
@@ -352,7 +352,7 @@ const STARTER_COMMANDS = [
|
|
|
352
352
|
// `git diff|log|show` rule, also on purpose: the harness already runs their
|
|
353
353
|
// read-only forms unprompted, and a prefix rule would switch off its flag check
|
|
354
354
|
// (`--output=<file>` writes anywhere, `diff --no-index` reads any file).
|
|
355
|
-
// tests/
|
|
355
|
+
// tests/cli_allowlist_permissions.mjs pins this list to the core's, rule for rule.
|
|
356
356
|
'bongos start:*',
|
|
357
357
|
'bongos status:*',
|
|
358
358
|
'bongos recall:*',
|
|
@@ -381,7 +381,7 @@ const STARTER_COMMANDS = [
|
|
|
381
381
|
];
|
|
382
382
|
// One rule per command PER SHELL TOOL (task 1004014): the shell tool is `PowerShell` on a Windows
|
|
383
383
|
// laptop, and a `Bash(...)` rule says nothing about its commands. The tools are the ones the guards
|
|
384
|
-
// see (`.claude/hooks/shell-tools.js`) — held equal by tests/
|
|
384
|
+
// see (`.claude/hooks/shell-tools.js`) — held equal by tests/cli_allowlist_permissions.mjs, not a require.
|
|
385
385
|
const STARTER_SHELL_TOOLS = ['Bash', 'PowerShell'];
|
|
386
386
|
const STARTER_ALLOW = STARTER_SHELL_TOOLS.flatMap((tool) => STARTER_COMMANDS.map((command) => `${tool}(${command})`));
|
|
387
387
|
|
package/scripts/gds/cli-lib.js
CHANGED
|
@@ -24,12 +24,12 @@ const ic = require('../../src/instance-config');
|
|
|
24
24
|
// namespaced instance, still resolves (R61 / task 1200). os.homedir() keeps it
|
|
25
25
|
// per-user on any machine.
|
|
26
26
|
//
|
|
27
|
-
// WHY THE OLD NAMES STAY READABLE. This file is on disk on every builder machine
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
27
|
+
// WHY THE OLD NAMES STAY READABLE. This file is on disk on every builder machine.
|
|
28
|
+
// Renaming it with no fallback signs all of them out at once and every /builder-*
|
|
29
|
+
// command dies with 'no Bongos session'. So a read that resolves through a
|
|
30
|
+
// superseded name MIGRATES forward (see loadSession), and the old file is
|
|
31
|
+
// deliberately LEFT IN PLACE — a builder may roll back to an older CLI, which
|
|
32
|
+
// can only see the old name. Part 4 (task 1003706) deletes it behind a
|
|
33
33
|
// test of its absence. (task 1003704)
|
|
34
34
|
//
|
|
35
35
|
// Order is FILENAME-major, not directory-major: the newest name found in ANY read
|
|
@@ -139,8 +139,8 @@ function hallBase(base = API_BASE) {
|
|
|
139
139
|
// still be mid-close when the caller's process.exit() runs, tripping a
|
|
140
140
|
// UV_HANDLE_CLOSING assertion that corrupts piped JSON stdout. Connection reuse
|
|
141
141
|
// buys these one-shot processes nothing, so route requests through a dispatcher
|
|
142
|
-
// with keep-alive effectively disabled
|
|
143
|
-
//
|
|
142
|
+
// with keep-alive effectively disabled. Degrades to the default dispatcher if
|
|
143
|
+
// undici can't be required.
|
|
144
144
|
//
|
|
145
145
|
// task 1002734 — THIS ALONE IS NOT ENOUGH, and the measurements say so: with the
|
|
146
146
|
// dispatcher wired in and undici resolving fine, `node scripts/gds/api.js GET
|
|
@@ -330,7 +330,7 @@ async function writeSessionToStore(session) {
|
|
|
330
330
|
// upgrading would still lose it.
|
|
331
331
|
// 2. store the incoming one under its own host.
|
|
332
332
|
// 3. write the ACTIVE pointer exactly where it has always gone, so every existing reader —
|
|
333
|
-
// in-repo skills
|
|
333
|
+
// in-repo skills and hooks — behaves identically.
|
|
334
334
|
async function saveSession(session) {
|
|
335
335
|
const dir = path.dirname(SESSION_PATH);
|
|
336
336
|
await fsp.mkdir(dir, { recursive: true });
|
|
@@ -1069,12 +1069,11 @@ function detectWorktreeName() {
|
|
|
1069
1069
|
// summary — that emitCard consumes directly.
|
|
1070
1070
|
//
|
|
1071
1071
|
// WHY THIS READS THE PAYLOAD AND NEVER require()s render-prefs.js. The ladder
|
|
1072
|
-
// lives in modules/builder-settings/render-prefs.js, and
|
|
1073
|
-
//
|
|
1074
|
-
//
|
|
1075
|
-
//
|
|
1076
|
-
//
|
|
1077
|
-
// ships the answers on `render.flags`; this function only picks them up.
|
|
1072
|
+
// lives in modules/builder-settings/render-prefs.js, and a CLI reaches a
|
|
1073
|
+
// module's logic through the server, never by require — the module may be
|
|
1074
|
+
// disabled on the instance, and a require would couple every CLI to one
|
|
1075
|
+
// module's internals. So the server resolves the rung and ships the answers on
|
|
1076
|
+
// `render.flags`; this function only picks them up.
|
|
1078
1077
|
//
|
|
1079
1078
|
// TWO SERVER SHAPES, deliberately. `render.flags` is the ladder (task 1002518);
|
|
1080
1079
|
// `render.widgets_enabled` is the boolean that predates it. A CLI newer than the
|
|
@@ -1174,6 +1173,7 @@ module.exports = {
|
|
|
1174
1173
|
repairMsysMangledPath,
|
|
1175
1174
|
resolveQuiet,
|
|
1176
1175
|
readSessionToken,
|
|
1176
|
+
CLI_USER_AGENT,
|
|
1177
1177
|
apiCall,
|
|
1178
1178
|
cliExit,
|
|
1179
1179
|
isDispatcherIncompatError,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
// never clobbered:
|
|
13
13
|
// src/gds/... -> src/bongos/... (directory refs)
|
|
14
14
|
// "src/gds" -> "src/bongos" (bare, at a boundary)
|
|
15
|
-
// src/gds-client -> src/gds-client (UNCHANGED:
|
|
15
|
+
// src/gds-client -> src/gds-client (UNCHANGED: a look-alike file name)
|
|
16
16
|
// src/gdsx -> src/gdsx (UNCHANGED here: prefix-edge fixture)
|
|
17
17
|
//
|
|
18
18
|
// Regex: /src\/gds(?![A-Za-z0-9_-])/g -- trailing guard only. No LEADING guard:
|
|
@@ -31,13 +31,11 @@ const path = require('node:path');
|
|
|
31
31
|
// so importing it from a CLI is safe — same precedent as next-number.js reading
|
|
32
32
|
// the repo tree directly. This is the "not hand-maintained" guarantee.
|
|
33
33
|
//
|
|
34
|
-
// OPTIONAL, because the file may not be ON DISK (task 1003085). A
|
|
35
|
-
//
|
|
36
|
-
//
|
|
37
|
-
//
|
|
38
|
-
//
|
|
39
|
-
// claim is what would fetch the module. A deadlock, escapable only by calling
|
|
40
|
-
// POST /claims with curl. The header's FAIL-OPEN promise ("must NEVER throw or
|
|
34
|
+
// OPTIONAL, because the file may not be ON DISK (task 1003085). A sparse checkout
|
|
35
|
+
// can lack modules/lifecycle, and when it did this require threw
|
|
36
|
+
// MODULE_NOT_FOUND at import time. That killed /builder-start AND /builder-claim
|
|
37
|
+
// — the two commands a builder needs to recover — leaving a deadlock escapable
|
|
38
|
+
// only by calling POST /claims with curl. The header's FAIL-OPEN promise ("must NEVER throw or
|
|
41
39
|
// block a claim") was already the right rule; this require was the line that did
|
|
42
40
|
// not keep it.
|
|
43
41
|
//
|
|
@@ -174,18 +174,12 @@ const CONCEPTUAL_TASK_IDS = {
|
|
|
174
174
|
246: 'R26 — karma surfaced on profile + sortable on leaderboard',
|
|
175
175
|
};
|
|
176
176
|
|
|
177
|
-
// 04-architecture (the
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
//
|
|
182
|
-
//
|
|
183
|
-
// 904 — the OTB Dev Box desktop app (menu-bar/tray on-off switch)
|
|
184
|
-
// 774 — the browser-only box terminal (ttyd over an outbound tunnel)
|
|
185
|
-
// 897 — the per-builder sandbox live game preview on the box
|
|
186
|
-
// 919 — the scoped dev-box session (box token deny-by-default)
|
|
187
|
-
// 1025 — server-mediated branch publish (box uploads bundle, server pushes)
|
|
188
|
-
// 1027 — hardware-verify of the box→prod flow end-to-end (now SHIPPED)
|
|
177
|
+
// 04-architecture (the ship flow) — how code on a builder's machine reaches
|
|
178
|
+
// prod. Same "LIVE iff its backing GDS task is 'shipped'" contract as the memory
|
|
179
|
+
// chain above. Each entry documents the piece it drives in
|
|
180
|
+
// scripts/gds/gen-diagrams.js `architectureMmd`:
|
|
181
|
+
// 1025 — server-mediated branch publish (a checkout with no GitHub push
|
|
182
|
+
// credential uploads a bundle, the server pushes it)
|
|
189
183
|
// 1028 — replaced the standing push PAT with a GitHub App (now SHIPPED)
|
|
190
184
|
//
|
|
191
185
|
// Every id here MUST drive a piece of the diagram. An id no consumer reads is
|
|
@@ -194,15 +188,10 @@ const CONCEPTUAL_TASK_IDS = {
|
|
|
194
188
|
// stop 03 + 04 from regenerating at all (the failure shape task 1002667 fixed
|
|
195
189
|
// for the offset case). Do NOT re-add 859 (CI self-deploy): the deploy leg is
|
|
196
190
|
// the standalone AUTO-PULL of ADR 0108/0129, not a task-gated Actions job, so
|
|
197
|
-
// gen-diagrams.js deliberately excludes it — see its comment at `
|
|
191
|
+
// gen-diagrams.js deliberately excludes it — see its comment at `ship flow`.
|
|
198
192
|
// Removed in task 1002674.
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
774: 'browser-only box terminal (ttyd over tunnel)',
|
|
202
|
-
897: 'per-builder sandbox live preview',
|
|
203
|
-
919: 'scoped dev-box session (box token deny-by-default)',
|
|
204
|
-
1025: 'server-mediated branch publish (box uploads bundle, server pushes)',
|
|
205
|
-
1027: 'hardware-verify the box-to-prod flow end-to-end',
|
|
193
|
+
const SHIP_FLOW_TASK_IDS = {
|
|
194
|
+
1025: 'server-mediated branch publish (a checkout with no push credential uploads a bundle, the server pushes)',
|
|
206
195
|
1028: 'GitHub App hardening (replace the standing push PAT)',
|
|
207
196
|
};
|
|
208
197
|
|
|
@@ -290,10 +279,10 @@ async function conceptualFacts({ repo, migs, api }) {
|
|
|
290
279
|
// process via cli-lib's guidance path (see the loop's degrade-to-null below).
|
|
291
280
|
api = await cliClient({ allowUnauthenticated: true });
|
|
292
281
|
}
|
|
293
|
-
// 03's pieces + 04-architecture's memory chain + its
|
|
282
|
+
// 03's pieces + 04-architecture's memory chain + its ship-flow pieces
|
|
294
283
|
// share one fetch + one taskStatus map; any unreachable id degrades the WHOLE
|
|
295
284
|
// conceptual bundle (so 03 + 04 skip together rather than emit partial data).
|
|
296
|
-
const ALL_TASK_IDS = { ...CONCEPTUAL_TASK_IDS, ...
|
|
285
|
+
const ALL_TASK_IDS = { ...CONCEPTUAL_TASK_IDS, ...SHIP_FLOW_TASK_IDS };
|
|
297
286
|
const ids = Object.keys(ALL_TASK_IDS).map(Number);
|
|
298
287
|
const status = {};
|
|
299
288
|
let lockedOffset = null;
|
|
@@ -360,7 +349,7 @@ module.exports = {
|
|
|
360
349
|
repoSlug,
|
|
361
350
|
conceptualFacts,
|
|
362
351
|
CONCEPTUAL_TASK_IDS,
|
|
363
|
-
|
|
352
|
+
SHIP_FLOW_TASK_IDS,
|
|
364
353
|
IMPORT_ID_OFFSETS,
|
|
365
354
|
gatherFacts,
|
|
366
355
|
};
|