@bongos/core 1.18.3 → 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 +1575 -285
- 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 +4 -2
- 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 +6 -1
- 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/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 +10 -0
- package/docs/api/openapi.json +843 -17
- package/docs/api-reference.md +23 -10
- 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 +8 -0
- 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/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/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/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/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/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/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 +51 -58
- 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 -27
- 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/login.js +16 -1
- package/scripts/gds/paste-token.js +7 -1
- package/scripts/gds/preflight.js +126 -0
- package/scripts/gds/provision.js +123 -12
- package/scripts/gds/publish-manifest.js +7 -1
- package/scripts/gds/reauth.js +7 -3
- package/scripts/gds/regen-instance-docs.js +47 -0
- package/scripts/gds/run-unit-tests.js +4 -2
- 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 +31 -5
- package/scripts/gds/shell.js +5 -3
- package/scripts/gds/ship.js +319 -29
- 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 +124 -2
- package/scripts/status-mirror-sync.js +114 -84
- package/src/bongos/api-errors.js +1 -0
- package/src/bongos/auth.js +447 -102
- package/src/bongos/db-kernel.js +27 -0
- package/src/bongos/db.js +39 -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 +219 -2
- package/src/bongos/routes/backup.js +58 -2
- package/src/bongos/routes/me.js +35 -1
- package/src/bongos/serve-internal.js +84 -15
- package/src/branding.js +32 -0
- package/src/instance-config.js +30 -0
- package/src/module-api.js +112 -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 +12 -0
- 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/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 +93 -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/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/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 +132 -7
- 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 +80 -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 +139 -0
- package/tests/web_admission_status.mjs +162 -0
- package/tests/write_validation_gaps.mjs +110 -0
|
@@ -104,8 +104,8 @@ const LIFECYCLE_EDGES = [
|
|
|
104
104
|
['blocked', 'active', 'blocker resolved'],
|
|
105
105
|
['active', 'ready', '/builder-release (no credits)'],
|
|
106
106
|
['active', 'completed', '/builder-ship: declared done + smoke tests'],
|
|
107
|
-
['completed', 'confirmed', 'grader passes
|
|
108
|
-
['confirmed', 'shipped', 'CI + gate-review → auto-merge + deploy'],
|
|
107
|
+
['completed', 'confirmed', 'grader passes (verified — not yet paid)'],
|
|
108
|
+
['confirmed', 'shipped', 'CI + gate-review → auto-merge + deploy ◀ CREDITS AWARDED HERE'],
|
|
109
109
|
['backlog', 'abandoned', 'dropped'],
|
|
110
110
|
];
|
|
111
111
|
|
|
@@ -297,7 +297,7 @@ function drachmaeKarmaMmd(f) {
|
|
|
297
297
|
` subgraph CURRENCY["${CUR} (the builder reward — equity / reputation, a stake, not a spendable currency)"]`,
|
|
298
298
|
' direction TB',
|
|
299
299
|
' D_TOKEN["Ship a SESSION — the main reward\\nround(true_cost_usd × 1.20) cents — cost-plus on real token spend\\n(LIVE: priced server-side from token counts; ADR 0054, idempotent per session)"]',
|
|
300
|
-
' D_SHIP["
|
|
300
|
+
' D_SHIP["SHIP a TASK — books when the code lands on main, not at confirm\\ncredits_reward × kind multiplier (0.8–1.5×)\\n+ 25% idea-promotion bonus to the capturer\\n(LIVE: ADR 0023; pay-on-land ADR 0120; withheld entirely on a cost-plus-only instance, ADR 0146)"]',
|
|
301
301
|
` D_ACH["Unlock an achievement\\nachievements.credit_bonus (LIVE: ${nAch} seeded)\\n+ small net-negative-ship bonus"]`,
|
|
302
302
|
` D_BOUNTY["Red-team / security bounty\\n${currency} payout by severity\\n(rate card ${rateCard ? 'LIVE' : 'PLANNED'}: R65 #284 — src/bongos/security.js + shown on /builders;\\nawarding still ${awarding ? 'LIVE' : 'PLANNED'}: R67 #286 + vulnerability_reports R63 #282)"]`,
|
|
303
303
|
'',
|
|
@@ -375,10 +375,18 @@ function architectureMmd(f) {
|
|
|
375
375
|
? 'GitHub App, short-lived tokens'
|
|
376
376
|
: 'standing push PAT (GitHub App pending — 1028)';
|
|
377
377
|
// The whole box→prod chain LIVE? (all the gated legs + the end-to-end verify.)
|
|
378
|
-
|
|
378
|
+
// NB the deploy leg is the standalone AUTO-PULL (ADR 0108/0129), not a task-gated
|
|
379
|
+
// GitHub-Actions CI job — so 859 (CI deploy) is intentionally NOT in this set.
|
|
380
|
+
const chainLive = [919, 897, 904, 774, 1025, 1028, 1027].every(shipped);
|
|
379
381
|
const closingNote = chainLive
|
|
380
|
-
? 'The whole box → production path is LIVE and hardware-verified end-to-end (1027 · 1028).'
|
|
381
|
-
: `Still landing (PLANNED):
|
|
382
|
+
? 'The whole box → production path is LIVE: a credential-less box uploads its branch, the server merges it, and the instance auto-pulls + redeploys — hardware-verified end-to-end (1027 · 1028).'
|
|
383
|
+
: `Still landing (PLANNED): the server-mediated publish (${tag(1025)} · 1025) and the GitHub App push credential (${tag(1028)} · 1028).`;
|
|
384
|
+
|
|
385
|
+
// Product-neutral runtime label: the instance's own product name (branding),
|
|
386
|
+
// NOT a hard-coded "game" (this core powers any app, not only the reference
|
|
387
|
+
// game instance). Falls back to a generic phrase when branding carries none.
|
|
388
|
+
const productName = brand().productName;
|
|
389
|
+
const appLabel = productName && productName !== 'Cloud Bongos' ? productName : 'app';
|
|
382
390
|
|
|
383
391
|
// Layout: ELK engine, top-down (task 1066). ELK minimizes edge crossings far
|
|
384
392
|
// better than the default renderer — this map is edge-dense and was a tangle
|
|
@@ -390,16 +398,18 @@ function architectureMmd(f) {
|
|
|
390
398
|
// low-signal annotation edges (box-token→bootstrap, DB-is-king, memory-
|
|
391
399
|
// follows-you) are folded into node labels. (3) WATERFALL ordering (task 1073,
|
|
392
400
|
// off Lars's "put the GitHub box last"): subgraphs are declared in flow order
|
|
393
|
-
// DEVICE→BOX→SERVER→GH, and the live
|
|
394
|
-
// into its own terminal node at the very
|
|
395
|
-
// Node process" so it stays honest).
|
|
396
|
-
// spine — device→box→server→github→
|
|
397
|
-
//
|
|
398
|
-
// tucks directly under BOX and the
|
|
399
|
-
// sync, pull, claim/ship) become short hops
|
|
400
|
-
// height past a mid-stack GitHub. The
|
|
401
|
-
//
|
|
402
|
-
//
|
|
401
|
+
// DEVICE→BOX→SERVER→GH, and the live app (the instance's product runtime) is
|
|
402
|
+
// pulled OUT of the SERVER cluster into its own terminal node at the very
|
|
403
|
+
// bottom (annotated "same server · same Node process" so it stays honest).
|
|
404
|
+
// That makes the map one monotonic top-down spine — device→box→server→github→
|
|
405
|
+
// live app — where the deploy is the LAST forward step instead of an edge
|
|
406
|
+
// looping back UP into the server. So SERVER tucks directly under BOX and the
|
|
407
|
+
// BOX↔SERVER wires (re-auth, upload, sync, pull, claim/ship) become short hops
|
|
408
|
+
// instead of detouring the full height past a mid-stack GitHub. The deploy is
|
|
409
|
+
// the STANDALONE auto-pull (ADR 0108/0129): merge to the instance's own main →
|
|
410
|
+
// the server pulls its own repo → migrate/regenerate/restart → the live app —
|
|
411
|
+
// NOT a GitHub-Actions push-deploy (that was the reference monorepo's model).
|
|
412
|
+
// NOTE on direction: we keep TB,
|
|
403
413
|
// not a repo-on-the-left LR/RL — the flow is an ~8-deep linear chain, so a
|
|
404
414
|
// sideways layout stretches into an unreadable ~5:1 strip; top-down keeps a
|
|
405
415
|
// legible aspect.
|
|
@@ -419,25 +429,26 @@ function architectureMmd(f) {
|
|
|
419
429
|
` CODE["the code — git clone + per-builder worktrees (.claude/worktrees/*)\\nfor sub-Metic builders it lives ONLY here · CLAUDE.md is DESCRIPTIVE only"]`,
|
|
420
430
|
' LOCAL["local ~/.claude memory\\nMAP = MEMORY.md — a one-line index loaded EVERY session\\n(a guard + auto-tidy keep it light; ADR 0074)\\n+ drawer of full notes, loaded only on demand"]',
|
|
421
431
|
' ORIGIN["credential-less git origin\\n(NO GitHub push secret on the box — by design)"]',
|
|
422
|
-
` BOXTOK["box-scoped
|
|
432
|
+
` BOXTOK["box-scoped Bongos token\\n(deny-by-default: bootstrap endpoints only;\\nrejected for branch upload → re-auth first — ${tag(919)})"]`,
|
|
423
433
|
` PREVIEW["sandbox preview server on :3000\\n→ a per-builder sandbox URL (${tag(897)})"]`,
|
|
424
434
|
` SWITCH["on / off + browser terminal\\n(desktop app ${tag(904)} · ttyd-over-tunnel ${tag(774)})"]`,
|
|
425
435
|
' end',
|
|
426
436
|
'',
|
|
427
|
-
` subgraph SERVER["THE SERVER — ${host} (the authority AND production)"]`,
|
|
428
|
-
' API["/api/
|
|
437
|
+
` subgraph SERVER["THE INSTANCE SERVER — ${host} (the authority AND production)"]`,
|
|
438
|
+
' API["/api/bongos/* (same Node process as the app)"]',
|
|
439
|
+
' CORE["@bongos/core — the build platform, VENDORED as a pinned dependency\\n(ADR 0108: central updates are a version-pin bump via `bongos upgrade`, not a merge)"]',
|
|
429
440
|
' DB["Postgres — tasks · claims · versions · builders.rank\\ncredit_log · grades · idea_inbox · builder_memory\\n(KING for work-state + permissions; CLAUDE.md only describes it)"]',
|
|
430
441
|
' RANK["auth.requireRank — checked per request, NO caching\\n(ADR 0016: a demotion takes effect on the next request)"]',
|
|
431
442
|
` SRVMEM["server-side builder_memory store\\n${memLead}: per-builder · isolated · Archon-audited forensic read\\nyour memory follows you across machines & worktrees\\n/recall fetches only the relevant subset (ADR 0060)\\n(${memStatus})"]`,
|
|
432
443
|
` PUSHTOK["server-held push credential\\n(${pushCred} — the box never holds it)"]`,
|
|
444
|
+
' DEPLOY["auto-pull deploy (ADR 0129)\\na timer pulls THIS instance repo every ~2 min →\\nnpm ci if the pin changed → migrate → regenerate docs → restart → healthz"]',
|
|
433
445
|
' end',
|
|
434
446
|
'',
|
|
435
|
-
` subgraph GH["GITHUB — the
|
|
436
|
-
' MAIN["branch-protected main\\n(no direct push; PR + required checks only)"]',
|
|
437
|
-
' ACTIONS["GitHub Actions — deploy-prod.yml"]',
|
|
447
|
+
` subgraph GH["GITHUB — the instance's own repo (${c.repoSlug})"]`,
|
|
448
|
+
' MAIN["branch-protected main\\n(no direct push; PR + required checks only)\\nholds config + the pinned @bongos/core — NOT the platform source"]',
|
|
438
449
|
' end',
|
|
439
450
|
'',
|
|
440
|
-
`
|
|
451
|
+
` LIVEAPP["the live ${appLabel} — ${host}\\n(same server · same Node process as /api/bongos/*)"]`,
|
|
441
452
|
'',
|
|
442
453
|
' APP -->|"1 · toggle box on / open terminal"| SWITCH',
|
|
443
454
|
' SWITCH --> WORKER',
|
|
@@ -445,8 +456,9 @@ function architectureMmd(f) {
|
|
|
445
456
|
' WORKER -->|"3 · re-auth in browser"| API',
|
|
446
457
|
flow('WORKER', 1025, '4 · upload branch as a git bundle', 'API'),
|
|
447
458
|
flow('API', 1025, `5 · push + open PR + auto-merge (${tag(1025)})`, 'MAIN'),
|
|
448
|
-
|
|
449
|
-
'
|
|
459
|
+
' MAIN -->|"6 · the instance auto-pulls its own main"| DEPLOY',
|
|
460
|
+
' DEPLOY -->|"7 · migrate · regenerate docs · restart"| LIVEAPP',
|
|
461
|
+
' CORE --- API',
|
|
450
462
|
' PUSHTOK -.-> API',
|
|
451
463
|
' ORIGIN -. "direct push blocked" .-> MAIN',
|
|
452
464
|
' API -. "claim / ship / cost" .-> WORKER',
|
|
@@ -454,7 +466,7 @@ function architectureMmd(f) {
|
|
|
454
466
|
` ${pullEdge}`,
|
|
455
467
|
'',
|
|
456
468
|
` NEXT["${closingNote}"]`,
|
|
457
|
-
'
|
|
469
|
+
' LIVEAPP --- NEXT',
|
|
458
470
|
];
|
|
459
471
|
return lines.join('\n') + '\n';
|
|
460
472
|
}
|
|
@@ -467,6 +479,11 @@ function rebuildAssertions(prev, f) {
|
|
|
467
479
|
next.rank_ladder.default_rank = f.default_rank;
|
|
468
480
|
next.rank_ladder.wired_ranks = f.wired_ranks;
|
|
469
481
|
next.task_lifecycle.task_statuses = f.task_statuses;
|
|
482
|
+
// Derived from LIFECYCLE_EDGES so this assertion can never drift from the
|
|
483
|
+
// rendered diagram again (it silently outlived ADR 0120's move of the award
|
|
484
|
+
// from completed→confirmed to confirmed→shipped).
|
|
485
|
+
const creditEdge = LIFECYCLE_EDGES.find(([, , label]) => label.includes('CREDITS AWARDED HERE'));
|
|
486
|
+
if (creditEdge) next.task_lifecycle.credits_awarded_at = `${creditEdge[0]}->${creditEdge[1]}`;
|
|
470
487
|
// Persist only the stable identity fields (drop started_at ordering helper).
|
|
471
488
|
next.versioning.diagram = '05-versioning';
|
|
472
489
|
next.versioning.versions = f.versions.map((v) => ({ id: v.id, status: v.status }));
|
|
@@ -485,11 +502,11 @@ function rebuildAssertions(prev, f) {
|
|
|
485
502
|
|
|
486
503
|
// 04-architecture — the ADR 0024 memory chain + the dev-box / box→prod ship
|
|
487
504
|
// flow, merged (task 1059). A piece is LIVE iff its backing task is shipped.
|
|
488
|
-
const arch = split([273, 274, 275, 276, 904, 774, 897, 919, 1025,
|
|
505
|
+
const arch = split([273, 274, 275, 276, 904, 774, 897, 919, 1025, 1027, 1028]);
|
|
489
506
|
next.architecture = {
|
|
490
507
|
diagram: '04-architecture',
|
|
491
508
|
_comment:
|
|
492
|
-
"Pieces of 04-architecture gated on a backing GDS task. A piece is LIVE iff its task is 'shipped'; live_tasks must ALL be shipped, pending_tasks must NOT yet be. Rebuilt by scripts/gds/gen-diagrams.js in lockstep with the diagram, so this is the drift checker's backstop. The device/box/server/GitHub topology is structural (not task-gated); these are the LIVE/PLANNED markers. MEMORY layer (ADR 0024): 273 schema / 274 sync-on-ship / 275 pull-on-start / 276 isolation. DEV BOX + box→prod: 904/774 (on-off + browser terminal), 897 (sandbox preview), 919 (scoped box token), 1025 (server-mediated publish),
|
|
509
|
+
"Pieces of 04-architecture gated on a backing GDS task. A piece is LIVE iff its task is 'shipped'; live_tasks must ALL be shipped, pending_tasks must NOT yet be. Rebuilt by scripts/gds/gen-diagrams.js in lockstep with the diagram, so this is the drift checker's backstop. The device/box/server/GitHub topology is structural (not task-gated); these are the LIVE/PLANNED markers. MEMORY layer (ADR 0024): 273 schema / 274 sync-on-ship / 275 pull-on-start / 276 isolation. DEV BOX + box→prod: 904/774 (on-off + browser terminal), 897 (sandbox preview), 919 (scoped box token), 1025 (server-mediated publish), 1028 (GitHub App push credential), 1027 (end-to-end hardware-verify). The deploy leg is the standalone AUTO-PULL (ADR 0108/0129), not a task-gated GitHub-Actions CI job, so 859 is intentionally absent. Supersedes the old server_repo_memory + dev_box slices.",
|
|
493
510
|
live_tasks: arch.live_tasks,
|
|
494
511
|
pending_tasks: arch.pending_tasks,
|
|
495
512
|
};
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
const fs = require('node:fs');
|
|
33
33
|
const path = require('node:path');
|
|
34
34
|
const { resolveInstanceRoot } = require('../../src/instance-config'); // ADR 0108 §1: configurable-root
|
|
35
|
+
const { sameContent } = require('./gen-freshness'); // eol-insensitive freshness (CRLF checkouts)
|
|
35
36
|
|
|
36
37
|
// ADR 0108 §Consequences #4 (configurable-root W6 / task 1886) — every target of this generator is
|
|
37
38
|
// INSTANCE-materialized content: the .claude/skills + .claude/scheduled-tasks it lists (materialized
|
|
@@ -141,7 +142,7 @@ function computeWrites() {
|
|
|
141
142
|
if (next.indexOf(begin(m.dir + '/')) === -1) { markersMissing.push(m.dir); continue; }
|
|
142
143
|
next = injectSection(next, m);
|
|
143
144
|
}
|
|
144
|
-
if (next
|
|
145
|
+
if (!sameContent(next, cur)) writes.push({ full: MAP_PATH, content: next, rel: 'docs/file-map.md' });
|
|
145
146
|
}
|
|
146
147
|
return { model, writes, missing, stale, markersMissing };
|
|
147
148
|
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// gen-freshness.js — how the doc generators decide "is the committed copy stale?"
|
|
2
|
+
//
|
|
3
|
+
// Shared by gen-repo-map / gen-session-index / gen-file-map / gen-api-docs, whose
|
|
4
|
+
// `--check` / `--check-block` modes back the fitness.js `generated artifacts fresh`
|
|
5
|
+
// hard gate.
|
|
6
|
+
//
|
|
7
|
+
// Why this exists: the generators render their blocks with `join('\n')` — always
|
|
8
|
+
// LF — but read the working copy with readFileSync, which on a `core.autocrlf=true`
|
|
9
|
+
// checkout (every default Windows clone) returns CRLF. A byte-wise `next !== cur`
|
|
10
|
+
// then reports STALE forever, and regenerating never clears it: the write lands as
|
|
11
|
+
// LF, git normalizes it back to CRLF on the next checkout, and the gate is red
|
|
12
|
+
// again. That is worse than noisy — a permanently-failing hard gate trains builders
|
|
13
|
+
// to ignore it, and it hides REAL drift, since the check is red either way.
|
|
14
|
+
//
|
|
15
|
+
// Freshness is a question about content, so compare content. Written bytes are
|
|
16
|
+
// unaffected: callers still write exactly the string they built, and git applies
|
|
17
|
+
// its own eol policy on commit.
|
|
18
|
+
'use strict';
|
|
19
|
+
|
|
20
|
+
// CRLF → LF. Lone-CR (classic Mac) is not normalized; no generator emits it and
|
|
21
|
+
// no checkout policy produces it, so treating it as content keeps this honest.
|
|
22
|
+
function normalizeEol(s) {
|
|
23
|
+
return String(s == null ? '' : s).replace(/\r\n/g, '\n');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// True when two documents are identical apart from line-ending convention.
|
|
27
|
+
// Use this for every freshness comparison — never `===` on raw file bytes.
|
|
28
|
+
function sameContent(a, b) {
|
|
29
|
+
return normalizeEol(a) === normalizeEol(b);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { normalizeEol, sameContent };
|
|
@@ -35,6 +35,7 @@ const { resolveCoreRoot, resolveInstanceRoot } = require('../../src/instance-con
|
|
|
35
35
|
// build the doc link-graph + staleness flags. Requiring it is side-effect-free
|
|
36
36
|
// (its CLI body is require.main-guarded).
|
|
37
37
|
const docsEntropy = require('./docs-entropy');
|
|
38
|
+
const { sameContent } = require('./gen-freshness'); // eol-insensitive freshness (CRLF checkouts)
|
|
38
39
|
|
|
39
40
|
// ADR 0108 §Consequences #4 (configurable-root W6 / task 1886) — the generator scans TWO trees.
|
|
40
41
|
// CORE code + the core-owned nested docs live under the core PACKAGE (resolveCoreRoot); the
|
|
@@ -475,7 +476,7 @@ function main() {
|
|
|
475
476
|
const mapPath = path.join(REPO_ROOT, 'docs', 'repo-map.md');
|
|
476
477
|
const mapNext = renderRepoMap(model);
|
|
477
478
|
const mapCur = fs.existsSync(mapPath) ? fs.readFileSync(mapPath, 'utf8') : '';
|
|
478
|
-
if (mapCur
|
|
479
|
+
if (!sameContent(mapCur, mapNext)) writes.push({ full: mapPath, content: mapNext, rel: 'docs/repo-map.md', bucket: 'whole' });
|
|
479
480
|
|
|
480
481
|
// 2) nested CLAUDE.md generated blocks (tracked; the HARD-gated bucket)
|
|
481
482
|
for (const dir of NESTED_DIRS) {
|
|
@@ -486,7 +487,7 @@ function main() {
|
|
|
486
487
|
}
|
|
487
488
|
const cur = fs.readFileSync(docPath, 'utf8');
|
|
488
489
|
const next = injectBlock(cur, renderNestedBlock(model, dir));
|
|
489
|
-
if (cur
|
|
490
|
+
if (!sameContent(cur, next)) writes.push({ full: docPath, content: next, rel: `${dir}/CLAUDE.md`, bucket: 'block' });
|
|
490
491
|
}
|
|
491
492
|
|
|
492
493
|
if (checkAll || checkWhole || checkBlock) {
|
|
@@ -30,8 +30,17 @@
|
|
|
30
30
|
|
|
31
31
|
const fs = require('node:fs');
|
|
32
32
|
const path = require('node:path');
|
|
33
|
-
|
|
34
|
-
const
|
|
33
|
+
const { resolveInstanceRoot } = require('../../src/instance-config'); // ADR 0108 §1: configurable-root
|
|
34
|
+
const { sameContent } = require('./gen-freshness'); // eol-insensitive freshness (CRLF checkouts)
|
|
35
|
+
|
|
36
|
+
// The session log, its index, and the CLAUDE.md §13 snippet are all HOST (instance) content —
|
|
37
|
+
// docs/session-logs/ + docs/session-log-index.md + the instance root CLAUDE.md. Resolve them under
|
|
38
|
+
// the host repo so a STANDALONE instance (core in node_modules, ADR 0108) indexes its OWN sessions,
|
|
39
|
+
// not the vendored core's. On the monorepo/at-ship this still resolves to the checkout (cwd
|
|
40
|
+
// fallback). Do NOT reintroduce a hardcoded `path.resolve(__dirname,'..','..')` — post-split it
|
|
41
|
+
// points INTO node_modules/@bongos/core (the exact bug gen-repo-map/gen-file-map warn against; the
|
|
42
|
+
// reason gen-session-index was writing the core's index on a standalone box — task 1002314).
|
|
43
|
+
const REPO_ROOT = resolveInstanceRoot();
|
|
35
44
|
const LOGS_DIR = path.join(REPO_ROOT, 'docs', 'session-logs');
|
|
36
45
|
const INDEX_PATH = path.join(REPO_ROOT, 'docs', 'session-log-index.md');
|
|
37
46
|
const CLAUDE_PATH = path.join(REPO_ROOT, 'CLAUDE.md');
|
|
@@ -100,7 +109,7 @@ function renderIndex(entries) {
|
|
|
100
109
|
const L = [];
|
|
101
110
|
L.push('# Session log — index');
|
|
102
111
|
L.push('');
|
|
103
|
-
L.push('> **AUTO-GENERATED — do not hand-edit.** Regenerate with `node scripts/gds/gen-session-index.js` (auto-regenerated + committed at ship, like `gen-repo-map.js`). Generated from the files in [`session-logs/`](session-logs/) so a link can never dangle (retires the recurring §13 drift: idea 57, [#580](https://
|
|
112
|
+
L.push('> **AUTO-GENERATED — do not hand-edit.** Regenerate with `node scripts/gds/gen-session-index.js` (auto-regenerated + committed at ship, like `gen-repo-map.js`). Generated from the files in [`session-logs/`](session-logs/) so a link can never dangle (retires the recurring §13 drift: idea 57, [#580](https://example.com/builders#/task/580)). The session PROSE is canonical in those files (older entries compressed into [`session-log-archive.md`](session-log-archive.md)); the DB session corpus (`session_logs` + the BFG `session_records`) is the structured record. See [ADR 0062](adr/0062-medusa-instance-model-decoupling.md) §8 · [ADR 0063](adr/0063-generated-repo-map-symbol-skeleton.md).');
|
|
104
113
|
L.push('');
|
|
105
114
|
L.push(`**${entries.length} sessions**, newest first.`);
|
|
106
115
|
L.push('');
|
|
@@ -144,12 +153,12 @@ function computeWrites() {
|
|
|
144
153
|
// stays a HARD CI gate. main() gates them separately (--check-block vs --check-whole).
|
|
145
154
|
const idxNext = renderIndex(entries);
|
|
146
155
|
const idxCur = fs.existsSync(INDEX_PATH) ? fs.readFileSync(INDEX_PATH, 'utf8') : '';
|
|
147
|
-
if (idxCur
|
|
156
|
+
if (!sameContent(idxCur, idxNext)) writes.push({ full: INDEX_PATH, content: idxNext, rel: 'docs/session-log-index.md', bucket: 'whole' });
|
|
148
157
|
|
|
149
158
|
if (fs.existsSync(CLAUDE_PATH)) {
|
|
150
159
|
const cur = fs.readFileSync(CLAUDE_PATH, 'utf8');
|
|
151
160
|
const next = injectSnippet(cur, renderSnippet(entries));
|
|
152
|
-
if (cur
|
|
161
|
+
if (!sameContent(cur, next)) {
|
|
153
162
|
if (next === cur && cur.indexOf(BEGIN) === -1) {
|
|
154
163
|
console.error('gen-session-index: WARN CLAUDE.md has no snippet markers — skipping snippet injection.');
|
|
155
164
|
} else {
|
|
@@ -28,7 +28,7 @@ const { execSync } = require('node:child_process');
|
|
|
28
28
|
const path = require('node:path');
|
|
29
29
|
|
|
30
30
|
const ppc = require(path.join(__dirname, '..', '..', '..', 'src', 'bongos', 'permission-path-check.js'));
|
|
31
|
-
const { apiCall } = require(path.join(__dirname, '..', 'cli-lib.js'));
|
|
31
|
+
const { apiCall, productName } = require(path.join(__dirname, '..', 'cli-lib.js'));
|
|
32
32
|
|
|
33
33
|
const ZERO = /^0+$/;
|
|
34
34
|
const MAIN_REF = 'refs/heads/main';
|
|
@@ -82,7 +82,7 @@ async function liveRank() {
|
|
|
82
82
|
}
|
|
83
83
|
|
|
84
84
|
function block(lines) {
|
|
85
|
-
console.error(
|
|
85
|
+
console.error(`\n\x1b[31m✖ push blocked by the ${productName()} permission gate (SEC #863)\x1b[0m`);
|
|
86
86
|
for (const l of lines) console.error(' ' + l);
|
|
87
87
|
console.error('');
|
|
88
88
|
process.exit(1);
|
package/scripts/gds/init.js
CHANGED
|
@@ -543,12 +543,51 @@ async function interview({ adopt = false } = {}) {
|
|
|
543
543
|
// Write + seed
|
|
544
544
|
// ---------------------------------------------------------------------------
|
|
545
545
|
|
|
546
|
+
// PURE (exported for tests) — the root START-HERE guide (task 1002404, goal
|
|
547
|
+
// 1000052). A freshly-CLONED instance must tell a human what to run FIRST: the
|
|
548
|
+
// `bongos` CLI ships INSIDE the not-yet-installed @bongos/core package, so
|
|
549
|
+
// `npm install` has to come before any `bongos` command (including `bongos dev`).
|
|
550
|
+
// `bongos init` runs npm install during scaffolding, but a later `git clone` of
|
|
551
|
+
// the committed instance repo skips that — so this file is the signpost the clone
|
|
552
|
+
// carries. Owner-friendly and plain-language (the owner may not be an engineer).
|
|
553
|
+
function buildReadme(branding = {}) {
|
|
554
|
+
const identity = branding.identity || {};
|
|
555
|
+
const name = identity.productName || 'This Cloud Bongos instance';
|
|
556
|
+
const origin = (branding.domains && branding.domains.publicOrigin) || '';
|
|
557
|
+
const loginLine = origin
|
|
558
|
+
? `3. \`bongos login ${origin}\` — only if you're signed in to a *different* instance (\`bongos dev\` signs you in the first time).`
|
|
559
|
+
: `3. \`bongos login <your-instance-url>\` — only if you're signed in to a *different* instance (\`bongos dev\` signs you in the first time).`;
|
|
560
|
+
return [
|
|
561
|
+
`# ${name}`,
|
|
562
|
+
'',
|
|
563
|
+
'A **Cloud Bongos** instance — an AI-first build platform: AI agents claim tasks and write the code; a human owner sets scope and the gates.',
|
|
564
|
+
'',
|
|
565
|
+
'## Start here (first run)',
|
|
566
|
+
'',
|
|
567
|
+
'Just cloned this repo? Run these **in order**. The `bongos` CLI ships *inside* the `@bongos/core` dependency, so step 1 comes first — until it runs there is no `bongos` command:',
|
|
568
|
+
'',
|
|
569
|
+
'1. `npm install` — installs the toolchain (this is what creates the `bongos` command).',
|
|
570
|
+
'2. `bongos dev` — one command to run this instance locally: starts Postgres, builds the tables, launches the server, and signs you in.',
|
|
571
|
+
loginLine,
|
|
572
|
+
'4. `bongos start` — see what you can work on. (Inside Claude Code, the same thing is `/builder-start`.)',
|
|
573
|
+
'',
|
|
574
|
+
'Requires Node >= 22 and Postgres installed locally (macOS/Linux; on Windows use WSL). If anything looks off, `bongos doctor` checks your setup and prints the fix.',
|
|
575
|
+
'',
|
|
576
|
+
'## Where to look next',
|
|
577
|
+
'',
|
|
578
|
+
'- `CLAUDE.md` — how this project is built (the operating manual agents read first).',
|
|
579
|
+
'- `bongos --help` — the full CLI: claim, ship, status, recall, and more.',
|
|
580
|
+
'',
|
|
581
|
+
].join('\n');
|
|
582
|
+
}
|
|
583
|
+
|
|
546
584
|
function writeConfigs(spec, { dir, force, dryRun, coreDep, log = console.log }) {
|
|
547
585
|
const configDir = path.join(dir, 'config');
|
|
548
586
|
const brandingPath = path.join(configDir, 'branding.json');
|
|
549
587
|
const modulesPath = path.join(configDir, 'modules.json');
|
|
550
588
|
const hierarchyPath = path.join(configDir, 'hierarchy.json');
|
|
551
589
|
const pkgPath = path.join(dir, 'package.json');
|
|
590
|
+
const readmePath = path.join(dir, 'README.md');
|
|
552
591
|
const branding = buildBrandingConfig(spec);
|
|
553
592
|
const modules = buildModulesConfig(spec);
|
|
554
593
|
const hierarchy = buildHierarchyConfig(spec);
|
|
@@ -574,7 +613,8 @@ function writeConfigs(spec, { dir, force, dryRun, coreDep, log = console.log })
|
|
|
574
613
|
log(JSON.stringify(hierarchy, null, 2));
|
|
575
614
|
log(`\n[dry-run] would write ${pkgPath} (pins ${CORE_PKG} → ${pinNote}):`);
|
|
576
615
|
log(JSON.stringify(pkg, null, 2));
|
|
577
|
-
|
|
616
|
+
log(`\n[dry-run] would write ${readmePath} (root START-HERE first-run guide) if absent`);
|
|
617
|
+
return { brandingPath, modulesPath, hierarchyPath, pkgPath, readmePath, wrote: false };
|
|
578
618
|
}
|
|
579
619
|
if (fs.existsSync(brandingPath) && !force) {
|
|
580
620
|
throw new Error(`${brandingPath} already exists — refusing to overwrite. Use --force to replace, or run init in a fresh --dir.`);
|
|
@@ -588,7 +628,15 @@ function writeConfigs(spec, { dir, force, dryRun, coreDep, log = console.log })
|
|
|
588
628
|
log(` ✓ wrote ${path.relative(dir, modulesPath)}`);
|
|
589
629
|
log(` ✓ wrote ${path.relative(dir, hierarchyPath)}`);
|
|
590
630
|
log(` ✓ wrote ${path.relative(dir, pkgPath)} (pins ${CORE_PKG} → ${pinNote})`);
|
|
591
|
-
|
|
631
|
+
// README START-HERE (task 1002404): write-if-absent so a --force re-init or an
|
|
632
|
+
// owner's own README is never clobbered.
|
|
633
|
+
if (!fs.existsSync(readmePath)) {
|
|
634
|
+
fs.writeFileSync(readmePath, buildReadme(branding));
|
|
635
|
+
log(` ✓ wrote ${path.relative(dir, readmePath)} (first-run START-HERE)`);
|
|
636
|
+
} else {
|
|
637
|
+
log(` • ${path.relative(dir, readmePath)} already present — left untouched`);
|
|
638
|
+
}
|
|
639
|
+
return { brandingPath, modulesPath, hierarchyPath, pkgPath, readmePath, wrote: true };
|
|
592
640
|
}
|
|
593
641
|
|
|
594
642
|
// `--adopt` config layering (ADR 0121 §Decision 2 / task 2042). The additive
|
|
@@ -955,11 +1003,20 @@ async function main(argv) {
|
|
|
955
1003
|
// catches any lag on the consumer's first CI.
|
|
956
1004
|
if (dryRun) {
|
|
957
1005
|
console.log('\n[dry-run] would regenerate the API artifacts (OpenAPI spec + reference + typed client) from the pinned core');
|
|
1006
|
+
console.log('[dry-run] would seed the whole-file navigation docs (session-log index) from the pinned core');
|
|
958
1007
|
} else {
|
|
959
1008
|
console.log('\nRegenerating the API artifacts from the pinned core (OpenAPI spec + reference + typed client):');
|
|
960
1009
|
const regen = upgrade.regenerateApiArtifacts({ instanceDir: dir, coreRoot: resolveCoreRoot() });
|
|
961
1010
|
if (regen.ok) console.log(` ✓ regenerated (${regen.ran.join(', ')}) → docs/api/ + docs/api-reference.md + clients/bongos-client/`);
|
|
962
1011
|
else console.error(` ! API-artifact regen skipped (${regen.reason}) — regenerate in ${dir} by hand; the instance-root fitness gate flags the lag otherwise.`);
|
|
1012
|
+
// Seed the whole-file navigation docs (session-log index) so a fresh instance's docs/ isn't
|
|
1013
|
+
// empty before its first deploy-regen (ADR 0110 / task 1002314). Gitignored on the instance —
|
|
1014
|
+
// this is a local seed; the ongoing refresh is regen-instance-docs.js on deploy + `bongos
|
|
1015
|
+
// upgrade`. Best-effort, mirrors the api-artifacts line: a hiccup warns, never fails init.
|
|
1016
|
+
console.log('\nSeeding the navigation docs from the pinned core (session-log index):');
|
|
1017
|
+
const nav = upgrade.regenerateNavDocs({ instanceDir: dir, coreRoot: resolveCoreRoot() });
|
|
1018
|
+
if (nav.ok) console.log(` ✓ seeded (${nav.ran.join(', ')}) → docs/`);
|
|
1019
|
+
else console.error(` ! nav-doc seed incomplete (failed: ${nav.failed.map((f) => f.gen).join(', ')}) — the deploy regen (regen-instance-docs.js) retries.`);
|
|
963
1020
|
}
|
|
964
1021
|
|
|
965
1022
|
let seedResult = {};
|
|
@@ -979,7 +1036,7 @@ async function main(argv) {
|
|
|
979
1036
|
}
|
|
980
1037
|
|
|
981
1038
|
module.exports = {
|
|
982
|
-
buildBrandingConfig, buildModulesConfig, buildHierarchyConfig, kickoffTasks, normalizeSpec,
|
|
1039
|
+
buildBrandingConfig, buildModulesConfig, buildHierarchyConfig, buildReadme, kickoffTasks, normalizeSpec,
|
|
983
1040
|
validateSpec, versionPayload, slugify, writeConfigs, seedViaApi, interview, main,
|
|
984
1041
|
provisioningSlug, provisioningRequest, productionTopologyKickoff,
|
|
985
1042
|
// --adopt (brownfield layering, ADR 0121 / task 2042)
|
|
@@ -36,7 +36,7 @@ function registerMergeDriver(root) {
|
|
|
36
36
|
// mangle %VARS on Windows cmd).
|
|
37
37
|
try {
|
|
38
38
|
execFileSync('git', ['config', `merge.${MERGE_DRIVER_NAME}.name`,
|
|
39
|
-
'
|
|
39
|
+
`${require('./cli-lib').productName()} generated-file regenerator (task 1243)`], { cwd: root, stdio: 'ignore' });
|
|
40
40
|
execFileSync('git', ['config', `merge.${MERGE_DRIVER_NAME}.driver`,
|
|
41
41
|
'node scripts/gds/git-merge-regen.js %O %A %B %P'], { cwd: root, stdio: 'ignore' });
|
|
42
42
|
return { ok: true };
|
package/scripts/gds/key-card.js
CHANGED
|
@@ -37,18 +37,27 @@
|
|
|
37
37
|
const fs = require('node:fs');
|
|
38
38
|
const os = require('node:os');
|
|
39
39
|
const path = require('node:path');
|
|
40
|
+
const ic = require('../../src/instance-config');
|
|
40
41
|
|
|
42
|
+
// NOTE the require path: this file lives in scripts/gds/, so branding is two
|
|
43
|
+
// levels up. It read '../src/branding' (= scripts/src/branding, which does not
|
|
44
|
+
// exist) until task 1002428 — so the require ALWAYS threw, safeBrand ALWAYS took
|
|
45
|
+
// the catch, and every key card told the builder to visit the hardcoded founder
|
|
46
|
+
// host regardless of which instance they were signed into.
|
|
47
|
+
//
|
|
48
|
+
// The settings URL now comes from the session-aware base (task 1002427), so it
|
|
49
|
+
// names the instance the builder is actually on; the neutral productName default
|
|
50
|
+
// is kept for the genuinely-unreadable-branding case.
|
|
41
51
|
function safeBrand() {
|
|
52
|
+
const settingsUrl = `${ic.resolveApiBase()}/builders/settings`;
|
|
42
53
|
try {
|
|
43
|
-
const b = require('
|
|
54
|
+
const b = require('../../src/branding').branding();
|
|
44
55
|
return {
|
|
45
56
|
productName: (b.identity && b.identity.productName) || 'Cloud Bongos',
|
|
46
|
-
settingsUrl
|
|
47
|
-
? `${b.domains.publicOrigin}/builders/settings`
|
|
48
|
-
: 'https://amazonprimea.com/builders/settings',
|
|
57
|
+
settingsUrl,
|
|
49
58
|
};
|
|
50
59
|
} catch (_) {
|
|
51
|
-
return { productName: 'Cloud Bongos', settingsUrl
|
|
60
|
+
return { productName: 'Cloud Bongos', settingsUrl };
|
|
52
61
|
}
|
|
53
62
|
}
|
|
54
63
|
|
|
@@ -179,7 +188,7 @@ async function resolveWidgetsEnabled() {
|
|
|
179
188
|
const timer = setTimeout(() => ctrl.abort(), 3000);
|
|
180
189
|
try {
|
|
181
190
|
const res = await fetch(`${base}/api/gds/me`, {
|
|
182
|
-
headers: { Authorization: `Bearer ${session.token}`, 'User-Agent': '
|
|
191
|
+
headers: { Authorization: `Bearer ${session.token}`, 'User-Agent': require('../../src/branding').userAgent() },
|
|
183
192
|
signal: ctrl.signal,
|
|
184
193
|
});
|
|
185
194
|
if (!res.ok) return true;
|
|
@@ -59,7 +59,7 @@ function refuseIfKeyPasted(argv) {
|
|
|
59
59
|
console.log('✖ That looks like an API key — this tool never accepts one as an argument,');
|
|
60
60
|
console.log(' and keys are never pasted into chat (the transcript is uploaded).');
|
|
61
61
|
console.log(' Add it in Settings instead — it syncs to your box automatically:');
|
|
62
|
-
console.log('
|
|
62
|
+
console.log(` ${require('./cli-lib').hallBase()}/settings#art-key`);
|
|
63
63
|
return true;
|
|
64
64
|
}
|
|
65
65
|
|
|
@@ -48,11 +48,34 @@
|
|
|
48
48
|
const fs = require('node:fs');
|
|
49
49
|
const path = require('node:path');
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
//
|
|
55
|
-
//
|
|
51
|
+
// The Builders' Hall deep-link resolver bases (task/idea/blocker), derived from the
|
|
52
|
+
// instance's STABLE public hall — branding.domains.buildersOrigin, falling back to
|
|
53
|
+
// publicOrigin. Deliberately NOT the env-overridable API_BASE: these bases get
|
|
54
|
+
// WRITTEN INTO COMMITTED markdown, so a per-dev CLOUDBONGOS_API_BASE=localhost
|
|
55
|
+
// override must never leak into a committed doc link (task 1002234; the committed-doc
|
|
56
|
+
// twin of the task-1002233 printed-link fix, which purged the last hardcoded
|
|
57
|
+
// `https://amazonprimea.com`). When branding is unreadable the base is the
|
|
58
|
+
// root-relative '/builders#/…' — never a hardcoded founder host. Reading branding is
|
|
59
|
+
// a sync file read (no network), safe at module scope for this token-free CI gate.
|
|
60
|
+
function resolverHallRoot() {
|
|
61
|
+
try {
|
|
62
|
+
const d = (require('../../src/branding').branding().domains) || {};
|
|
63
|
+
const origin = (typeof d.buildersOrigin === 'string' && d.buildersOrigin.trim())
|
|
64
|
+
|| (typeof d.publicOrigin === 'string' && d.publicOrigin.trim())
|
|
65
|
+
|| '';
|
|
66
|
+
return `${String(origin).replace(/\/+$/, '')}/builders#`;
|
|
67
|
+
} catch (_) {
|
|
68
|
+
return '/builders#';
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const RESOLVER_HALL_ROOT = resolverHallRoot();
|
|
72
|
+
const RESOLVER_BASE = `${RESOLVER_HALL_ROOT}/task/`;
|
|
73
|
+
const RESOLVER_BASE_IDEA = `${RESOLVER_HALL_ROOT}/idea/`;
|
|
74
|
+
const RESOLVER_BASE_BLOCKER = `${RESOLVER_HALL_ROOT}/blocker/`;
|
|
75
|
+
// API_BASE (env → session → branding default) comes from cli-lib (the single
|
|
76
|
+
// source) — used ONLY for the RUNTIME /public/ref-ids fetch below, never for the
|
|
77
|
+
// committed link bases above. Safe for this token-free CI gate: cli-lib does no
|
|
78
|
+
// eager session read or network at module scope.
|
|
56
79
|
const { API_BASE } = require('./cli-lib');
|
|
57
80
|
|
|
58
81
|
// Every hand-authored markdown file that a reader sees rendered on github.com:
|
|
@@ -101,11 +124,14 @@ const GITHUB_NS_RE = /\b(pull requests?|pull|prs?)[`'")\s(:]*$/i;
|
|
|
101
124
|
// "reports #2–#11" treat BOTH ends the same way.
|
|
102
125
|
const LIST_GLUE_RE = /^[\s,–—-]*(?:and|&|\+|or|to|through)?[\s,–—-]*$/i;
|
|
103
126
|
|
|
104
|
-
|
|
105
|
-
//
|
|
106
|
-
// [#N](task-resolver/N). Used only to undo PAST task-resolver mis-links of
|
|
127
|
+
// An existing markdown link of the TASK-resolver form this script writes:
|
|
128
|
+
// [#N](…/builders#/task/N). Used only to undo PAST task-resolver mis-links of
|
|
107
129
|
// entity/idea/blocker refs; the idea/blocker resolver links are left alone.
|
|
108
|
-
|
|
130
|
+
// HOST-AGNOSTIC (task 1002234 part b): matches any http(s) host OR a root-relative
|
|
131
|
+
// '/builders#/…', so the mislink-cleanup path still recognizes a link a PRIOR run
|
|
132
|
+
// committed under a DIFFERENT host — the legacy `amazonprimea.com` links, a
|
|
133
|
+
// co-tenant's, or this instance's own — not only the current RESOLVER_BASE host.
|
|
134
|
+
const RESOLVER_LINK_RE = /\[#(\d{1,5})\]\((?:https?:\/\/[^/)\s]+)?\/builders#\/task\/(\d{1,5})\)/g;
|
|
109
135
|
|
|
110
136
|
// Classify a ref by its left context (+ list-glue carry). Returns one of
|
|
111
137
|
// 'github' | 'idea' | 'blocker' | 'entity' | null (null = candidate task ref).
|
package/scripts/gds/login.js
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
const readline = require('node:readline');
|
|
24
24
|
const { spawnSync } = require('node:child_process');
|
|
25
25
|
const { saveSession } = require('./cli-lib');
|
|
26
|
+
const { branding } = require('../../src/branding');
|
|
26
27
|
|
|
27
28
|
// --- pure helpers (unit-tested) ---------------------------------------------
|
|
28
29
|
|
|
@@ -149,6 +150,20 @@ async function runDeviceFlow(base, { log, idp = null }) {
|
|
|
149
150
|
return { state: 'expired' };
|
|
150
151
|
}
|
|
151
152
|
|
|
153
|
+
// A helpful, instance-agnostic example origin for the sign-in prompt. login is
|
|
154
|
+
// deliberately instance-agnostic (point it at ANY instance), so the example is
|
|
155
|
+
// derived from THIS checkout's branding — a branded checkout shows its own
|
|
156
|
+
// instance; the neutral core shows a neutral placeholder. It never hardcodes
|
|
157
|
+
// another instance's real domain (hardcoding one steered a new builder to the
|
|
158
|
+
// wrong backend — task 1002400, onboarding-audit area 3).
|
|
159
|
+
function exampleInstanceOrigin() {
|
|
160
|
+
try {
|
|
161
|
+
const origin = branding().domains && branding().domains.publicOrigin;
|
|
162
|
+
if (origin && !/localhost|127\.0\.0\.1/.test(origin)) return origin;
|
|
163
|
+
} catch (_) { /* branding unavailable — fall through to the neutral placeholder */ }
|
|
164
|
+
return 'https://your-instance.example.com';
|
|
165
|
+
}
|
|
166
|
+
|
|
152
167
|
// --- main --------------------------------------------------------------------
|
|
153
168
|
|
|
154
169
|
async function main() {
|
|
@@ -158,7 +173,7 @@ async function main() {
|
|
|
158
173
|
|
|
159
174
|
let base;
|
|
160
175
|
try {
|
|
161
|
-
base = normalizeInstanceBase(urlArg || (await prompt(
|
|
176
|
+
base = normalizeInstanceBase(urlArg || (await prompt(`Instance URL (e.g. ${exampleInstanceOrigin()}): `)));
|
|
162
177
|
} catch {
|
|
163
178
|
console.error('✖ usage: bongos login <instance-url>');
|
|
164
179
|
process.exit(2);
|
|
@@ -28,7 +28,13 @@ const ic = require('../../src/instance-config');
|
|
|
28
28
|
// WRITE the session to the configured instance dir (OTB → ~/.config/otb,
|
|
29
29
|
// unchanged; a fresh instance → its neutral dir). R61 / task 1200.
|
|
30
30
|
const SESSION_PATH = ic.configPath('gds-session.json');
|
|
31
|
-
|
|
31
|
+
// env → the EXISTING session's api_base → this instance's branding default.
|
|
32
|
+
// On a RE-auth a session file already exists, and its api_base is the best signal
|
|
33
|
+
// of which instance the builder is on — this file used to hardcode the founder
|
|
34
|
+
// host here (a straggler the task 1002201 sweep missed), so a token minted by
|
|
35
|
+
// another instance was verified against amazonprimea.com and rejected 401 with a
|
|
36
|
+
// perfectly valid token (task 1002427).
|
|
37
|
+
const API_BASE = ic.resolveApiBase();
|
|
32
38
|
|
|
33
39
|
function usage(extra) {
|
|
34
40
|
if (extra) console.error(extra);
|