@bongos/core 1.18.0 → 1.18.18
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 +1740 -640
- package/.claude/skills/builder-box/SKILL.md +6 -0
- package/.claude/skills/builder-sequence/SKILL.md +97 -0
- package/.claude/skills/builder-ship/SKILL.md +8 -2
- package/.claude/skills/builder-start/SKILL.md +11 -0
- package/.claude/skills/builder-sync/SKILL.md +41 -0
- package/.claude/skills/fix-task/SKILL.md +64 -0
- package/.claude/skills/goal-create/SKILL.md +158 -0
- package/.claude/skills/goal-review/SKILL.md +3 -1
- package/.claude/skills/idea-triage/SKILL.md +14 -8
- package/.claude/skills/merge-mode/SKILL.md +2 -2
- package/.claude/skills/new-project/SKILL.md +1 -0
- package/.claude/skills/planning-session/SKILL.md +45 -18
- package/.env.local.example +4 -3
- package/README.md +5 -3
- package/bin/bongos.js +1 -0
- package/clients/bongos-client/README.md +2 -2
- package/clients/bongos-client/bongos-client.global.js +82 -18
- package/clients/bongos-client/index.cjs +82 -18
- package/clients/bongos-client/index.d.ts +131 -29
- package/clients/bongos-client/index.mjs +82 -18
- package/config/branding.neutral.json +11 -2
- package/config/governance.neutral.json +21 -0
- package/docs/adr/0043-git-ssh-trust-boundary-and-rank-floor-on-permission-paths.md +24 -0
- package/docs/adr/0090-metic-task-authoring.md +1 -1
- package/docs/adr/0142-project-context-is-prose-only.md +41 -0
- package/docs/adr/0143-onboarding-repo-picker-oauth-scope.md +35 -0
- package/docs/adr/0144-devbox-rehome-onto-cloudbongos-plane.md +41 -0
- package/docs/adr/0144-federated-single-logout-backchannel.md +42 -0
- package/docs/adr/0145-devbox-app-branding-driven-module.md +44 -0
- package/docs/adr/0145-free-hosted-project-tier-isolation-and-domain-separation.md +62 -0
- package/docs/adr/0146-configurable-reward-mode-cost-plus-only.md +53 -0
- package/docs/adr/0147-standalone-live-docs-regen.md +39 -0
- package/docs/adr/0148-task-scoped-box-source-access.md +48 -0
- package/docs/adr/0149-bongos-dev-local-launcher.md +57 -0
- package/docs/adr/0150-box-first-boot-bringup-vendored-instances.md +68 -0
- package/docs/adr/0151-governance-permissions-as-atom-ranks-as-roles.md +229 -0
- package/docs/adr/0152-landing-gate-served-by-the-core-app.md +92 -0
- package/docs/adr/0152-metic-task-abandonment.md +67 -0
- package/docs/adr/0153-sequential-chain-runner.md +51 -0
- package/docs/adr/0154-goal-owner-criterion-authoring.md +86 -0
- package/docs/adr/README.md +15 -2
- package/docs/api/openapi.json +2648 -483
- package/docs/api-reference.md +73 -13
- package/docs/architecture.md +4 -2
- package/docs/branding-contract.md +3 -1
- package/docs/canonical-permissions.md +21 -8
- package/docs/file-map.md +15 -7
- package/docs/onboarding/diagrams/01-task-lifecycle.mmd +2 -2
- package/docs/onboarding/diagrams/02-rank-ladder.mmd +3 -1
- package/docs/onboarding/diagrams/05-versioning.mmd +1 -3
- package/docs/onboarding/diagrams/assertions.json +4 -7
- package/docs/onboarding/drachmae-and-karma.md +3 -3
- package/docs/onboarding/primer.md +17 -16
- package/docs/onboarding/slash-commands.md +124 -0
- package/docs/recipes/builder-box-lifecycle.md +23 -0
- package/docs/recipes/devbox-app-release.md +14 -4
- package/docs/recipes/instance-first-run.md +16 -0
- package/docs/recipes/local-dev.md +81 -0
- package/docs/recipes/ops-gotchas.md +19 -1
- package/docs/recipes/overnight-builder.md +1 -1
- package/docs/recipes/packaging-the-core.md +13 -0
- package/docs/recipes/parallel-goal-waves.md +174 -0
- package/docs/recipes/ship-and-regrade.md +2 -2
- package/docs/recipes/standalone-live-docs.md +48 -0
- package/docs/recipes/upgrading-the-core.md +5 -2
- package/docs/recipes/work-on-a-task-from-your-dev-box.md +108 -0
- package/migrations/003_pms.sql +6 -7
- package/migrations/006_pms_v2.sql +3 -31
- package/migrations/039_newcomer_friendly_column.sql +5 -0
- package/migrations/102_remove_box_first_provision_approval.sql +4 -0
- package/migrations/core_192_github_oauth_tokens.sql +33 -0
- package/migrations/core_193_task_needs_rebase.sql +28 -0
- package/migrations/core_194_confirmed_backlog_clawback.sql +63 -0
- package/migrations/core_195_idea_triage_provenance.sql +57 -0
- package/migrations/core_196_session_reward_topup.sql +69 -0
- package/modules/autonomy/pollers/routine-timers.js +9 -8
- package/modules/builder-settings/wandering-prefs.js +61 -18
- package/modules/dev-box/app/README.md +73 -0
- package/modules/dev-box/app/assets/tray/mac-alertTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-alertTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-busyTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-busyTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-offTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-offTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-onTemplate.png +0 -0
- package/modules/dev-box/app/assets/tray/mac-onTemplate@2x.png +0 -0
- package/modules/dev-box/app/assets/tray/win-alert.png +0 -0
- package/modules/dev-box/app/assets/tray/win-busy.png +0 -0
- package/modules/dev-box/app/assets/tray/win-off.png +0 -0
- package/modules/dev-box/app/assets/tray/win-on.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background.png +0 -0
- package/modules/dev-box/app/build-resources/dmg-background@2x.png +0 -0
- package/modules/dev-box/app/build-resources/icon.png +0 -0
- package/modules/dev-box/app/electron-builder.tmpl.yml +95 -0
- package/modules/dev-box/app/electron-builder.yml +95 -0
- package/modules/dev-box/app/package-lock.json +5291 -0
- package/modules/dev-box/app/package.json +30 -0
- package/modules/dev-box/app/renderer/app.js +319 -0
- package/modules/dev-box/app/renderer/index.html +45 -0
- package/modules/dev-box/app/renderer/styles.css +246 -0
- package/modules/dev-box/app/renderer/theme.generated.css +16 -0
- package/modules/dev-box/app/scripts/apply-dmg-backdrop.sh +82 -0
- package/modules/dev-box/app/scripts/dmgbuild-settings.py +39 -0
- package/modules/dev-box/app/scripts/gen-brand.js +138 -0
- package/modules/dev-box/app/scripts/gen-dmg-backdrop.py +323 -0
- package/modules/dev-box/app/scripts/gen-icons.js +286 -0
- package/modules/dev-box/app/scripts/vendor-client.js +23 -0
- package/modules/dev-box/app/src/box-controller.js +287 -0
- package/modules/dev-box/app/src/brand.generated.json +13 -0
- package/modules/dev-box/app/src/brand.js +16 -0
- package/modules/dev-box/app/src/config.js +19 -0
- package/modules/dev-box/app/src/gds-client.js +90 -0
- package/modules/dev-box/app/src/main.js +610 -0
- package/modules/dev-box/app/src/pairing.js +57 -0
- package/modules/dev-box/app/src/preload.js +29 -0
- package/modules/dev-box/app/src/session-store.js +58 -0
- package/modules/dev-box/app/src/ssh-setup.js +569 -0
- package/modules/dev-box/app/src/task-picker.js +70 -0
- package/modules/dev-box/app/src/tray.js +99 -0
- package/modules/dev-box/app/src/updater.js +55 -0
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +698 -0
- package/modules/dev-box/app/test/unit.mjs +526 -0
- package/modules/dev-box/box-access.js +121 -4
- package/modules/dev-box/boxes.js +20 -0
- package/modules/dev-box/module.json +1 -1
- package/modules/dev-box/routes/box.js +87 -3
- package/modules/economy/credits.js +116 -25
- package/modules/economy/reward.js +8 -0
- package/modules/economy/streak.js +2 -1
- package/modules/governance/CLAUDE.md +15 -0
- package/modules/governance/catalog.js +419 -0
- package/modules/governance/config.js +174 -0
- package/modules/governance/db.js +125 -0
- package/modules/governance/migrations/governance_001_tables.sql +81 -0
- package/modules/governance/migrations/governance_002_seed_and_backfill.sql +103 -0
- package/modules/governance/migrations/governance_003_task_abandon_metic.sql +28 -0
- package/modules/governance/migrations/governance_004_criterion_create.sql +39 -0
- package/modules/governance/migrations/governance_005_resync_builder_rank_roles.sql +56 -0
- package/modules/governance/module.json +10 -0
- package/modules/governance/protected-surfaces.js +88 -0
- package/modules/governance/protected-surfaces.json +80 -0
- package/modules/governance/rank-roles.js +83 -0
- package/modules/governance/resolver.js +221 -0
- package/modules/governance/routes/governance.js +89 -0
- package/modules/governance/routes/role-sync.js +49 -0
- package/modules/governance/session-scopes.js +127 -0
- package/modules/governance/session-scopes.json +38 -0
- package/modules/hall-ui/public/atlas.css +117 -0
- package/modules/hall-ui/public/atlas.html +3 -114
- package/modules/hall-ui/public/brand-apply.js +34 -6
- package/modules/hall-ui/public/builders.js +187 -219
- package/modules/hall-ui/public/diagrams.html +2 -0
- package/modules/hall-ui/public/dom-utils.js +27 -0
- package/modules/hall-ui/public/drachmae.html +2 -0
- package/modules/hall-ui/public/drachmae.js +54 -1
- package/modules/hall-ui/public/gate.css +98 -0
- package/modules/hall-ui/public/gate.html +3 -95
- package/modules/hall-ui/public/goal-inbox.js +4 -1
- package/modules/hall-ui/public/goals-page.js +626 -114
- package/modules/hall-ui/public/goals.css +79 -1
- package/modules/hall-ui/public/goals.html +38 -11
- package/modules/hall-ui/public/hall-widgets.js +62 -52
- package/modules/hall-ui/public/harbor.css +123 -0
- package/modules/hall-ui/public/harbor.html +3 -120
- package/modules/hall-ui/public/index.html +11 -4
- package/modules/hall-ui/public/instances-panel.js +4 -1
- package/modules/hall-ui/public/modules.css +63 -0
- package/modules/hall-ui/public/modules.html +3 -60
- package/modules/hall-ui/public/my-projects.html +78 -0
- package/modules/hall-ui/public/my-projects.js +142 -0
- package/modules/hall-ui/public/new-project-wizard.js +7 -3
- package/modules/hall-ui/public/not-ready.html +2 -0
- package/modules/hall-ui/public/pair.css +73 -0
- package/modules/hall-ui/public/pair.html +3 -70
- package/modules/hall-ui/public/palette.js +302 -0
- package/modules/hall-ui/public/primer.css +13 -0
- package/modules/hall-ui/public/primer.html +2 -0
- package/modules/hall-ui/public/profile.html +2 -0
- package/modules/hall-ui/public/ranks.html +2 -0
- package/modules/hall-ui/public/roadmap.css +179 -0
- package/modules/hall-ui/public/roadmap.html +9 -172
- package/modules/hall-ui/public/roadmap.js +329 -316
- package/modules/hall-ui/public/scouting.html +45 -0
- package/modules/hall-ui/public/scouting.js +73 -0
- package/modules/hall-ui/public/sessions.css +16 -0
- package/modules/hall-ui/public/sessions.html +3 -13
- package/modules/hall-ui/public/settings.html +2 -0
- package/modules/hall-ui/public/settings.js +4 -4
- package/modules/hall-ui/public/shell.js +143 -18
- package/modules/hall-ui/public/style.css +231 -39
- package/modules/hall-ui/public/task-detail.js +347 -26
- package/modules/hall-ui/public/task.html +6 -1
- package/modules/hall-ui/public/watch.html +2 -0
- package/modules/hall-ui/public/work.html +8 -6
- package/modules/hall-ui/public/work.js +1 -1
- package/modules/ideas/inbox.js +61 -11
- package/modules/ideas/routes/inbox.js +23 -0
- package/modules/lifecycle/claim-eligibility.js +72 -0
- package/modules/lifecycle/db.js +519 -139
- package/modules/lifecycle/done-when.js +18 -3
- package/modules/lifecycle/github-push.js +19 -2
- package/modules/lifecycle/goal-advisory.js +114 -0
- package/modules/lifecycle/goal-authz.js +62 -0
- package/modules/lifecycle/lifecycle.js +9 -0
- package/modules/lifecycle/publish-reconciler.js +109 -6
- package/modules/lifecycle/routes/claims.js +68 -23
- package/modules/lifecycle/routes/done-when.js +110 -15
- package/modules/lifecycle/routes/goals.js +8 -38
- package/modules/lifecycle/routes/tasks.js +38 -6
- package/modules/lifecycle/ship-card.js +6 -0
- package/modules/onboarding/onboarding-state.js +1 -1
- package/modules/platform-identity/CLAUDE.md +15 -0
- package/modules/platform-identity/hub-device.js +147 -0
- package/modules/platform-identity/hub-keys.js +151 -0
- package/modules/platform-identity/migrations/platform_identity_001_tables.sql +114 -0
- package/modules/platform-identity/migrations/platform_identity_002_client_origin_index.sql +18 -0
- package/modules/platform-identity/migrations/platform_identity_003_project_memberships.sql +42 -0
- package/modules/platform-identity/migrations/platform_identity_004_projects.sql +44 -0
- package/modules/platform-identity/migrations/platform_identity_005_builder_activity.sql +42 -0
- package/modules/platform-identity/module.json +18 -0
- package/modules/platform-identity/platform-identity.js +531 -0
- package/modules/platform-identity/pollers/code-sweep.js +43 -0
- package/modules/platform-identity/routes/my-projects.js +140 -0
- package/modules/platform-identity/routes/projects.js +107 -0
- package/modules/platform-identity/routes/scouting.js +35 -0
- package/modules/platform-identity/routes/sso.js +402 -0
- package/modules/platform-identity/tests/platform-identity.mjs +388 -0
- package/modules/platform-identity/ui/.gitkeep +0 -0
- package/modules/security/routes/reports.js +10 -0
- package/modules/sessions/db.js +166 -21
- package/modules/sessions/module.json +1 -1
- package/modules/sessions/pollers/session-reward-reconcile.js +78 -0
- package/modules/sessions/routes/sessions.js +33 -0
- package/modules/status-ui/public/explore.html +54 -0
- package/modules/status-ui/public/explore.js +67 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/public-landing/assets/anim/idle/frame_00.webp +0 -0
- package/public-landing/assets/anim/idle/frame_01.webp +0 -0
- package/public-landing/assets/anim/idle/frame_02.webp +0 -0
- package/public-landing/assets/anim/idle/frame_03.webp +0 -0
- package/public-landing/assets/anim/idle/frame_04.webp +0 -0
- package/public-landing/assets/anim/idle/frame_05.webp +0 -0
- package/public-landing/assets/anim/idle/frame_06.webp +0 -0
- package/public-landing/assets/anim/idle/frame_07.webp +0 -0
- package/public-landing/assets/anim/idle/frame_08.webp +0 -0
- package/public-landing/assets/anim/idle/frame_09.webp +0 -0
- package/public-landing/assets/anim/idle/frame_10.webp +0 -0
- package/public-landing/assets/anim/idle/frame_11.webp +0 -0
- package/public-landing/assets/anim/idle/frame_12.webp +0 -0
- package/public-landing/assets/anim/idle/frame_13.webp +0 -0
- package/public-landing/assets/anim/idle/frame_14.webp +0 -0
- package/public-landing/assets/anim/idle/frame_15.webp +0 -0
- package/public-landing/assets/anim/idle/frame_16.webp +0 -0
- package/public-landing/assets/anim/idle/frame_17.webp +0 -0
- package/public-landing/assets/anim/idle/frame_18.webp +0 -0
- package/public-landing/assets/anim/idle/frame_19.webp +0 -0
- package/public-landing/assets/anim/idle/frame_20.webp +0 -0
- package/public-landing/assets/anim/idle/frame_21.webp +0 -0
- package/public-landing/assets/anim/idle/frame_22.webp +0 -0
- package/public-landing/assets/anim/idle/frame_23.webp +0 -0
- package/public-landing/assets/anim/idle/frame_24.webp +0 -0
- package/public-landing/assets/anim/idle/frame_25.webp +0 -0
- package/public-landing/assets/anim/idle/frame_26.webp +0 -0
- package/public-landing/assets/anim/idle/frame_27.webp +0 -0
- package/public-landing/assets/anim/idle/frame_28.webp +0 -0
- package/public-landing/assets/anim/idle/frame_29.webp +0 -0
- package/public-landing/assets/anim/idle/frame_30.webp +0 -0
- package/public-landing/assets/anim/idle/frame_31.webp +0 -0
- package/public-landing/assets/anim/idle/frame_32.webp +0 -0
- package/public-landing/assets/anim/idle/frame_33.webp +0 -0
- package/public-landing/assets/anim/idle/frame_34.webp +0 -0
- package/public-landing/assets/anim/idle/frame_35.webp +0 -0
- package/public-landing/assets/anim/idle/frame_36.webp +0 -0
- package/public-landing/assets/anim/idle/frame_37.webp +0 -0
- package/public-landing/assets/anim/idle/frame_38.webp +0 -0
- package/public-landing/assets/anim/idle/frame_39.webp +0 -0
- package/public-landing/assets/anim/idle/frame_40.webp +0 -0
- package/public-landing/assets/anim/idle/frame_41.webp +0 -0
- package/public-landing/assets/anim/idle/frame_42.webp +0 -0
- package/public-landing/assets/anim/idle/frame_43.webp +0 -0
- package/public-landing/create.html +252 -62
- package/public-landing/gate/README.md +137 -0
- package/public-landing/gate/dispmaps/bar.png +0 -0
- package/public-landing/gate/dispmaps/flat.png +0 -0
- package/public-landing/gate/dispmaps/key.png +0 -0
- package/public-landing/gate/index.html +587 -0
- package/public-landing/gate/previews/cloud-bongos.jpg +0 -0
- package/public-landing/gate/previews/off-the-boats.jpg +0 -0
- package/public-landing/gate/space.css +799 -0
- package/public-landing/gate/space.js +1826 -0
- package/public-landing/gate/sprites/enter.png +0 -0
- package/public-landing/gate/sprites/search.png +0 -0
- package/public-landing/gate/sprites/terminal-blank.png +0 -0
- package/public-landing/gate/sprites/tile.png +0 -0
- package/public-landing/world/assets/clouds/cloud-island-large.png +0 -0
- package/public-landing/world/assets/clouds/cloud-puff.png +0 -0
- package/public-landing/world/assets/creatures/creature-whale-cargo.png +0 -0
- package/public-landing/world/assets/creatures/creature-whale-glide.png +0 -0
- package/public-landing/world/assets/plates/plate-clouds-near.png +0 -0
- package/public-landing/world/assets/plates/scene-establishing.png +0 -0
- package/scripts/gds/abandon.js +6 -4
- package/scripts/gds/api.js +10 -5
- package/scripts/gds/api.ps1 +26 -0
- package/scripts/gds/api.sh +6 -0
- package/scripts/gds/audit-ships.js +7 -1
- package/scripts/gds/backfill-sessions.js +78 -18
- package/scripts/gds/backup.js +23 -1
- package/scripts/gds/box-connect-lib.js +124 -31
- package/scripts/gds/box-sync.js +66 -0
- package/scripts/gds/box.js +225 -53
- package/scripts/gds/cf-tunnel.js +145 -6
- package/scripts/gds/claim.js +34 -3
- package/scripts/gds/cli-lib.js +161 -21
- package/scripts/gds/code.js +6 -2
- package/scripts/gds/deploy-divergence.js +209 -0
- package/scripts/gds/dev-lib.js +309 -0
- package/scripts/gds/dev.js +322 -0
- package/scripts/gds/doctor.js +90 -61
- package/scripts/gds/fetch-art-key.js +1 -1
- package/scripts/gds/fetch-sound-prefs.js +2 -2
- package/scripts/gds/fitness.js +228 -12
- package/scripts/gds/gds-db-backup.service +16 -1
- package/scripts/gds/gds-db-offsite.service +9 -1
- package/scripts/gds/gen-api-client.js +1 -1
- package/scripts/gds/gen-api-docs.js +36 -14
- package/scripts/gds/gen-diagrams.js +45 -28
- package/scripts/gds/gen-file-map.js +2 -1
- package/scripts/gds/gen-freshness.js +32 -0
- package/scripts/gds/gen-repo-map.js +3 -2
- package/scripts/gds/gen-session-index.js +14 -5
- package/scripts/gds/hooks/pre-push.js +2 -2
- package/scripts/gds/init.js +60 -3
- package/scripts/gds/install-git-hooks.js +1 -1
- package/scripts/gds/key-card.js +15 -6
- package/scripts/gds/key-status.js +1 -1
- package/scripts/gds/linkify-refs.js +35 -9
- package/scripts/gds/lint-migrations.js +102 -0
- package/scripts/gds/login.js +58 -11
- package/scripts/gds/mirror-redact.js +5 -0
- package/scripts/gds/package-core.js +263 -4
- package/scripts/gds/paste-token.js +7 -1
- package/scripts/gds/preflight.js +126 -0
- package/scripts/gds/provision.js +268 -19
- package/scripts/gds/publish-manifest.js +22 -1
- package/scripts/gds/reauth.js +7 -3
- package/scripts/gds/regen-instance-docs.js +47 -0
- package/scripts/gds/run-unit-tests.js +42 -16
- package/scripts/gds/seed-bongos-v1-seo-tasks.js +104 -0
- package/scripts/gds/seed-bv1-profiles-tasks.js +126 -0
- package/scripts/gds/sequence.js +425 -0
- package/scripts/gds/session-cost.js +10 -1
- package/scripts/gds/setup.js +72 -5
- package/scripts/gds/shell.js +5 -3
- package/scripts/gds/ship.js +433 -59
- package/scripts/gds/smoke-gds.js +139 -8
- package/scripts/gds/start.js +171 -22
- package/scripts/gds/status.js +1 -1
- package/scripts/gds/triage.js +10 -9
- package/scripts/gds/upgrade.js +271 -7
- package/scripts/migrate.sh +10 -0
- package/scripts/status-mirror-sync.js +114 -84
- package/src/bongos/api-errors.js +1 -0
- package/src/bongos/auth.js +809 -107
- package/src/bongos/db-kernel.js +27 -0
- package/src/bongos/db.js +105 -0
- package/src/bongos/github-repos.js +93 -0
- package/src/bongos/module-scope-map.js +27 -1
- package/src/bongos/permission-path-check.js +136 -102
- package/src/bongos/repo-info.js +47 -11
- package/src/bongos/route-rank-check.js +429 -46
- package/src/bongos/routes/_helpers.js +12 -1
- package/src/bongos/routes/auth.js +312 -13
- package/src/bongos/routes/backup.js +58 -2
- package/src/bongos/routes/github.js +90 -0
- package/src/bongos/routes/instance.js +15 -3
- package/src/bongos/routes/me.js +35 -1
- package/src/bongos/routes.js +2 -0
- package/src/bongos/serve-internal.js +84 -15
- package/src/branding.js +49 -2
- package/src/instance-config.js +46 -0
- package/src/module-api.js +140 -1
- package/src/platform-server.js +86 -9
- package/tests/abandon_task.mjs +59 -3
- package/tests/api_cli_flags.mjs +53 -0
- package/tests/auth_page_gate.mjs +13 -0
- package/tests/backfill_sessions.mjs +127 -1
- package/tests/backup_cli.mjs +54 -0
- package/tests/bongos_box_connect.mjs +77 -0
- package/tests/box_access.mjs +130 -1
- package/tests/box_credential.mjs +125 -0
- package/tests/box_host_keys.mjs +24 -0
- package/tests/box_infra_resolve.mjs +149 -0
- package/tests/box_scope_session.mjs +6 -2
- package/tests/box_sync.mjs +55 -0
- package/tests/box_task_scope.mjs +99 -0
- package/tests/branding.mjs +41 -23
- package/tests/cf_ruleset_preflight.mjs +142 -0
- package/tests/cf_tunnel.mjs +37 -0
- package/tests/claim_gate_rebase.mjs +98 -0
- package/tests/clawback_confirmed_backlog.mjs +103 -0
- package/tests/cli_lib_formatters.mjs +20 -0
- package/tests/confirm_attribution.mjs +30 -46
- package/tests/credit_grant.mjs +198 -10
- package/tests/criterion_authoring_gate.mjs +272 -0
- package/tests/criterion_progress.mjs +33 -1
- package/tests/dev_lib.mjs +253 -0
- package/tests/devbox_artifact_gate.mjs +75 -0
- package/tests/devbox_dmg_backdrop.mjs +137 -0
- package/tests/devbox_icons.mjs +304 -0
- package/tests/devbox_installer_brand.mjs +232 -0
- package/tests/devbox_key_register.mjs +234 -0
- package/tests/docs_openapi_route.mjs +110 -0
- package/tests/doctor_hooks.mjs +141 -0
- package/tests/extract_json.mjs +140 -0
- package/tests/fitness.mjs +89 -0
- package/tests/gen_freshness.mjs +96 -0
- package/tests/github_repos_helpers.mjs +91 -0
- package/tests/github_token_store.mjs +121 -0
- package/tests/goal_advisory.mjs +251 -0
- package/tests/goal_criterion_confirm_ui.mjs +269 -0
- package/tests/goal_routes.mjs +59 -4
- package/tests/goal_tier.mjs +12 -3
- package/tests/governance_catalog.mjs +129 -0
- package/tests/governance_claim_eligibility.mjs +262 -0
- package/tests/governance_config.mjs +187 -0
- package/tests/governance_ownership_scope.mjs +410 -0
- package/tests/governance_page_gates.mjs +324 -0
- package/tests/governance_parity.mjs +336 -0
- package/tests/governance_principals.mjs +232 -0
- package/tests/governance_protected_surfaces.mjs +208 -0
- package/tests/governance_require_permission.mjs +223 -0
- package/tests/governance_resolver.mjs +84 -0
- package/tests/governance_role_sync.mjs +231 -0
- package/tests/governance_seed.mjs +127 -0
- package/tests/governance_session_scope.mjs +434 -0
- package/tests/governance_vanilla_boot.mjs +203 -0
- package/tests/grade_attribution.mjs +7 -7
- package/tests/hall_audit.mjs +223 -0
- package/tests/hall_nav.mjs +191 -0
- package/tests/hall_palette.mjs +206 -0
- package/tests/hall_signout.mjs +124 -0
- package/tests/hook_user_agents.mjs +10 -0
- package/tests/idea_triage.mjs +162 -0
- package/tests/idp_device_exchange.mjs +198 -0
- package/tests/idp_federation.mjs +100 -0
- package/tests/init.mjs +51 -0
- package/tests/instance_config.mjs +65 -0
- package/tests/instance_mismatch_guard.mjs +23 -6
- package/tests/instance_release_config.mjs +104 -0
- package/tests/linkify_refs.mjs +15 -2
- package/tests/migrations_forward_safe.mjs +86 -0
- package/tests/module_api.mjs +1 -1
- package/tests/module_contributions.mjs +55 -0
- package/tests/module_loader.mjs +10 -5
- package/tests/module_scope_active_claims.mjs +94 -0
- package/tests/needs_rebase.mjs +92 -0
- package/tests/one_active_claim_per_session.mjs +76 -0
- package/tests/override_attribution.mjs +10 -8
- package/tests/override_request_ownership.mjs +8 -4
- package/tests/package_core.mjs +246 -1
- package/tests/parse_cookie_decode.mjs +42 -0
- package/tests/pay_on_land.mjs +129 -0
- package/tests/platform_boot.mjs +100 -1
- package/tests/post_login_landing.mjs +42 -0
- package/tests/preflight_checks.mjs +72 -0
- package/tests/provision.mjs +289 -7
- package/tests/pruned_lockfile_integrity.mjs +79 -0
- package/tests/publish_branch_route.mjs +53 -0
- package/tests/publish_reconciler.mjs +187 -2
- package/tests/repo_info_binding.mjs +248 -0
- package/tests/reward_gate.mjs +11 -2
- package/tests/reward_mode_cost_plus_only.mjs +116 -0
- package/tests/reward_mode_surfacing.mjs +168 -0
- package/tests/route_permission_check.mjs +301 -0
- package/tests/route_rank_check.mjs +254 -12
- package/tests/route_validation.mjs +30 -0
- package/tests/sequence.mjs +267 -0
- package/tests/session_digest.mjs +44 -0
- package/tests/session_index.mjs +18 -6
- package/tests/session_records.mjs +39 -1
- package/tests/session_reward_on_land.mjs +381 -0
- package/tests/session_reward_reconcile.mjs +229 -0
- package/tests/ship_api_client_pathspec.mjs +100 -0
- package/tests/ship_base_flag.mjs +93 -0
- package/tests/ship_ci_deploy.mjs +140 -3
- package/tests/ship_upstream_deletion.mjs +57 -0
- package/tests/smoke_target.mjs +233 -0
- package/tests/start_env_guard.mjs +87 -0
- package/tests/start_rebase_warning.mjs +103 -0
- package/tests/status_mirror_sync.mjs +122 -0
- package/tests/stop_refcheck.mjs +19 -1
- package/tests/task_goal_link.mjs +15 -6
- package/tests/upgrade.mjs +393 -5
- package/tests/web_admission_status.mjs +162 -0
- package/tests/write_validation_gaps.mjs +110 -0
- package/.gitignore +0 -91
- package/docs/adr/0139-platform-history-migration-to-cloudbongos.md +0 -94
- package/docs/adr/0140-cloudbongos-standalone-reprovision.md +0 -43
- package/scripts/hall-preview/fixtures/access-requests.json +0 -20
- package/scripts/hall-preview/fixtures/achievements.json +0 -76
- package/scripts/hall-preview/fixtures/analytics__builder.json +0 -251
- package/scripts/hall-preview/fixtures/audit-log.json +0 -68
- package/scripts/hall-preview/fixtures/blockers__detail.json +0 -12
- package/scripts/hall-preview/fixtures/box__me.json +0 -5
- package/scripts/hall-preview/fixtures/boxes__cost-ledger.json +0 -69
- package/scripts/hall-preview/fixtures/builders__active-claims.json +0 -1
- package/scripts/hall-preview/fixtures/builders__directory.json +0 -81
- package/scripts/hall-preview/fixtures/builders__roster.json +0 -48
- package/scripts/hall-preview/fixtures/goals.json +0 -502
- package/scripts/hall-preview/fixtures/goals__25.json +0 -96
- package/scripts/hall-preview/fixtures/goals__26.json +0 -67
- package/scripts/hall-preview/fixtures/goals__3.json +0 -103
- package/scripts/hall-preview/fixtures/goals__35.json +0 -49
- package/scripts/hall-preview/fixtures/goals__conflicts.json +0 -154
- package/scripts/hall-preview/fixtures/goals__detail.json +0 -96
- package/scripts/hall-preview/fixtures/goals__inbox.json +0 -5
- package/scripts/hall-preview/fixtures/goals__requests.json +0 -3
- package/scripts/hall-preview/fixtures/grades__by-builder.json +0 -32
- package/scripts/hall-preview/fixtures/inbox.json +0 -330
- package/scripts/hall-preview/fixtures/inbox__detail.json +0 -15
- package/scripts/hall-preview/fixtures/instance.json +0 -124
- package/scripts/hall-preview/fixtures/leaderboard.json +0 -184
- package/scripts/hall-preview/fixtures/me.json +0 -476
- package/scripts/hall-preview/fixtures/me__art-key__own.json +0 -6
- package/scripts/hall-preview/fixtures/me__event-sound-prefs.json +0 -209
- package/scripts/hall-preview/fixtures/me__recent-ships.json +0 -304
- package/scripts/hall-preview/fixtures/me__render.json +0 -5
- package/scripts/hall-preview/fixtures/me__skill-prefs.json +0 -143
- package/scripts/hall-preview/fixtures/me__sound-prefs.json +0 -67
- package/scripts/hall-preview/fixtures/me__wandering.json +0 -43
- package/scripts/hall-preview/fixtures/override-requests.json +0 -15
- package/scripts/hall-preview/fixtures/provisioning__fleet.json +0 -1
- package/scripts/hall-preview/fixtures/provisioning__fleet__cost-ledger.json +0 -1
- package/scripts/hall-preview/fixtures/provisioning__instances.json +0 -1
- package/scripts/hall-preview/fixtures/public__analytics__ecosystem.json +0 -516
- package/scripts/hall-preview/fixtures/public__bounty-table.json +0 -37
- package/scripts/hall-preview/fixtures/public__cost-summary.json +0 -742
- package/scripts/hall-preview/fixtures/public__estimation-drift.json +0 -41
- package/scripts/hall-preview/fixtures/public__grades.json +0 -50
- package/scripts/hall-preview/fixtures/public__progress.json +0 -124
- package/scripts/hall-preview/fixtures/public__recent-shipped.json +0 -426
- package/scripts/hall-preview/fixtures/public__repo-health.json +0 -160
- package/scripts/hall-preview/fixtures/public__repo-info.json +0 -5
- package/scripts/hall-preview/fixtures/security__docs.json +0 -10
- package/scripts/hall-preview/fixtures/security__reports.json +0 -31
- package/scripts/hall-preview/fixtures/sessions__search.json +0 -9
- package/scripts/hall-preview/fixtures/tasks.json +0 -2420
- package/scripts/hall-preview/fixtures/tasks__claimable.json +0 -2555
- package/scripts/hall-preview/fixtures/tasks__detail.json +0 -111
- package/scripts/hall-preview/fixtures/tasks__peer-votes__feed.json +0 -330
- package/scripts/hall-preview/fixtures/versions.json +0 -89
package/src/bongos/routes/me.js
CHANGED
|
@@ -83,7 +83,7 @@ module.exports = function buildMeRouter() {
|
|
|
83
83
|
const [
|
|
84
84
|
builder, activeClaims, estVsActual, unlocked, lockedWithProgress, streakInfo,
|
|
85
85
|
recentGrades, builderAvg, onboardingRow, shipCount, recentKarma, karma30d, discordLink, boxConnected, cliAuthed,
|
|
86
|
-
behaviorPrefs, geminiKeyRow,
|
|
86
|
+
behaviorPrefs, geminiKeyRow, needsRebaseTasks,
|
|
87
87
|
] = await Promise.all([
|
|
88
88
|
db.getBuilderById(req.builder.id),
|
|
89
89
|
lc().getActiveClaimsForBuilder(req.builder.id),
|
|
@@ -136,6 +136,14 @@ module.exports = function buildMeRouter() {
|
|
|
136
136
|
// Own Gemini-key status via the art-pipeline port (ADR 0102) — the storage
|
|
137
137
|
// is art-pipeline domain now; degrades to a no-key shape on a vanilla instance.
|
|
138
138
|
seams.resolveOptional('art.getBuilderGeminiKeyRow', async () => ({ enc: null, last4: null, set_at: null }))(req.builder.id),
|
|
139
|
+
// ADR 0120 part 5: the confirmed tasks this builder owes a rebase on —
|
|
140
|
+
// un-landed confirmed work the publish-reconciler flagged needs_rebase
|
|
141
|
+
// (part 2). It GATES new claims (part 3: claimTask refuses REBASE_REQUIRED)
|
|
142
|
+
// and its per-task reward now lands only on ship (part 1), so the CLI
|
|
143
|
+
// (/builder-start) + the hall surface an owed-rebase warning from this
|
|
144
|
+
// without a follow-up call. Through the `lifecycle` port; [] on a
|
|
145
|
+
// lifecycle-less instance (guarded — the port is resolveOptional).
|
|
146
|
+
lc() ? lc().needsRebaseTasksForBuilder(req.builder.id) : [],
|
|
139
147
|
]);
|
|
140
148
|
// V3.R84 (#302), criterion C3: the builder's month-to-date spend vs their
|
|
141
149
|
// monthly budget. Surfaced here so the CLI (session-start ping) and the hall
|
|
@@ -148,6 +156,18 @@ module.exports = function buildMeRouter() {
|
|
|
148
156
|
} catch (err) {
|
|
149
157
|
console.error('[gds] GET /me cost status', err);
|
|
150
158
|
}
|
|
159
|
+
// Best-effort read of the resolved reward policy (see the payload note).
|
|
160
|
+
// Never break the profile over a display concern — null degrades the CLI to
|
|
161
|
+
// its own paying default rather than a wrong "not paid" claim.
|
|
162
|
+
const rewardPolicySafe = () => {
|
|
163
|
+
try {
|
|
164
|
+
const p = typeof reward.rewardConfig === 'function' ? reward.rewardConfig() : null;
|
|
165
|
+
return p && typeof p.mode === 'string' ? { mode: p.mode, perTaskCredit: p.perTaskCredit !== false } : null;
|
|
166
|
+
} catch (err) {
|
|
167
|
+
console.error('[gds] GET /me reward policy', err);
|
|
168
|
+
return null;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
151
171
|
// For each active claim, compute the streak preview (cheap; pool query).
|
|
152
172
|
// Lets the CLI render "shipping this would extend streak to N days" hints.
|
|
153
173
|
const activeClaimsWithPreview = await Promise.all(
|
|
@@ -161,6 +181,20 @@ module.exports = function buildMeRouter() {
|
|
|
161
181
|
active_claims: activeClaimsWithPreview,
|
|
162
182
|
// Legacy field — first claim only. Prefer active_claims (plural).
|
|
163
183
|
active_claim: activeClaimsWithPreview[0] ?? null,
|
|
184
|
+
// ADR 0120 part 5: un-landed confirmed tasks this builder owes a rebase on.
|
|
185
|
+
// Each row: { id, title, needs_rebase_reason, needs_rebase_at }, oldest
|
|
186
|
+
// first. Empty when none owed (or on a lifecycle-less instance). These GATE
|
|
187
|
+
// new claims (part 3) and their reward is pending until they land on ship
|
|
188
|
+
// (part 1); the CLI + hall render a warning off this array.
|
|
189
|
+
needs_rebase_tasks: needsRebaseTasks,
|
|
190
|
+
// ADR 0146 / task 1002469: the instance's RESOLVED reward policy, so the
|
|
191
|
+
// CLI can label a task's advertised `credits_reward` honestly. On a
|
|
192
|
+
// `cost-plus-only` instance that estimate is never paid, and a builder who
|
|
193
|
+
// isn't told reads a correct `+0` at ship as a broken payout. It must come
|
|
194
|
+
// from the SERVER — the instance's branding.json is not in the builder's
|
|
195
|
+
// checkout, so a laptop reading local config always sees the default.
|
|
196
|
+
// Resolved by economy (never re-derived); null if economy is disabled.
|
|
197
|
+
reward: rewardPolicySafe(),
|
|
164
198
|
est_vs_actual: estVsActual,
|
|
165
199
|
unlocked,
|
|
166
200
|
locked_with_progress: lockedWithProgress,
|
package/src/bongos/routes.js
CHANGED
|
@@ -20,6 +20,7 @@ const express = require('express');
|
|
|
20
20
|
const buildHealthzRouter = require('./routes/healthz');
|
|
21
21
|
const buildInstanceRouter = require('./routes/instance');
|
|
22
22
|
const buildAuthRouter = require('./routes/auth');
|
|
23
|
+
const buildGithubRouter = require('./routes/github');
|
|
23
24
|
const buildMeRouter = require('./routes/me');
|
|
24
25
|
const buildBuildersRouter = require('./routes/builders');
|
|
25
26
|
// The LIFECYCLE routes (tasks · claims · versions · done-when · goals ·
|
|
@@ -116,6 +117,7 @@ function buildGdsRouter() {
|
|
|
116
117
|
router.use(buildHealthzRouter());
|
|
117
118
|
router.use(buildInstanceRouter());
|
|
118
119
|
router.use(buildAuthRouter());
|
|
120
|
+
router.use(buildGithubRouter());
|
|
119
121
|
router.use(buildMeRouter());
|
|
120
122
|
router.use(buildBuildersRouter());
|
|
121
123
|
// tasks · claims · versions · done-when · goals · dependencies · analytics now
|
|
@@ -47,7 +47,7 @@ const { buildBongosDownloads } = require('../bongos-downloads');
|
|
|
47
47
|
const { clientBranding, branding } = require('../branding');
|
|
48
48
|
const { clientModules, isModuleEnabled } = require('../modules');
|
|
49
49
|
const { hallWidgetScripts, moduleWebSurfaces } = require('../module-loader/loader');
|
|
50
|
-
const { resolveCoreRoot } = require('../instance-config');
|
|
50
|
+
const { resolveCoreRoot, resolveDocsRoot, resolveInstanceRoot } = require('../instance-config');
|
|
51
51
|
const { API_PREFIX, LEGACY_API_PREFIXES, API_VERSION, VERSIONED_API_PREFIX, ALL_API_PREFIXES } = require('./api-prefix');
|
|
52
52
|
|
|
53
53
|
// ADR 0108 §1: every use of ROOT below (infra/ installers, modules/, docs/) is
|
|
@@ -56,15 +56,28 @@ const { API_PREFIX, LEGACY_API_PREFIXES, API_VERSION, VERSIONED_API_PREFIX, ALL_
|
|
|
56
56
|
const ROOT = resolveCoreRoot();
|
|
57
57
|
|
|
58
58
|
// Instance-only RELEASE config (config/devbox-app.json, config/bongos-cli.json) is
|
|
59
|
-
// boundary-excluded from the portable core (publish-manifest INSTANCE_EXCLUDE), so
|
|
60
|
-
//
|
|
61
|
-
//
|
|
62
|
-
//
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
59
|
+
// boundary-excluded from the portable core (publish-manifest INSTANCE_EXCLUDE), so it is
|
|
60
|
+
// HOST content: it lives at the INSTANCE root, which on a vendored instance is NOT the
|
|
61
|
+
// package dir this file sits under. A core-relative require therefore looked in
|
|
62
|
+
// node_modules/@bongos/core/config/ and never found it, so /downloads/* silently failed
|
|
63
|
+
// to mount (task 1002371 — same class as ADR 0144's vendored infra/ path bug; ADR 0145's
|
|
64
|
+
// copy-the-config-into-node_modules workaround is lost on the next `npm ci`). So resolve
|
|
65
|
+
// the instance root FIRST — the branding/modules resolution (src/branding.js INSTANCE_PATH)
|
|
66
|
+
// — then the core package dir, which keeps a single checkout (and that copied-in
|
|
67
|
+
// workaround) byte-identical.
|
|
68
|
+
//
|
|
69
|
+
// Fail-soft is preserved verbatim: an ABSENT config makes its download surface simply not
|
|
70
|
+
// mount (fail-to-vanilla, like branding/modules) rather than crash the boot as the original
|
|
71
|
+
// hard require did (task 1824); a MALFORMED config still throws — only a MISSING file is
|
|
72
|
+
// tolerated. `roots` is injected so the ladder is unit-testable with zero ambient state.
|
|
73
|
+
function tryLoadInstanceConfig(name, roots = [resolveInstanceRoot(), ROOT]) {
|
|
74
|
+
for (const root of new Set(roots)) {
|
|
75
|
+
let raw;
|
|
76
|
+
try { raw = fs.readFileSync(path.join(root, 'config', name), 'utf8'); }
|
|
77
|
+
catch (e) { if (e.code === 'ENOENT') continue; throw e; }
|
|
78
|
+
return JSON.parse(raw);
|
|
79
|
+
}
|
|
80
|
+
return null;
|
|
68
81
|
}
|
|
69
82
|
|
|
70
83
|
// Map the pack's camelCase theme color keys → the kebab-case CSS custom
|
|
@@ -193,6 +206,60 @@ function docsIndexHtml() {
|
|
|
193
206
|
return _docsHtml;
|
|
194
207
|
}
|
|
195
208
|
|
|
209
|
+
// The OpenAPI 3.1 spec served at /docs/openapi.json — SELF-HEALING (task 1002200).
|
|
210
|
+
// The Redoc page (public-docs/) ships as static assets, but the SPEC is a generated
|
|
211
|
+
// artifact whose on-disk copy is NOT guaranteed at every deploy topology, so a bare
|
|
212
|
+
// res.sendFile(one fixed path) 404s exactly when the file is missing:
|
|
213
|
+
// • Standalone instance (ADR 0108/0140): the route resolves from the CORE package
|
|
214
|
+
// (resolveCoreRoot → node_modules/@bongos/core) while the generator writes the
|
|
215
|
+
// INSTANCE's own spec to resolveDocsRoot (the instance repo) — a path mismatch.
|
|
216
|
+
// • A pinned @bongos/core that predates the spec's packaging ships NO copy at all
|
|
217
|
+
// (the observed cloudbongos.com 404: public-docs/ shipped, docs/api/ didn't).
|
|
218
|
+
// • A fresh instance, before its first generate, has neither.
|
|
219
|
+
// So resolve the spec in tiers: (1) the committed spec at resolveDocsRoot() (the
|
|
220
|
+
// instance's own — carries its module routes), then (2) at resolveCoreRoot() (the
|
|
221
|
+
// core-package copy), then (3) GENERATE it in-process from the live route source.
|
|
222
|
+
// gen-api-docs.build() reads routes from resolveCoreRoot() (always present — it IS
|
|
223
|
+
// the running code), is DB-free + express-free (a pure line+regex extractor that
|
|
224
|
+
// never executes a route or opens a connection), and yields the identical spec.
|
|
225
|
+
// resolveOpenapiJson is the pure, injectable core so the fallback ladder is unit-
|
|
226
|
+
// testable (tests/docs_openapi_route.mjs).
|
|
227
|
+
function resolveOpenapiJson({ candidates = [], generate } = {}) {
|
|
228
|
+
for (const p of candidates) {
|
|
229
|
+
let raw;
|
|
230
|
+
try { raw = fs.readFileSync(p, 'utf8'); } catch { continue; } // absent → next tier
|
|
231
|
+
try { JSON.parse(raw); } catch { continue; } // corrupt → next tier
|
|
232
|
+
return raw;
|
|
233
|
+
}
|
|
234
|
+
if (typeof generate === 'function') {
|
|
235
|
+
try {
|
|
236
|
+
const out = generate();
|
|
237
|
+
if (out) return out;
|
|
238
|
+
} catch (e) {
|
|
239
|
+
console.error('[docs] in-process OpenAPI generation failed:', e && e.message);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return '';
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// Memoized like docsIndexHtml: one resolve per process; a redeploy restarts and
|
|
246
|
+
// re-resolves. '' (→ the route falls through to 404) only if every tier fails.
|
|
247
|
+
let _openapiJson;
|
|
248
|
+
function openapiJson() {
|
|
249
|
+
if (_openapiJson !== undefined) return _openapiJson;
|
|
250
|
+
const roots = [...new Set([resolveDocsRoot(), ROOT])]; // instance repo first, then core pkg
|
|
251
|
+
_openapiJson = resolveOpenapiJson({
|
|
252
|
+
candidates: roots.map((r) => path.join(r, 'docs/api/openapi.json')),
|
|
253
|
+
generate() {
|
|
254
|
+
// Lazy require: boot never pays for it, and a generator hiccup is contained
|
|
255
|
+
// to this one endpoint rather than taking down server start.
|
|
256
|
+
const gen = require('../../scripts/gds/gen-api-docs.js');
|
|
257
|
+
return JSON.stringify(gen.build().spec, null, 2) + '\n';
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
return _openapiJson;
|
|
261
|
+
}
|
|
262
|
+
|
|
196
263
|
// The browser-global build of the generated typed client (task 1996 / R09),
|
|
197
264
|
// served at /lib/bongos-client.js so classic <script> web pages can consume the
|
|
198
265
|
// same generated client the CLI uses (window.BongosClient). Read once at boot
|
|
@@ -408,7 +475,7 @@ function mountInternalSurfaces(app) {
|
|
|
408
475
|
// builders.<apex> (the builders rewrite shim below only prefixes non-/api
|
|
409
476
|
// paths, so without this placement /downloads/* would be rewritten to
|
|
410
477
|
// /builders/downloads/* and 404).
|
|
411
|
-
const devboxCfg =
|
|
478
|
+
const devboxCfg = tryLoadInstanceConfig('devbox-app.json');
|
|
412
479
|
if (devboxCfg) {
|
|
413
480
|
const devboxDownloads = buildDevboxDownloads(devboxCfg);
|
|
414
481
|
app.get('/downloads/devbox/latest.json', (_req, res) => {
|
|
@@ -439,7 +506,7 @@ function mountInternalSurfaces(app) {
|
|
|
439
506
|
// every user-facing URL on the apex. The installer scripts are served with the
|
|
440
507
|
// server's PINNED origin substituted for __GDS_API_BASE__ — never a request
|
|
441
508
|
// header, so a spoofed Host can't redirect a `curl | sh` (the box-connect.sh rule).
|
|
442
|
-
const bongosCfg =
|
|
509
|
+
const bongosCfg = tryLoadInstanceConfig('bongos-cli.json');
|
|
443
510
|
if (bongosCfg) {
|
|
444
511
|
const bongosDownloads = buildBongosDownloads(bongosCfg);
|
|
445
512
|
// Pinned public origin for the served installer scripts (never a request header —
|
|
@@ -847,7 +914,7 @@ function mountInternalSurfaces(app) {
|
|
|
847
914
|
// external fetch (matches the /vendor/* self-hosting convention; CSP-safe).
|
|
848
915
|
// GET /docs → the Redoc host page (branding-injected)
|
|
849
916
|
// GET /docs/redoc.standalone.js → the vendored renderer (long-cached)
|
|
850
|
-
// GET /docs/openapi.json → the
|
|
917
|
+
// GET /docs/openapi.json → the spec, SELF-HEALING (committed → generated), CORS-open so Postman/Swagger/AI can fetch it; see openapiJson()
|
|
851
918
|
app.get('/docs', (req, res, next) => {
|
|
852
919
|
if (isModuleSurfaceHost(req)) return next();
|
|
853
920
|
const html = docsIndexHtml();
|
|
@@ -864,10 +931,12 @@ function mountInternalSurfaces(app) {
|
|
|
864
931
|
});
|
|
865
932
|
app.get('/docs/openapi.json', (req, res, next) => {
|
|
866
933
|
if (isModuleSurfaceHost(req)) return next();
|
|
934
|
+
const json = openapiJson();
|
|
935
|
+
if (!json) return next(); // no committed spec + generation failed → fall through to 404
|
|
867
936
|
res.set('Access-Control-Allow-Origin', '*'); // read-only spec — tools fetch it cross-origin
|
|
868
937
|
res.set('Cache-Control', 'public, max-age=60');
|
|
869
938
|
res.type('application/json');
|
|
870
|
-
res.
|
|
939
|
+
res.send(json);
|
|
871
940
|
});
|
|
872
941
|
|
|
873
942
|
app.use((req, res, next) => {
|
|
@@ -895,4 +964,4 @@ function mountInternalSurfaces(app) {
|
|
|
895
964
|
return app;
|
|
896
965
|
}
|
|
897
966
|
|
|
898
|
-
module.exports = { mountInternalSurfaces, isStatusHost, isBuildersHost, injectBrandingGlobal, injectBrandingInto, injectModuleHallWidgets, themeMarkup, applyBrandTokens };
|
|
967
|
+
module.exports = { mountInternalSurfaces, isStatusHost, isBuildersHost, injectBrandingGlobal, injectBrandingInto, injectModuleHallWidgets, themeMarkup, applyBrandTokens, resolveOpenapiJson, openapiJson, tryLoadInstanceConfig };
|
package/src/branding.js
CHANGED
|
@@ -44,6 +44,16 @@ const ENV_OVERRIDES = [
|
|
|
44
44
|
['OAUTH_ORIGIN', ['domains', 'oauthOrigin']],
|
|
45
45
|
['PROVISIONING_ORIGIN', ['domains', 'provisioningOrigin']],
|
|
46
46
|
['COOKIE_DOMAIN', ['domains', 'cookieDomain']],
|
|
47
|
+
// Cross-site identity federation flip (ADR 0141 §4). Provisioning sets
|
|
48
|
+
// <PREFIX>_AUTH_IDP=true per hosted instance (config/branding.neutral.json ships
|
|
49
|
+
// idp:false), so a co-tenant instance sharing the neutral pack still federates
|
|
50
|
+
// individually. 'bool'-coerced below — auth.js idpEnabled() reads it as strict === true.
|
|
51
|
+
['AUTH_IDP', ['auth', 'idp'], 'bool'],
|
|
52
|
+
// Post-sign-in landing when no ?return=/Referer was carried (auth.js
|
|
53
|
+
// postLoginLanding). Env-overridable so a platform-home instance can flip its
|
|
54
|
+
// front door with one env var and no instance branding.json — cloudbongos.com
|
|
55
|
+
// sets <PREFIX>_POST_LOGIN_LANDING=/gate/ (the orbs). Task 1002240.
|
|
56
|
+
['POST_LOGIN_LANDING', ['landing', 'postLogin']],
|
|
47
57
|
];
|
|
48
58
|
|
|
49
59
|
const isObj = (v) => v && typeof v === 'object' && !Array.isArray(v);
|
|
@@ -69,6 +79,12 @@ function deepFreeze(o) {
|
|
|
69
79
|
return o;
|
|
70
80
|
}
|
|
71
81
|
|
|
82
|
+
// This is the ONE structured host-identity contract. Project context (vision/world/visual-style
|
|
83
|
+
// prose in docs/project-context.md) is deliberately PROSE-ONLY — there is no parallel resolver for
|
|
84
|
+
// it, because nothing in the platform reads project context as data; it is written for agents to
|
|
85
|
+
// read. If a host value must be CODE-READ, add it HERE (branding), not a new project-context
|
|
86
|
+
// resolver. Decided in ADR 0142 (audit H11 / task 1002224).
|
|
87
|
+
//
|
|
72
88
|
// Pure resolver — all inputs injected, so tests drive it with zero I/O.
|
|
73
89
|
function resolveBranding({ neutral = {}, instance = {}, env = {} } = {}) {
|
|
74
90
|
// structuredClone so the merged result shares no nested references with the
|
|
@@ -76,9 +92,13 @@ function resolveBranding({ neutral = {}, instance = {}, env = {} } = {}) {
|
|
|
76
92
|
// the caller's input objects (deepMerge shallow-copies only the top level).
|
|
77
93
|
const resolved = structuredClone(deepMerge(neutral, instance));
|
|
78
94
|
const prefix = resolved.envPrefix || 'CLOUDBONGOS';
|
|
79
|
-
for (const [suffix, p] of ENV_OVERRIDES) {
|
|
95
|
+
for (const [suffix, p, coerce] of ENV_OVERRIDES) {
|
|
80
96
|
const v = env[`${prefix}_${suffix}`];
|
|
81
|
-
if (v
|
|
97
|
+
if (v === undefined || v === '') continue;
|
|
98
|
+
// Most overrides are string-valued (origins, cookie domain) and set verbatim. A
|
|
99
|
+
// 'bool'-tagged override (auth.idp) coerces the env string to a real boolean —
|
|
100
|
+
// idpEnabled() checks `=== true`, so an uncoerced "true" would never federate.
|
|
101
|
+
setPath(resolved, p, coerce === 'bool' ? /^(1|true|yes|on)$/i.test(String(v)) : v);
|
|
82
102
|
}
|
|
83
103
|
const missing = REQUIRED.filter((p) => {
|
|
84
104
|
const v = getPath(resolved, p);
|
|
@@ -177,7 +197,34 @@ function clientBranding(b = branding()) {
|
|
|
177
197
|
notFound: b.copy?.notFound || 'Page not found.',
|
|
178
198
|
},
|
|
179
199
|
rankLabels: b.rankLabels || {},
|
|
200
|
+
reward: clientReward(),
|
|
180
201
|
};
|
|
181
202
|
}
|
|
182
203
|
|
|
204
|
+
// The RESOLVED reward policy, projected client-safe (ADR 0146 follow-up, task
|
|
205
|
+
// 1002469). Display surfaces need to know which streams this instance actually
|
|
206
|
+
// pays — on a `cost-plus-only` instance the per-task "Est." is a guide, never a
|
|
207
|
+
// payout, and a builder who is not told that reads a correct `+0` as a bug.
|
|
208
|
+
//
|
|
209
|
+
// Resolved through the economy module's `reward` port, NOT re-derived here: the
|
|
210
|
+
// mode→perTaskCredit mapping is economy's to own (ADR 0146 put the knob inside
|
|
211
|
+
// the module deliberately). `module-seams` is a dependency-free leaf, so this
|
|
212
|
+
// adds no boot-order coupling to the config layer.
|
|
213
|
+
//
|
|
214
|
+
// Fail-safe: an instance with economy disabled, or a resolve that throws, falls
|
|
215
|
+
// back to the ADR 0146 DEFAULT (pay both streams) — the same direction the pure
|
|
216
|
+
// resolver takes an unknown mode, so a hiccup can never silently tell builders
|
|
217
|
+
// their per-task reward is withheld.
|
|
218
|
+
function clientReward() {
|
|
219
|
+
const fallback = { mode: 'cost-plus-and-estimate', perTaskCredit: true };
|
|
220
|
+
try {
|
|
221
|
+
const reward = require('./module-seams').resolveOptional('reward');
|
|
222
|
+
const p = reward && typeof reward.rewardConfig === 'function' ? reward.rewardConfig() : null;
|
|
223
|
+
if (!p || typeof p.mode !== 'string') return fallback;
|
|
224
|
+
return { mode: p.mode, perTaskCredit: p.perTaskCredit !== false };
|
|
225
|
+
} catch (_) {
|
|
226
|
+
return fallback;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
183
230
|
module.exports = { resolveBranding, loadBranding, deepMerge, branding, clientBranding, userAgent, NEUTRAL_PATH, INSTANCE_PATH };
|
package/src/instance-config.js
CHANGED
|
@@ -50,6 +50,50 @@ function envPrefix(b = safeBrand()) {
|
|
|
50
50
|
return b.envPrefix || FALLBACK_ENV_PREFIX;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
// The default API base the CLI targets when there is no <PREFIX>_API_BASE env
|
|
54
|
+
// override AND no logged-in session api_base — i.e. the last-resort fallback.
|
|
55
|
+
// Resolves to THIS instance's own publicOrigin from the branding pack (OTB →
|
|
56
|
+
// https://amazonprimea.com, vanilla → http://localhost:3000), so the portable
|
|
57
|
+
// core never hard-codes another instance's URL (task 1002201 — pre-ADR-0139 the
|
|
58
|
+
// literal 'https://amazonprimea.com' was baked into cli-lib, sending every
|
|
59
|
+
// unconfigured consumer at the founder's game box). Single source of truth: every
|
|
60
|
+
// CLI base resolution routes through here. Last-resort http://localhost:3000 when
|
|
61
|
+
// branding can't be read at all — a local dev origin, never a foreign prod, so an
|
|
62
|
+
// unconfigured raw CLI fails safe rather than acting against someone else's DB.
|
|
63
|
+
function defaultApiBase(b = safeBrand()) {
|
|
64
|
+
const origin = b && b.domains && b.domains.publicOrigin;
|
|
65
|
+
return (typeof origin === 'string' && origin.trim()) || 'http://localhost:3000';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// The API base a CLI command should actually talk to:
|
|
69
|
+
// <PREFIX>_API_BASE (env) → the PERSISTED session's api_base → defaultApiBase()
|
|
70
|
+
// The session beats the branding default because a builder authenticated against
|
|
71
|
+
// instance A must keep hitting A even when this checkout's own branding names B —
|
|
72
|
+
// which is exactly what broke re-auth (task 1002427). cliClient() had this order
|
|
73
|
+
// right; paste-token.js hardcoded the founder host and reauth.js used the bare
|
|
74
|
+
// branding default, so a token minted by one instance was verified against
|
|
75
|
+
// another and rejected 401. Every base resolution routes through here so the
|
|
76
|
+
// three cannot drift again.
|
|
77
|
+
//
|
|
78
|
+
// `session` is injected by callers that already loaded it (cliClient) and read
|
|
79
|
+
// from the session file otherwise; pass null to mean "no session" without a disk
|
|
80
|
+
// read. Never returns empty — an unusable api_base falls back to the default.
|
|
81
|
+
function resolveApiBase({ session, env = process.env, b = safeBrand() } = {}) {
|
|
82
|
+
const fromEnv = resolveEnv('API_BASE', { env, prefix: envPrefix(b) });
|
|
83
|
+
if (fromEnv) return fromEnv;
|
|
84
|
+
let s = session;
|
|
85
|
+
if (s === undefined) {
|
|
86
|
+
try {
|
|
87
|
+
const raw = readConfigFileSync('gds-session.json', { b });
|
|
88
|
+
s = raw ? JSON.parse(raw) : null;
|
|
89
|
+
} catch (_) {
|
|
90
|
+
s = null; // unreadable/corrupt session must never break base resolution
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
const fromSession = s && typeof s.api_base === 'string' && s.api_base.trim();
|
|
94
|
+
return fromSession || defaultApiBase(b);
|
|
95
|
+
}
|
|
96
|
+
|
|
53
97
|
// Absolute path to the instance config dir — the WRITE target and first read.
|
|
54
98
|
function configHome(b = safeBrand()) {
|
|
55
99
|
return path.join(os.homedir(), '.config', configDirName(b));
|
|
@@ -186,6 +230,8 @@ module.exports = {
|
|
|
186
230
|
LEGACY_ENV_PREFIXES,
|
|
187
231
|
configDirName,
|
|
188
232
|
envPrefix,
|
|
233
|
+
defaultApiBase,
|
|
234
|
+
resolveApiBase,
|
|
189
235
|
configHome,
|
|
190
236
|
configReadDirs,
|
|
191
237
|
configPath,
|
package/src/module-api.js
CHANGED
|
@@ -218,8 +218,138 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
218
218
|
// post-dates the published 1.17.3 tarball — a new user-facing feature set with no
|
|
219
219
|
// doorway export removal, so semver MINOR. NOT yet published to npm (that is the
|
|
220
220
|
// follow-on release task); amazonprimea still runs the vendored 1.17.3.
|
|
221
|
+
// 1.18.1 — go-live cut deployed to cloudbongos.com (owner-directed, 2026-07-14). Rolling
|
|
222
|
+
// 1.18.0 content PLUS the onboarding GitHub repo picker + auto-create (task 1002099,
|
|
223
|
+
// ADR 0143 — core auth: opt-in public_repo scope, encrypted short-TTL token store,
|
|
224
|
+
// GET/POST /github/repos) and the goal 1000041 cross-project hub features
|
|
225
|
+
// (platform-identity module, ADR 0141). Adds no doorway export → semver PATCH.
|
|
226
|
+
// 1.18.2 — go-live cut for cloudbongos.com (owner-directed, 2026-07-14). Rolling 1.18.1
|
|
227
|
+
// content PLUS the /create onboarding repo-picker rendering fix (task 1002228):
|
|
228
|
+
// the Home step's `hidden` attribute was defeated by author display rules
|
|
229
|
+
// (.field/.row2), so the adopt-picker / fresh-name / manual sub-panels all showed
|
|
230
|
+
// at once, and #ghConnect never appeared (toggled via `hidden` instead of its .on
|
|
231
|
+
// class). A CSS/markup-only fix in public-landing/create.html. No doorway export
|
|
232
|
+
// change → semver PATCH.
|
|
233
|
+
// 1.18.3 — package-core .gitignore pin fix (task 1002229, idea 1000543). `npm install` never
|
|
234
|
+
// materializes .gitignore/.npmignore/.npmrc into an installed package, but package-core
|
|
235
|
+
// pinned a tracked .gitignore in tree_sha256 → every vendored `bongos upgrade` pin-verify
|
|
236
|
+
// failed with `missing installed file: .gitignore` and auto-rolled-back (the workaround
|
|
237
|
+
// was --skip-pin-verify, which the unattended auto-upgrade subscription cannot pass).
|
|
238
|
+
// package-core now drops npm-stripped files from the manifest + pin so it describes exactly
|
|
239
|
+
// what npm installs. Build-tool fix, no doorway export change → semver PATCH.
|
|
240
|
+
// 1.18.4 — ship the platform-identity hub module in the core package (task 1002235, goal 1000041).
|
|
241
|
+
// The module (ADR 0141: /sso/*, projects catalog, my-projects, scouting + its migrations) was
|
|
242
|
+
// built but never added to publish-manifest PUBLISH_ALLOWLIST, so it did not ship in
|
|
243
|
+
// @bongos/core — the hub's enabledModules() threw "unknown module platform-identity" and
|
|
244
|
+
// provision.js's federation load MODULE_NOT_FOUNDed. Reclassified IN (sibling of provisioning);
|
|
245
|
+
// default:false → shipped ≠ enabled, dormant on every instance until the hub turns it on. PATCH.
|
|
246
|
+
// 1.18.5 — configurable post-login landing (task 1002240, goal 1000041). A successful web sign-in
|
|
247
|
+
// that carried no explicit ?return= / same-apex Referer now lands on branding.landing.postLogin
|
|
248
|
+
// (auth.js postLoginLanding) instead of a hardcoded /builders. Portable default stays
|
|
249
|
+
// '/builders' (the hall always exists); env-overridable per instance via
|
|
250
|
+
// <PREFIX>_POST_LOGIN_LANDING. cloudbongos.com sets it to /gate/ so a visitor who signs in
|
|
251
|
+
// from the orbs returns to the orbs, never auto-redirected into the builders' hall. The value
|
|
252
|
+
// is validated through the open-redirect allowlist. Additive config read, no doorway change → PATCH.
|
|
253
|
+
// 1.18.6 — post-login ?return= fix (task 1002241). parseCookie() now URL-DECODES the cookie
|
|
254
|
+
// value, symmetric with Express res.cookie's percent-ENCODING. Before this, a return
|
|
255
|
+
// target like "/create" was stored as "%2Fcreate"; safeReturnTo() rejected the encoded
|
|
256
|
+
// form and every explicit ?return= fell through to the post-login landing (on
|
|
257
|
+
// cloudbongos.com, /gate/) — most visibly the onboarding "Connect GitHub" button, which
|
|
258
|
+
// bounced to the orbs instead of back to the wizard. Also un-breaks the #726 subdomain
|
|
259
|
+
// return. A bug fix in a shared route helper, no doorway change → PATCH.
|
|
260
|
+
// 1.18.7 — federated single-logout (task 1002238, goal 1000041, ADR 0144). Signing out of the hub now
|
|
261
|
+
// signs you out of every federated project too. Core gains: a `builder.logout` seam event
|
|
262
|
+
// (emitted by POST /auth/logout), a POST /auth/backchannel-logout endpoint (dormant unless the
|
|
263
|
+
// instance federates — idp set), and auth.js verifyHubLogoutToken. The hub (platform-identity)
|
|
264
|
+
// listens for builder.logout and fans a hub-signed EdDSA logout token out to each federated
|
|
265
|
+
// instance the builder entered, which verifies it (aud-scoped, purpose-tagged, ~120s TTL) and
|
|
266
|
+
// revokes that builder's local sessions. Identity/trust boundary intact (the token carries only
|
|
267
|
+
// a subject + purpose, never a rank). Additive event + route, no doorway change → PATCH.
|
|
268
|
+
// 1.18.8 — hall sign-out works on every page (task 1002245). The real sign-out (POST /auth/logout:
|
|
269
|
+
// revoke session + clear cookies + emit the `builder.logout` federated single-logout) was wired
|
|
270
|
+
// ONLY in the index script (builders.js); shell.js draws the sign-out control on EVERY hall page
|
|
271
|
+
// as a bare GET anchor to the POST-only endpoint, so on non-index pages the click 404'd — the
|
|
272
|
+
// session was never revoked and the hub never notified (the 1.18.7 SLO was bypassed). Centralized
|
|
273
|
+
// in shell.js (doLogout + a delegated click listener), with tests/hall_signout.mjs proving it.
|
|
274
|
+
// Also carries minor /create wizard polish (tasks 1002246/1002247). Client + shared-surface fix,
|
|
275
|
+
// no doorway change → PATCH.
|
|
276
|
+
// 1.18.9 — /create onboarding: the wizard's own "Sign in with GitHub" now requests repo scope up front
|
|
277
|
+
// (read:user + public_repo via &repos=1), so a visitor who signs in THROUGH the create flow grants
|
|
278
|
+
// everything in one GitHub screen and never hits the separate "Connect GitHub" step at Home —
|
|
279
|
+
// ensureRepoAccess()'s probe finds the stored token and shows the picker/creator directly. Also
|
|
280
|
+
// reworks the residual need-connect copy + button ("Allow repo access") so a user already signed
|
|
281
|
+
// in with identity-only scope isn't asked to "connect" as if signing in twice. Hall + CLI sign-in
|
|
282
|
+
// stay identity-only (ADR 0143 least-privilege default). Client-only (public-landing/create.html),
|
|
283
|
+
// no doorway change → PATCH. (task 1002259)
|
|
284
|
+
// 1.18.10 — reward-mode go-live: the configurable per-instance branding.reward.mode knob (economy;
|
|
285
|
+
// ADR 0146) lands together with the goal-1000037 pay-on-land migrations. Cloud Bongos selects
|
|
286
|
+
// "cost-plus-only" (instance config), so a shipped task pays only the cost-plus session reward,
|
|
287
|
+
// not the per-task author estimate; the estimate still rides the row for display + the no-zero
|
|
288
|
+
// claim gate. This deploy applies core_193 (tasks.needs_rebase columns) + core_194 (the one-time
|
|
289
|
+
// confirmed-backlog clawback). Default stays "cost-plus-and-estimate" → every other instance is
|
|
290
|
+
// unchanged; economy-only, no doorway change → PATCH. (task 1002270 + goal 1000037 go-live 1002273)
|
|
291
|
+
// 1.18.12 — Docs-surface correctness (task 1002374). User-facing "GDS"/"Game Development System" →
|
|
292
|
+
// "Bongos" (primer, OpenAPI spec title/description + reference header, the two CLI session
|
|
293
|
+
// messages the primer quotes). 04-architecture diagram REDRAWN for the standalone model —
|
|
294
|
+
// own repo + auto-pull deploy (ADR 0129) + vendored @bongos/core (ADR 0108), product-neutral;
|
|
295
|
+
// it had hardcoded the reference game monorepo (amazonprimea.com / GitHub-Actions deploy-prod.yml
|
|
296
|
+
// / "the live game"). Docs/prose + diagram generator only, no schema/doorway change → PATCH.
|
|
297
|
+
// 1.18.11 — Standalone instances get live-updating docs (ADR 0147, task 1002314). gen-session-index.js
|
|
298
|
+
// now resolves the INSTANCE root (was hardcoded to the core, so a standalone box indexed
|
|
299
|
+
// node_modules/@bongos/core instead of its own sessions); adds upgrade.regenerateNavDocs() +
|
|
300
|
+
// a regen-instance-docs.js CLI wired into init/upgrade/provision-deploy; INSTANCE_GITIGNORE
|
|
301
|
+
// ignores the whole-file nav docs. Docs-pipeline only, no schema/doorway change → PATCH.
|
|
302
|
+
// (go-live 1002318)
|
|
303
|
+
// 1.18.12 — docs-surface correctness: GDS→Bongos rename + standalone architecture redraw
|
|
304
|
+
// (task 1002374). Docs/prose + diagram generator only, no schema/doorway change → PATCH.
|
|
305
|
+
// 1.18.13 — `bongos dev`: one-command LOCAL launcher for a standalone instance (task 1002397,
|
|
306
|
+
// ADR 0149). New CLI verb + scripts/gds/dev.js + dev-lib.js so a freshly-created,
|
|
307
|
+
// localhost-configured project stands up locally in one step. No schema/doorway change → PATCH.
|
|
308
|
+
// 1.18.14 — module pollers actually start on a standalone instance (task 1002419). The loader's
|
|
309
|
+
// startModulePollers had ZERO callers once the game entrypoint server.js was retired, so
|
|
310
|
+
// EVERY module poller was dead — most visibly lifecycle/publish-reconciler, which is what
|
|
311
|
+
// drives confirmed→shipped, leaving merged tasks stranded at 'confirmed' indefinitely
|
|
312
|
+
// (12 rows, oldest 6.2 days). src/platform-server.js now starts them at boot behind the
|
|
313
|
+
// same isEnabled gate mountModuleRoutes uses, and stops them on SIGTERM/SIGINT. Wiring
|
|
314
|
+
// only — no schema/doorway change → PATCH. Any instance on ≤1.18.13 lands nothing until
|
|
315
|
+
// it takes this bump.
|
|
316
|
+
// 1.18.15 — re-release of the 1.18.14 module-poller fix (task 1002419) under a fresh number.
|
|
317
|
+
// A SEPARATE release had already published 1.18.14 for the task-scoped dev-box go-live
|
|
318
|
+
// (goal 1000051), so the poller-fix 1.18.14 could never reach an instance already pinned to
|
|
319
|
+
// the dev-box 1.18.14 (same version = npm no-op; the pull-deploy loop skips npm ci when the
|
|
320
|
+
// lockfile is unchanged). This bump carries the identical src/platform-server.js poller
|
|
321
|
+
// wiring forward on a number no instance has taken yet, so the pin can actually move. No
|
|
322
|
+
// code delta vs the 1.18.14 already on main — version constant only → PATCH. (task 1002421)
|
|
323
|
+
// 1.18.16 — go-live carrier for the hall version-UI work already merged to main since 1.18.15:
|
|
324
|
+
// the Roadmap "Command deck" redesign (task 1002426) and the sidebar reorg — nav order
|
|
325
|
+
// Roadmap→Goals→Tasks, the "Work" board relabelled "Tasks", goal-detail task parity
|
|
326
|
+
// (task 1002425, PR #17). Both landed on main with NO version bump, so no vendored-tarball
|
|
327
|
+
// instance could take them (the pull-deploy pin only moves on a fresh number). No new code
|
|
328
|
+
// delta beyond this constant → PATCH. (go-live task 1002431)
|
|
329
|
+
// 1.18.17 — Goals page reorganised into a task-readiness rollup (grouped
|
|
330
|
+
// Active/Blocked/Achieved; each goal rolls its tasks into ready/in-progress/
|
|
331
|
+
// blocked + a next claimable task) and the task-list API gained an opt-in
|
|
332
|
+
// `?include=deps` that enriches each task with blocked_by[]/blocks so the
|
|
333
|
+
// hall can paint readiness without an N+1 (db.attachTaskDepSummaries). New
|
|
334
|
+
// export is additive; the enrichment is opt-in → PATCH. (task 1002439)
|
|
335
|
+
// 1.18.18 — go-live carrier for 171 commits that landed on main between 2026-07-24
|
|
336
|
+
// and 2026-08-03 with no bump behind them, so no vendored-tarball instance
|
|
337
|
+
// could take any of them. Headline: the governance permission system
|
|
338
|
+
// (BV1.R95–R109 — resolver + kernel port, first-class principals, session
|
|
339
|
+
// scopes, requirePermission(), ownership-scoped grants, config/governance.json)
|
|
340
|
+
// and the route-rank/validation hardening that followed it; the ship.js
|
|
341
|
+
// Windows project-path fix so Windows sessions actually get paid (89f291c);
|
|
342
|
+
// the sequential chain runner (task 1002484); Metic task abandon/un-abandon
|
|
343
|
+
// (ADR 0152); goal-authored criteria + the orphan-task goal_advisory (ADR
|
|
344
|
+
// 0154); the nightly-backup 203/EXEC fix (task 1002479); and a broad hall
|
|
345
|
+
// pass (jump palette, sidebar regroup, browser-side idea triage, mobile
|
|
346
|
+
// overflow). This bump also carries the /version-vs-CORE_VERSION divergence
|
|
347
|
+
// check added under task 1002521 — the gap above went unnoticed for ten days
|
|
348
|
+
// precisely because nothing compared live against main. The doorway surface
|
|
349
|
+
// is byte-identical to 1.18.17 (governance is reached through the kernel
|
|
350
|
+
// port, not a new export), so despite the size this is → PATCH. (task 1002521)
|
|
221
351
|
// ---------------------------------------------------------------------------
|
|
222
|
-
const CORE_VERSION = '1.18.
|
|
352
|
+
const CORE_VERSION = '1.18.18'; // go-live carrier for 171 unreleased commits + the deploy-divergence check (task 1002521); see changelog above
|
|
223
353
|
|
|
224
354
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
225
355
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -245,6 +375,15 @@ module.exports = {
|
|
|
245
375
|
// tokens. A module's own bootstrap routes flag themselves; everything else
|
|
246
376
|
// stays closed to box tokens (the ADR 0016 trust boundary).
|
|
247
377
|
allowBoxScope: auth.allowBoxScope,
|
|
378
|
+
// resolveSession(req) — resolve the request to a live session row (or null)
|
|
379
|
+
// WITHOUT the 401-or-pass behaviour of requireBuilder. A module route that
|
|
380
|
+
// must make its own auth decision — e.g. a browser page that REDIRECTS to
|
|
381
|
+
// sign-in on a missing session rather than returning JSON 401 (the
|
|
382
|
+
// platform-identity /sso/authorize leg, ADR 0141) — needs the raw resolve.
|
|
383
|
+
// Returns the same shape lookupSession does (builder_id, github_id,
|
|
384
|
+
// github_login, display_name, avatar_url, rank, source, status); rank is
|
|
385
|
+
// still never an authority a module should trust for cross-instance identity.
|
|
386
|
+
resolveSession: (...a) => auth.resolveSession(...a),
|
|
248
387
|
|
|
249
388
|
// --- data — the shared Postgres pool. A module owns its namespaced tables
|
|
250
389
|
// (<key>_*) via its own migrations (BV1.R46); it reaches them through this.
|