@bongos/core 1.19.726 → 1.19.727

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (226) hide show
  1. package/.bongos-core.json +176 -491
  2. package/.devcontainer/Dockerfile +1 -1
  3. package/.devcontainer/devcontainer.json +2 -2
  4. package/.devcontainer/healthcheck.sh +1 -1
  5. package/.devcontainer/init-firewall.sh +1 -1
  6. package/.devcontainer/post-create.sh +2 -2
  7. package/.env.local.example +1 -1
  8. package/Dockerfile +1 -1
  9. package/docs/copy-inventory.md +1 -1
  10. package/docs/copy-registry.json +9 -9
  11. package/docs/module-api-changelog.md +2 -0
  12. package/docs/recipes/devbox-app-release.md +4 -4
  13. package/modules/dev-box/app/scripts/dmgbuild-settings.py +5 -5
  14. package/modules/dev-box/app/scripts/gen-brand.js +1 -1
  15. package/modules/dev-box/app/src/brand.js +1 -1
  16. package/modules/dev-box/app/test/unit.mjs +16 -16
  17. package/modules/dev-box/box-access.js +1 -1
  18. package/modules/dev-box/routes/box.js +1 -1
  19. package/modules/discord/discord-approvals.js +1 -1
  20. package/modules/grading/grader-model.js +1 -1
  21. package/modules/grading/grader-prompt.js +1 -1
  22. package/modules/grading/grader-workers/quality.js +1 -1
  23. package/modules/hall-ui/module.json +1 -1
  24. package/modules/hall-ui/public/brand-apply.js +1 -1
  25. package/modules/hall-ui/public/shell.js +1 -1
  26. package/modules/hall-ui/public/work.js +1 -1
  27. package/modules/lifecycle/conflict-resolve.js +1 -1
  28. package/modules/lifecycle/db-analytics.js +1 -1
  29. package/modules/lifecycle/routes/analytics.js +1 -1
  30. package/modules/onboarding/approval-broadcast.js +1 -1
  31. package/modules/onboarding/onboarding.js +1 -1
  32. package/modules/provisioning/tests/liveness.mjs +1 -1
  33. package/modules/public-landing/public/index.html +1 -1
  34. package/modules/public-landing/public/projects-floor.states.json +2 -2
  35. package/modules/public-landing/public/projects.probes.json +4 -4
  36. package/modules/public-landing/public/projects.states.json +2 -2
  37. package/modules/status-ui/module.json +1 -1
  38. package/modules/status-ui/public/status.js +4 -4
  39. package/modules/status-ui/public/style.css +1 -1
  40. package/modules/ui-design/kit/fixtures/cost-summary.json +1 -1
  41. package/modules/ui-design/kit/fixtures/featured-hub.json +1 -1
  42. package/modules/ui-design/kit/fixtures/featured.json +1 -1
  43. package/modules/ui-design/kit/fixtures/leaderboard.json +1 -1
  44. package/modules/ui-design/kit/fixtures/my-projects.json +1 -1
  45. package/modules/ui-design/kit/fixtures/progress.json +1 -1
  46. package/modules/ui-design/kit/fixtures/recent-shipped.json +1 -1
  47. package/package-lock.json +2 -2
  48. package/package.json +1 -1
  49. package/scripts/cron/style_guide_audit.sh +1 -1
  50. package/scripts/discord/lib.js +1 -1
  51. package/scripts/discord/post.js +1 -1
  52. package/scripts/gds/audit-authorship.sh +1 -1
  53. package/scripts/gds/audit-replay.sh +29 -2
  54. package/scripts/gds/audit-ships.js +1 -1
  55. package/scripts/gds/backfill-sessions.js +2 -2
  56. package/scripts/gds/cf-tunnel.js +4 -4
  57. package/scripts/gds/claude-materialize.js +2 -2
  58. package/scripts/gds/cli-lib.js +6 -6
  59. package/scripts/gds/cutover-codemod.js +1 -1
  60. package/scripts/gds/dev-lib.js +2 -2
  61. package/scripts/gds/diagnose-achievements.js +2 -2
  62. package/scripts/gds/fitness-checks-identity.js +6 -4
  63. package/scripts/gds/gen-diagrams.js +1 -1
  64. package/scripts/gds/leak-scan-allowlist.js +293 -0
  65. package/scripts/gds/learning-capture.js +1 -1
  66. package/scripts/gds/linkify-refs.js +2 -2
  67. package/scripts/gds/local-preview-lib.js +1 -1
  68. package/scripts/gds/mirror-lineage-check.js +1 -1
  69. package/scripts/gds/mirror-redact.js +17 -2
  70. package/scripts/gds/newcomer-floor.templates.json +1 -1
  71. package/scripts/gds/package-core.js +18 -1
  72. package/scripts/gds/paste-token.js +1 -1
  73. package/scripts/gds/provision-units.js +2 -2
  74. package/scripts/gds/publish-manifest.js +15 -0
  75. package/scripts/gds/repo-metrics.js +1 -1
  76. package/scripts/gds/sandbox-stage.js +1 -1
  77. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +1 -1
  78. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +1 -1
  79. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +1 -1
  80. package/scripts/gds/seed-bongos-tasks.js +2 -2
  81. package/scripts/gds/seed-gds-v4-tasks.js +1 -1
  82. package/scripts/gds/seed-medusa-tasks.js +10 -10
  83. package/scripts/gds/seed-module-upstreaming.js +1 -1
  84. package/scripts/gds/seed-productization-tasks.js +6 -6
  85. package/scripts/gds/seed-provisioning-tasks.js +2 -2
  86. package/scripts/gds/seed-staging.sh +19 -6
  87. package/scripts/gds/ship-deploy-target.js +1 -1
  88. package/scripts/gds/ship-flow.js +1 -1
  89. package/scripts/gds/smoke-gds.js +1 -1
  90. package/scripts/status-probe.mjs +2 -2
  91. package/src/bongos/auth-discord.js +2 -2
  92. package/src/bongos/live-channel.js +1 -1
  93. package/src/bongos/pool.js +1 -1
  94. package/src/bongos/routes/auth.js +11 -11
  95. package/src/bongos/routes/security.js +1 -1
  96. package/src/bongos/routes.js +1 -1
  97. package/src/branding.js +1 -1
  98. package/src/devbox-downloads.js +1 -1
  99. package/src/instance-config.js +2 -2
  100. package/src/module-api.js +1 -1
  101. package/src/module-loader/provenance.js +2 -2
  102. package/tests/art_stage.mjs +2 -2
  103. package/tests/auth_anthropic_identity.mjs +1 -1
  104. package/tests/auth_duplicate_cookie.mjs +1 -1
  105. package/tests/auth_error_brand.mjs +1 -1
  106. package/tests/auth_inactive_builder.mjs +1 -1
  107. package/tests/backup_cli.mjs +4 -4
  108. package/tests/bongos_box_connect.mjs +2 -2
  109. package/tests/bongos_downloads.mjs +2 -2
  110. package/tests/bongos_login.mjs +5 -5
  111. package/tests/box_connect_e2e.mjs +2 -2
  112. package/tests/box_dns_repoint.mjs +10 -10
  113. package/tests/box_host_keys.mjs +1 -1
  114. package/tests/box_onboard.mjs +9 -9
  115. package/tests/box_scope_session.mjs +1 -1
  116. package/tests/box_terminal_ssrf.mjs +7 -7
  117. package/tests/boxes.mjs +9 -9
  118. package/tests/branding.mjs +2 -2
  119. package/tests/bump_version.mjs +2 -2
  120. package/tests/cf_tunnel.mjs +40 -40
  121. package/tests/cli_token_reissue.mjs +7 -7
  122. package/tests/cloud_bongos_pack.mjs +1 -1
  123. package/tests/currency_label.mjs +8 -8
  124. package/tests/dev_lib.mjs +4 -4
  125. package/tests/devbox_dmg_backdrop.mjs +1 -1
  126. package/tests/devbox_downloads.mjs +2 -2
  127. package/tests/devbox_icons.mjs +1 -1
  128. package/tests/discord_approvals.mjs +1 -1
  129. package/tests/discord_oauth.mjs +2 -2
  130. package/tests/executed_closure.mjs +6 -1
  131. package/tests/first_admin_bootstrap.mjs +1 -1
  132. package/tests/gate_approvals.mjs +5 -5
  133. package/tests/grade_aggregates_unavailable.mjs +1 -1
  134. package/tests/hook_user_agents.mjs +2 -2
  135. package/tests/init.mjs +6 -6
  136. package/tests/instance_config.mjs +1 -1
  137. package/tests/instance_manifest.mjs +5 -5
  138. package/tests/instance_mismatch_guard.mjs +13 -13
  139. package/tests/leak_scan_allowlist.mjs +94 -0
  140. package/tests/migrate_root_resolution.mjs +4 -4
  141. package/tests/mirror_redact.mjs +28 -4
  142. package/tests/module_catalog.mjs +5 -5
  143. package/tests/module_submissions.mjs +3 -3
  144. package/tests/package_core.mjs +1 -1
  145. package/tests/parallel-load.mjs +6 -6
  146. package/tests/projects_hub.mjs +2 -2
  147. package/tests/provision.mjs +50 -50
  148. package/tests/provisioning_github_app_routes.mjs +1 -1
  149. package/tests/provisioning_onboard_mode.mjs +2 -2
  150. package/tests/publish_reconciler.mjs +4 -4
  151. package/tests/sandbox_stage.mjs +1 -1
  152. package/tests/scrubber_corpus.mjs +3 -3
  153. package/tests/search_isolation.mjs +1 -1
  154. package/tests/session_records.mjs +1 -1
  155. package/tests/ship_card.mjs +6 -6
  156. package/tests/ship_ci_deploy.mjs +1 -1
  157. package/tests/single_host_hall.mjs +9 -9
  158. package/tests/smoke_preflight.mjs +1 -1
  159. package/tests/smoke_target.mjs +1 -1
  160. package/tests/status-probe.mjs +1 -1
  161. package/tests/status_mirror_sync.mjs +1 -1
  162. package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +0 -45
  163. package/docs/design/mocks/_schemes.css +0 -604
  164. package/docs/design/mocks/component-sheet.html +0 -428
  165. package/docs/design/mocks/hall/_tokens.css +0 -370
  166. package/docs/design/mocks/hall/board/v1.html +0 -846
  167. package/docs/design/mocks/hall/board/v2.html +0 -858
  168. package/docs/design/mocks/hall/board/v3.html +0 -884
  169. package/docs/design/mocks/hall/goals/v1.html +0 -1212
  170. package/docs/design/mocks/hall/goals/v2.html +0 -1192
  171. package/docs/design/mocks/hall/goals/v3.html +0 -1205
  172. package/docs/design/mocks/hall/hall-sheet.html +0 -244
  173. package/docs/design/mocks/hall/reading/v1.html +0 -1125
  174. package/docs/design/mocks/hall/reading/v2.html +0 -1177
  175. package/docs/design/mocks/hall/reading/v3.html +0 -1150
  176. package/docs/design/mocks/hall/settings/v1.html +0 -1238
  177. package/docs/design/mocks/hall/settings/v2.html +0 -1235
  178. package/docs/design/mocks/hall/settings/v3.html +0 -1299
  179. package/docs/design/mocks/hall/task/v1.html +0 -633
  180. package/docs/design/mocks/hall/task/v2.html +0 -646
  181. package/docs/design/mocks/hall/task/v3.html +0 -647
  182. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg +0 -0
  183. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg.json +0 -13
  184. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg +0 -0
  185. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg.json +0 -13
  186. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg +0 -0
  187. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg.json +0 -13
  188. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg +0 -0
  189. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg.json +0 -13
  190. package/docs/design/mocks/hub/hub-sheet.html +0 -192
  191. package/docs/design/mocks/hub/mine.html +0 -465
  192. package/docs/design/mocks/hub/picker.html +0 -421
  193. package/docs/design/mocks/hub/planets.html +0 -356
  194. package/docs/design/mocks/hub/v1.html +0 -1209
  195. package/docs/design/mocks/hub/v2.html +0 -1257
  196. package/docs/design/mocks/hub/v3.html +0 -1496
  197. package/docs/design/mocks/hub/wizard.html +0 -421
  198. package/docs/design/mocks/landing/landing-sheet.html +0 -131
  199. package/docs/design/mocks/landing/v1.html +0 -956
  200. package/docs/design/mocks/landing/v2.html +0 -708
  201. package/docs/design/mocks/landing/v3.html +0 -911
  202. package/docs/design/mocks/landing-page-mock.html +0 -687
  203. package/docs/design/mocks/landing-palettes.html +0 -103
  204. package/docs/design/mocks/projects-hub-mock.html +0 -991
  205. package/docs/design/mocks/projects-hub-variants.html +0 -146
  206. package/docs/design/mocks/projects-page-mock.html +0 -167
  207. package/docs/design/mocks/world/blue-hud/_tokens.css +0 -246
  208. package/docs/design/mocks/world/blue-hud/hall.html +0 -595
  209. package/docs/design/mocks/world/blue-hud/landing.html +0 -424
  210. package/docs/design/mocks/world/blue-hud/status.html +0 -410
  211. package/docs/design/mocks/world/chrome-blobs/_tokens.css +0 -479
  212. package/docs/design/mocks/world/chrome-blobs/hall.html +0 -553
  213. package/docs/design/mocks/world/chrome-blobs/landing-b.html +0 -581
  214. package/docs/design/mocks/world/chrome-blobs/landing.html +0 -328
  215. package/docs/design/mocks/world/chrome-blobs/status.html +0 -416
  216. package/docs/design/mocks/world/natgeo-editorial/_tokens.css +0 -377
  217. package/docs/design/mocks/world/natgeo-editorial/hall.html +0 -649
  218. package/docs/design/mocks/world/natgeo-editorial/landing-b.html +0 -743
  219. package/docs/design/mocks/world/natgeo-editorial/landing.html +0 -475
  220. package/docs/design/mocks/world/natgeo-editorial/status.html +0 -437
  221. package/docs/design/mocks/world/organic-cards/_tokens.css +0 -462
  222. package/docs/design/mocks/world/organic-cards/hall.html +0 -625
  223. package/docs/design/mocks/world/organic-cards/landing-b.html +0 -736
  224. package/docs/design/mocks/world/organic-cards/landing.html +0 -420
  225. package/docs/design/mocks/world/organic-cards/status.html +0 -458
  226. package/docs/design/mocks/world/world-sheet.html +0 -156
@@ -281,12 +281,27 @@ const INSTANCE_EXCLUDE = [
281
281
  'docs/design/container-exterior-tiles.md',
282
282
  'docs/design/container-interior.md',
283
283
  'docs/design/world-map-scroll.md',
284
+ // instance-specific UI MOCKUPS — iteration snapshots of THIS instance's own hub (hub v1/v2/v3,
285
+ // the wizard, the projects hub, the world chrome), branded end to end in markup a consumer of
286
+ // the portable core has no use for: they are our design history, not methodology. Same reason as
287
+ // the game-design carve-out above, and the same failure mode — redaction de-brands names in DOCS,
288
+ // but an .html is a FUNCTIONAL file that ships verbatim, so every brand string in the mock markup
289
+ // reached the published artifact. They were 117 of the 240 remaining leak-scan hits. Excluding the
290
+ // subtree rather than the six files is deliberate: it is the boundary that holds when someone adds
291
+ // mockup number seven. (task 1003869)
292
+ 'docs/design/mocks/',
284
293
  // instance-HISTORY ADRs (task 1002219 / audit H5). These record THIS platform-family's own
285
294
  // migration + identity history (the amazonprimea→cloudbongos lift, the standalone reprovision,
286
295
  // the cloudbongos identity hub) — they are inherently full of the prior instance's name/owner and
287
296
  // genericize to nothing (unlike a portable methodology ADR). docs/adr/ is allowlisted wholesale for
288
297
  // the portable decision records; these three stay in this repo and never ship in the core, mirroring
289
298
  // the instance-recipe / game-design carve-outs above. (The portable ADRs + the README index still publish.)
299
+ // The instance's OWN name + trademark decision. Its prose redacts cleanly, but the FILENAME
300
+ // carries the brand and the publish manifest lists every path — so the literal shipped in
301
+ // .bongos-core.json no matter how well the body was redacted. It also genericizes to nothing:
302
+ // "accepting trademark risk on <our name>" is not a decision another instance inherits.
303
+ // (task 1003869 — the last literal in the artifact.)
304
+ 'docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md',
290
305
  'docs/adr/0139-platform-history-migration-to-cloudbongos.md',
291
306
  'docs/adr/0140-cloudbongos-standalone-reprovision.md',
292
307
  'docs/adr/0141-cross-site-identity-federated-hub-idp.md',
@@ -6,7 +6,7 @@
6
6
  // out to git / wc / knip and emits a JSON snapshot of repo health, then upserts
7
7
  // it into repo_health_snapshots (idempotent on calendar date — rerun same day
8
8
  // = upsert, not a new row). The latest row feeds /api/gds/public/repo-health,
9
- // which renders a trend tile on status.amazonprimea.com.
9
+ // which renders a trend tile on status.example.com.
10
10
  //
11
11
  // What the snapshot contains:
12
12
  // - total_loc + loc_by_dir — tracked JS/MJS line counts, per watched dir
@@ -6,7 +6,7 @@
6
6
  //
7
7
  // Two preview contexts (resolvePreviewContext picks one):
8
8
  // - BOX (ADR 0031): box-game-preview.service serves the working tree at
9
- // https://sandbox-<login>.amazonprimea.com; "staging" restarts the service.
9
+ // https://sandbox-<login>.example.com; "staging" restarts the service.
10
10
  // - LOCAL (task 1056): a builder on a full local clone (laptop) runs the same
11
11
  // ADR 0052 game-only entry privately at http://localhost:<port> via
12
12
  // scripts/gds/local-preview.js; "staging" (re)starts that local process.
@@ -7,7 +7,7 @@
7
7
  // Run: node scripts/gds/seed-bongos-coreB-tranche1-tasks.js
8
8
  const os = require('os');
9
9
  const TOKEN = require(os.homedir() + '/.config/otb/gds-session.json').token;
10
- const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://amazonprimea.com';
10
+ const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://example.com';
11
11
  const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' };
12
12
 
13
13
  // ref → task spec. depends_on_refs are local R## refs resolved after create.
@@ -9,7 +9,7 @@
9
9
  // Run: node scripts/gds/seed-bongos-coreB-tranche2-tasks.js
10
10
  const os = require('os');
11
11
  const TOKEN = require(os.homedir() + '/.config/otb/gds-session.json').token;
12
- const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://amazonprimea.com';
12
+ const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://example.com';
13
13
  const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' };
14
14
 
15
15
  // ref → task spec. deps are local R## refs resolved after create. Clean-slicing
@@ -47,7 +47,7 @@ const TASKS = [
47
47
  {
48
48
  key: 'G02',
49
49
  title: 'config/hierarchy.json + hierarchy-config.js — the six-tier preset (onboarding-edited)',
50
- description: `Phase 1 of the goal hierarchy (ADR 0086 §1 — the ADR 0062 core/host pattern applied to the work model). Add \`config/hierarchy.json\` (joins branding.json/modules.json as host config) declaring the tiers — names, order, and which tier carries scope, membership, and criteria. Ship the six-tier Amazonprimea preset: Project → Version → Goal → Criteria → Task → Sub-task. Add \`src/bongos/hierarchy-config.js\` (mirrors src/modules.js) to load + validate it. v1 "editable" = owner-set labels, enable/disable, and which tier owns scope/criteria/membership; arbitrary custom tier graphs are explicitly DEFERRED. Owner fills/edits during onboarding (extend the scripts/gds/init.js interview).
50
+ description: `Phase 1 of the goal hierarchy (ADR 0086 §1 — the ADR 0062 core/host pattern applied to the work model). Add \`config/hierarchy.json\` (joins branding.json/modules.json as host config) declaring the tiers — names, order, and which tier carries scope, membership, and criteria. Ship the six-tier Example preset: Project → Version → Goal → Criteria → Task → Sub-task. Add \`src/bongos/hierarchy-config.js\` (mirrors src/modules.js) to load + validate it. v1 "editable" = owner-set labels, enable/disable, and which tier owns scope/criteria/membership; arbitrary custom tier graphs are explicitly DEFERRED. Owner fills/edits during onboarding (extend the scripts/gds/init.js interview).
51
51
 
52
52
  **Done when:** hierarchy.json + hierarchy-config.js exist; the loader validates + exposes the tier set; the six-tier preset is the OTB default; onboarding can set labels/enable/scope-owner; unit test covers a malformed preset rejected.`,
53
53
  kind: 'feature', discipline: 'engineer', priority: 5,
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // Seed the 6 net-new "Cloud Bongos CLI" tasks added to GDS-V4 (C8) — the
3
3
  // conda/Miniconda-style terminal-first onboarding toolkit. `bongos` is the CLI
4
- // command (Cloud Bongos = the standalone build platform; Amazonprimea =
4
+ // command (Cloud Bongos = the standalone build platform; Example =
5
5
  // instance 1). Design doc: artifact 02bcca71 (the bongos toolkit).
6
6
  //
7
7
  // Shape mirrors seed-medusa-tasks.js exactly:
@@ -98,7 +98,7 @@ A small public, read-only endpoint returning the instance descriptor assembled f
98
98
 
99
99
  \`bongos login <instance-url>\` fetches the P4A manifest, runs the GitHub device-flow (browser-click, no token paste — the UI-first rule), stores a per-instance scoped session, and brands the CLI for that instance. For someone NOT yet admitted, it files the public POST /api/gds/access-requests (their GitHub username) and polls — telling them "an Archon will approve you with a 👍 in Discord" — until admission flips, then completes sign-in. No GitHub collaborator invite is involved. Default admission is invite-only. Also folds the already-planned \`bongos init\` (scaffold a brand-new instance, R65) and \`bongos upgrade\` (R64) in as subcommands of the same CLI.
100
100
 
101
- **Done when:** \`bongos login <any-instance-url>\` works end-to-end including the not-yet-admitted path (files the request, polls, completes once approved); the CLI is instance-agnostic (no hard-coded amazonprimea); \`init\`/\`upgrade\` are reachable subcommands.`,
101
+ **Done when:** \`bongos login <any-instance-url>\` works end-to-end including the not-yet-admitted path (files the request, polls, completes once approved); the CLI is instance-agnostic (no hard-coded example); \`init\`/\`upgrade\` are reachable subcommands.`,
102
102
  kind: 'feature', discipline: 'engineer', priority: 3,
103
103
  est_minutes: 360, manual_degree: 2, credits_reward: 60,
104
104
  touches: ['bin/', 'scripts/gds/'], criteria: ['C8'], deps: ['P1', 'P4A'],
@@ -379,7 +379,7 @@ Reconcile shipped tasks against uploaded session records (BFG 6D follow-up to ta
379
379
  title: 'Embedding provider decision + key provisioning (Archon go-ahead)',
380
380
  description: `**Criterion:** one-call-recall (gated by V4.R24's go/no-go).
381
381
 
382
- If the eval gate says GO: pick the provider (research recommendation: Voyage voyage-4-lite — $0.02/M tokens, 200M free tier, Matryoshka dims; fallback OpenAI text-embedding-3-small), create the account, provision EMBEDDINGS_API_KEY into /etc/amazonprimea/secrets.env per ADR 0022. New external account = Lars's explicit go-ahead per the budget rules.
382
+ If the eval gate says GO: pick the provider (research recommendation: Voyage voyage-4-lite — $0.02/M tokens, 200M free tier, Matryoshka dims; fallback OpenAI text-embedding-3-small), create the account, provision EMBEDDINGS_API_KEY into /etc/example/secrets.env per ADR 0022. New external account = Lars's explicit go-ahead per the budget rules.
383
383
 
384
384
  **Done when:** decision recorded (ADR addendum), key live on the droplet, cost expectations logged.`,
385
385
  kind: 'decision', discipline: 'engineering', priority: 2,
@@ -2,9 +2,9 @@
2
2
  // Seed the 24 net-new "Medusa" tasks (R50–R73) added to GDS-V4 in the
3
3
  // 2026-06-17 Medusa Planning Session (meta task 1188 / claim 982).
4
4
  //
5
- // Medusa = decouple the GDS from the Amazonprimea game into a standalone,
5
+ // Medusa = decouple the GDS from the Example game into a standalone,
6
6
  // configurable, self-hostable, AGPL open-source, non-profit, AI-first build
7
- // platform. Amazonprimea becomes instance 1.
7
+ // platform. Example becomes instance 1.
8
8
  //
9
9
  // Companion migration 110_medusa_planning_seed.sql handles:
10
10
  // - the 2 done_when_criteria rows (C8 = medusa-standalone-instance,
@@ -66,7 +66,7 @@ A Medusa-only boot (sibling to src/preview-server.js) that builds the Express ap
66
66
  title: 'GDS-owned DB pool + migration carve-out + drop the track enum',
67
67
  description: `Part of Medusa (C8). Cross-ref: R50 design.
68
68
 
69
- A GDS-owned pool reading DATABASE_URL/PG* (not hard-defaulting to the amazonprimea DB name); a GDS-only migration sequence (game migrations 001/002 simply not applied on a fresh non-game instance); drop the product/internal 'track' distinction. Live prod keeps its existing DB. Zero cross-FKs exist between game and GDS tables, so the split is clean.
69
+ A GDS-owned pool reading DATABASE_URL/PG* (not hard-defaulting to the example DB name); a GDS-only migration sequence (game migrations 001/002 simply not applied on a fresh non-game instance); drop the product/internal 'track' distinction. Live prod keeps its existing DB. Zero cross-FKs exist between game and GDS tables, so the split is clean.
70
70
 
71
71
  **Done when:** a fresh-DB migration run produces only the build-system schema; a query asserts the game tables (world_events, players, seats) are absent; live prod unaffected.`,
72
72
  kind: 'infra', discipline: 'engineer', priority: 5,
@@ -80,7 +80,7 @@ A GDS-owned pool reading DATABASE_URL/PG* (not hard-defaulting to the amazonprim
80
80
 
81
81
  A per-instance config layer (config/branding.json + a documented schema + a neutral starter + a fill-it-in prompt an owner's own LLM uses) supplying product name, domain/cookie apex, sign-in (OAuth) origin, repo binding, currency label, copy, fonts, palette, icons/favicon/cursors. Core reads identity + branding from this layer; defaults preserve live OTB exactly. NOT a vanilla strip — branding becomes per-instance config; OTB's look becomes instance 1's pack (extracted in R57).
82
82
 
83
- **Done when:** core resolves all identity + branding from config; booting under a non-amazonprimea.com domain + a non-game name needs config only, no source edits. Gates most de-brand + self-host tasks.`,
83
+ **Done when:** core resolves all identity + branding from config; booting under a non-example.com domain + a non-game name needs config only, no source edits. Gates most de-brand + self-host tasks.`,
84
84
  kind: 'feature', discipline: 'engineer', priority: 5,
85
85
  est_minutes: 360, manual_degree: 2, credits_reward: 60,
86
86
  touches: ['config/', 'src/bongos/', 'public-builders/'], criteria: ['C8'], deps: ['R50'],
@@ -128,7 +128,7 @@ Make the reward currency a configurable label (neutral default; OTB's instance =
128
128
  title: "Extract OTB's look into instance 1's branding pack (not a vanilla strip)",
129
129
  description: `Part of Medusa (C8). Cross-ref: R53, R56.
130
130
 
131
- Move the ~272 archaic strings, the Greek fonts, the parchment palette, favicon/cursors/SVG sigils, and the page copy out of the hall + status code and into instance 1's branding pack; core renders from the R53 branding layer with a neutral starter as the fallback. status.amazonprimea.com + builders.amazonprimea.com look IDENTICAL afterward — their look just comes from config now. Add a rank display-label map so the Greek rank LABELS are presentation (the enum stays Greek by decision).
131
+ Move the ~272 archaic strings, the Greek fonts, the parchment palette, favicon/cursors/SVG sigils, and the page copy out of the hall + status code and into instance 1's branding pack; core renders from the R53 branding layer with a neutral starter as the fallback. status.example.com + builders.example.com look IDENTICAL afterward — their look just comes from config now. Add a rank display-label map so the Greek rank LABELS are presentation (the enum stays Greek by decision).
132
132
 
133
133
  **Done when:** no project branding is hard-coded in public-builders/ or public-status/; OTB's surfaces render unchanged from instance 1's pack; a fresh instance renders the neutral starter.`,
134
134
  kind: 'refactor', discipline: 'engineer', priority: 4,
@@ -142,7 +142,7 @@ Move the ~272 archaic strings, the Greek fonts, the parchment palette, favicon/c
142
142
 
143
143
  scripts/gds/gen-diagrams.js auto-generates the onboarding diagrams + assertions.json on every deploy. Make its template strings + assertions read the instance branding config so deploy-time regeneration emits neutral (instance-correct) branding. Rank names stay Greek by decision. This prevents the "we de-branded but Greek text reappeared after the next deploy" regression.
144
144
 
145
- **Done when:** running gen-diagrams.js under a neutral instance config produces diagrams + assertions.json with no hard-coded OTB/Amazonprimea tokens; OTB's instance still renders its own branding.`,
145
+ **Done when:** running gen-diagrams.js under a neutral instance config produces diagrams + assertions.json with no hard-coded OTB/Example tokens; OTB's instance still renders its own branding.`,
146
146
  kind: 'refactor', discipline: 'engineer', priority: 4,
147
147
  est_minutes: 180, manual_degree: 2, credits_reward: 30,
148
148
  touches: ['scripts/gds/gen-diagrams.js'], criteria: ['C8'], deps: ['R53'],
@@ -190,7 +190,7 @@ The CLI config root (~/.config/otb/: gds-session.json, env, discord-webhooks.jso
190
190
  title: 'Config-driven owner bootstrap + per-instance repo/OAuth binding',
191
191
  description: `Part of Medusa (C8). Cross-ref: R52, R53.
192
192
 
193
- Replace migration 023's hard-coded founding-Archon literal (UPDATE builders SET rank='archon' WHERE github_login='lars589') with an install-time first-admin bootstrap from instance config. Make the GitHub repo binding (repo-info.js — the OTB_GITHUB_OWNER/REPO seam already exists) and the OAuth/App config per-instance. Single-project model keeps the global economy fine — only the owner literal + repo/OAuth need to generalize.
193
+ Replace migration 023's hard-coded founding-Archon literal (UPDATE builders SET rank='archon' WHERE github_login='example-owner') with an install-time first-admin bootstrap from instance config. Make the GitHub repo binding (repo-info.js — the OTB_GITHUB_OWNER/REPO seam already exists) and the OAuth/App config per-instance. Single-project model keeps the global economy fine — only the owner literal + repo/OAuth need to generalize.
194
194
 
195
195
  **Done when:** grep over migrations/ returns zero login literals; a fresh install seats the configured first admin; repo + OAuth resolve from instance config.`,
196
196
  kind: 'feature', discipline: 'engineer', priority: 4,
@@ -202,7 +202,7 @@ Replace migration 023's hard-coded founding-Archon literal (UPDATE builders SET
202
202
  title: 'Containerized self-host instance (Dockerfile + docker-compose)',
203
203
  description: `Part of Medusa (C8). Cross-ref: R51, R52.
204
204
 
205
- A Dockerfile + docker-compose (app + Postgres) that brings a Medusa instance up from clean state with ZERO hard-coded droplet IP (104.236.254.243), amazonprimea systemd unit, or hand-maintained ~/deploy.sh. This is the self-host artifact; it does not touch prod's existing laptop/CI deploy path.
205
+ A Dockerfile + docker-compose (app + Postgres) that brings a Medusa instance up from clean state with ZERO hard-coded droplet IP, instance-specific systemd unit, or hand-maintained ~/deploy.sh. This is the self-host artifact; it does not touch prod's existing laptop/CI deploy path.
206
206
 
207
207
  **Done when:** \`docker compose up\` on a machine that has never seen our droplet brings up Medusa + Postgres and the hall is reachable; no prod topology referenced anywhere in the path.`,
208
208
  kind: 'infra', discipline: 'engineer', priority: 4,
@@ -248,7 +248,7 @@ Separate the portable methodology core Medusa ships (the working rules, the sess
248
248
  {
249
249
  ref: 'R67',
250
250
  title: 'PROOF — Medusa dogfood: a second, differently-branded non-game instance ships a task',
251
- description: `Part of Medusa (C8) — the proof-task that satisfies C8 ("the GDS builds itself"). Customer 0 = Medusa itself, running on the vanilla brand pack (R74); customer 1 = Amazonprimea.
251
+ description: `Part of Medusa (C8) — the proof-task that satisfies C8 ("the GDS builds itself"). Customer 0 = Medusa itself, running on the vanilla brand pack (R74); customer 1 = Example.
252
252
 
253
253
  Stand Medusa up as customer 0 (its own database, vanilla brand, no game code) and take one real task through the full lifecycle on it: claim -> grade -> merge -> ship with credits awarded. Medusa building Medusa, on Medusa. (A separate non-game third project is an acceptable alternative proof, but customer-0 self-build is the truest.)
254
254
 
@@ -342,7 +342,7 @@ Verify the private and public lineages stay consistent: migration numbering (the
342
342
  title: 'Medusa vanilla brand pack — the plain "customer 0" identity (Substack-like)',
343
343
  description: `Part of Medusa (C8). Cross-ref: R53 (branding-contract layer), R57 (customer 1 / OTB pack).
344
344
 
345
- Design + build the canonical Medusa VANILLA brand pack — the identity Medusa itself runs on as **customer 0** (Amazonprimea is customer 1). Deliberately PLAIN, clean, modern, professional — restrained palette, clean sans-serif type, minimal wordmark, plain-English product copy, simple favicon/icons. Aesthetic touchstone: Substack-plain; take INSPIRATION from planetscale.com's simplicity (do NOT copy). Delivered as a branding pack against the R53 contract; it is the default the hall + status render under when no other pack is supplied, and the brand Medusa ships on. Distinct from R57 (extracting customer 1 / OTB's Greek look) — this is customer 0's identity. No game/Greek flavor.
345
+ Design + build the canonical Medusa VANILLA brand pack — the identity Medusa itself runs on as **customer 0** (Example is customer 1). Deliberately PLAIN, clean, modern, professional — restrained palette, clean sans-serif type, minimal wordmark, plain-English product copy, simple favicon/icons. Aesthetic touchstone: Substack-plain; take INSPIRATION from planetscale.com's simplicity (do NOT copy). Delivered as a branding pack against the R53 contract; it is the default the hall + status render under when no other pack is supplied, and the brand Medusa ships on. Distinct from R57 (extracting customer 1 / OTB's Greek look) — this is customer 0's identity. No game/Greek flavor.
346
346
 
347
347
  **Done when:** a complete Medusa vanilla brand pack (name/wordmark, restrained palette, clean type, plain copy, favicon/icons) renders the hall + status as a plain, professional dev toolkit; it is the pack customer 0 (Medusa) runs on; verified on the standalone boot.`,
348
348
  kind: 'feature', discipline: 'artist', priority: 4,
@@ -19,7 +19,7 @@ const DRY = process.argv.includes('--dry-run');
19
19
  const VERSION = 'BONGOS-V1';
20
20
  const GOAL_TITLE = 'Module upstreaming & catalog — instances contribute modules into core';
21
21
  const GOAL_DESC =
22
- 'ADR 0107. The reverse of the ADR 0100/0103 distribution arrow: instances (Amazonprimea, ' +
22
+ 'ADR 0107. The reverse of the ADR 0100/0103 distribution arrow: instances (Example, ' +
23
23
  'Mercury) build feature modules and submit them for approval to be merged INTO the shared ' +
24
24
  'Cloud Bongos core catalog, credited to author + origin project. Accepted modules land in ' +
25
25
  'core modules/<key>/ default-off, added to the isPublishable() allowlist; every instance may ' +
@@ -52,7 +52,7 @@ const TASKS = [
52
52
  title: 'ADR: instance docs-discovery contract (how an agent finds its hall/docs)',
53
53
  description: `From the 2026-07-04 review (bullet 6). Today the only pointer to an instance's doc surface is \`domains.buildersOrigin\` in branding.json. A fresh self-hosted instance needs a DEFINED contract for how an agent reliably locates its builders' hall + rendered docs from config alone (standard docs location? discovery endpoint? manifest field?). Write an ADR that pins the contract, then CLAUDE.md's preamble references it instead of hand-waving.
54
54
 
55
- **Done when:** an ADR records the docs-discovery contract; branding/config carries the needed field(s); CLAUDE.md §0 points at the contract; a second instance can resolve its docs surface with no hard-coded amazonprimea.`,
55
+ **Done when:** an ADR records the docs-discovery contract; branding/config carries the needed field(s); CLAUDE.md §0 points at the contract; a second instance can resolve its docs surface with no hard-coded example.`,
56
56
  kind: 'decision', discipline: 'engineer', priority: 3,
57
57
  est_minutes: 90, manual_degree: 3, credits_reward: 20,
58
58
  touches: ['docs/adr/', 'config/', 'CLAUDE.md'], criteria: ['C16'], deps: [],
@@ -80,12 +80,12 @@ const TASKS = [
80
80
  {
81
81
  key: 'NAV-HYGIENE',
82
82
  title: 'Nav hygiene — reference the module, split instance-specifics',
83
- description: `From the 2026-07-04 review (bullets 42, 57, 64, 66, 68, 94). Several nav rows (and §2 prose) INLINE content that belongs to a module or to instance-specifics. Convert them to module references, and split anything naming the amazonprimea servers/assets into project-specific detail. By module:
84
- - **discord** (57, 64, 94): inbound #ideas, build-broadcast, channel layout → reference the discord module; the general mechanism lives there, anything naming the amazonprimea Discord server specifically → project-specific detail.
83
+ description: `From the 2026-07-04 review (bullets 42, 57, 64, 66, 68, 94). Several nav rows (and §2 prose) INLINE content that belongs to a module or to instance-specifics. Convert them to module references, and split anything naming the example servers/assets into project-specific detail. By module:
84
+ - **discord** (57, 64, 94): inbound #ideas, build-broadcast, channel layout → reference the discord module; the general mechanism lives there, anything naming the example Discord server specifically → project-specific detail.
85
85
  - **art-pipeline** (66): the pixel-art design-system row → reference the art module; the pixel/greek style choice itself is instance detail.
86
86
  - **game** (68): world-cell model + paths-as-overlays rows → the game module / instance context (out of the portable core).
87
87
 
88
- **Done when:** those nav/§2 items are thin references to their modules; no module-owned or amazonprimea-server-specific detail is inlined in the core; the game-specific rows are out of core.`,
88
+ **Done when:** those nav/§2 items are thin references to their modules; no module-owned or example-server-specific detail is inlined in the core; the game-specific rows are out of core.`,
89
89
  kind: 'cleanup', discipline: 'engineer', priority: 3,
90
90
  est_minutes: 120, manual_degree: 3, credits_reward: 25,
91
91
  touches: ['CLAUDE.md'], criteria: ['C32'], deps: [],
@@ -123,7 +123,7 @@ const TASKS = [
123
123
  {
124
124
  key: 'IDENTITY-ORG',
125
125
  title: 'Rationalize the identity apparatus + structure project-context.md',
126
- description: `From the 2026-07-04 review (bullets 109-111, 134/140, 187). Almost every identity section (§§1,3,5,6,7,9) is now a thin pointer to project-context.md, the §3 stub verbosely re-explains the core↔host split that §1 + the charter already cover, and the §6/§7 stubs still NAME the instance ("the Amazonprimea world", "the \`otb-*\` art skills"). Meanwhile project-context.md is getting overloaded (bullet 187). Fix: collapse §§3/5/6/7 to a single minimal pointer (or one-liners), genericize instance names out of any surviving stub, and give project-context.md a real section structure.
126
+ description: `From the 2026-07-04 review (bullets 109-111, 134/140, 187). Almost every identity section (§§1,3,5,6,7,9) is now a thin pointer to project-context.md, the §3 stub verbosely re-explains the core↔host split that §1 + the charter already cover, and the §6/§7 stubs still NAME the instance ("the Example world", "the \`otb-*\` art skills"). Meanwhile project-context.md is getting overloaded (bullet 187). Fix: collapse §§3/5/6/7 to a single minimal pointer (or one-liners), genericize instance names out of any surviving stub, and give project-context.md a real section structure.
127
127
 
128
128
  **Done when:** the stub scaffolding is minimal + instance-name-free in the core; project-context.md has a clear, non-overloaded structure; anchors/cross-refs still resolve.`,
129
129
  kind: 'cleanup', discipline: 'engineer', priority: 3,
@@ -148,7 +148,7 @@ const TASKS = [
148
148
  title: 'Scheduled-routines portability to self-host + multi-builder',
149
149
  description: `From the 2026-07-04 review (bullet 241). The ~17 autonomous cron routines under \`.claude/scheduled-tasks/\` (overnight-code-review, idea-triage-nightly, overnight-builder, bfg, security-review-weekly, …) are written for this instance. Define how they port to a self-hosted, multi-builder world: which run instance-wide vs per-builder, how a fresh instance inherits/configures them, and what a builder gets by default. Spike → a contract (and likely a config surface).
150
150
 
151
- **Done when:** there's a documented model for which routines are instance-wide vs per-builder, how a fresh instance inherits them, and how a builder configures their own; no routine hard-assumes the amazonprimea instance.`,
151
+ **Done when:** there's a documented model for which routines are instance-wide vs per-builder, how a fresh instance inherits them, and how a builder configures their own; no routine hard-assumes the example instance.`,
152
152
  kind: 'spike', discipline: 'engineer', priority: 2,
153
153
  est_minutes: 120, manual_degree: 3, credits_reward: 25,
154
154
  touches: ['.claude/scheduled-tasks/', 'docs/'], criteria: ['C16'], deps: [],
@@ -7,7 +7,7 @@
7
7
  // Run: node scripts/gds/seed-provisioning-tasks.js
8
8
  const os = require('os');
9
9
  const TOKEN = require(os.homedir() + '/.config/otb/gds-session.json').token;
10
- const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://amazonprimea.com';
10
+ const BASE = require('../../src/instance-config').resolveEnv('BASE') || 'https://example.com';
11
11
  const H = { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' };
12
12
  const GOAL = 26; // Cloud Bongos productization and self-host
13
13
 
@@ -27,7 +27,7 @@ const TASKS = [
27
27
  deps: ['P1', 'P2'], extDeps: [] },
28
28
  { ref: 'P4', kind: 'infra', discipline: 'engineer', priority: 2, est: 300,
29
29
  title: 'BV1 — Automated DNS record + Caddy on-demand ACME TLS for a provisioned host',
30
- description: 'ADR 0111 §4. Cloudflare A-record UPSERT via the shared client (P2), plus Caddy on-demand ACME (Let\'s Encrypt) so a NEWLY provisioned host is TLS-ready with no manual Cloudflare Origin-Cert console step (the least-automated leg today). On-demand TLS MUST be allow-listed to hostnames the module actually provisioned (no cert-minting for arbitrary names). Existing amazonprimea/cloudbongos apexes keep their Origin Certs unchanged. deps: P2, P3. (buildable now)',
30
+ description: 'ADR 0111 §4. Cloudflare A-record UPSERT via the shared client (P2), plus Caddy on-demand ACME (Let\'s Encrypt) so a NEWLY provisioned host is TLS-ready with no manual Cloudflare Origin-Cert console step (the least-automated leg today). On-demand TLS MUST be allow-listed to hostnames the module actually provisioned (no cert-minting for arbitrary names). Existing example/cloudbongos apexes keep their Origin Certs unchanged. deps: P2, P3. (buildable now)',
31
31
  deps: ['P2', 'P3'], extDeps: [] },
32
32
  { ref: 'P5', kind: 'feature', discipline: 'engineer', priority: 2, est: 240,
33
33
  title: 'BV1 — Wire provisioning into `bongos init` (idea #345 — "configured via the API")',
@@ -16,19 +16,32 @@
16
16
  # column that referenced a session, then deletes all sessions so NO real
17
17
  # bearer token persists on staging.
18
18
  #
19
- # SAFETY: hard-refuses to target anything but `amazonprimea_staging`, so a
19
+ # SAFETY: hard-refuses to target any database not named `*_staging`, so a
20
20
  # fat-fingered env can never point the wipe at production. Everything runs at
21
- # table-owner privilege (no superuser) since `lars` owns the staging objects.
21
+ # table-owner privilege (no superuser) the invoking role owns the staging objects.
22
22
  #
23
23
  # "What's real, what's faked on staging": see docs/recipes/staging-data.md.
24
24
 
25
25
  set -euo pipefail
26
26
 
27
- PROD_DB="${PROD_DB:-amazonprimea}"
28
- STAGING_DB="${STAGING_DB:-amazonprimea_staging}"
27
+ # No baked-in database names. A portable core cannot know an instance's DB, and the
28
+ # founder's two were hardcoded here until task 1003869 — including inside the safety
29
+ # check, which meant de-branding the names alone would have quietly disarmed it. So the
30
+ # guard is STRUCTURAL now instead of a name comparison: the target must be named
31
+ # <something>_staging. That keeps the original property ("a fat-fingered env can never
32
+ # point the wipe at production", since no production DB is called *_staging) and extends
33
+ # it to every instance rather than one. Both names must be set explicitly — this script
34
+ # WIPES its target, so there is no default worth guessing.
35
+ PROD_DB="${PROD_DB:-}"
36
+ STAGING_DB="${STAGING_DB:-}"
29
37
 
30
- if [ "$STAGING_DB" != "amazonprimea_staging" ]; then
31
- echo "REFUSING: STAGING_DB must be 'amazonprimea_staging' (got '$STAGING_DB'). This script wipes its target." >&2
38
+ if [ -z "$STAGING_DB" ] || [ -z "$PROD_DB" ]; then
39
+ echo "REFUSING: set PROD_DB (the dump source) and STAGING_DB (the wipe target) explicitly." >&2
40
+ echo " e.g. PROD_DB=myapp STAGING_DB=myapp_staging $0" >&2
41
+ exit 2
42
+ fi
43
+ if ! printf '%s' "$STAGING_DB" | grep -qE '^[A-Za-z0-9_]+_staging$'; then
44
+ echo "REFUSING: STAGING_DB '$STAGING_DB' must be a bare identifier ending in '_staging'. This script wipes its target." >&2
32
45
  exit 2
33
46
  fi
34
47
  if [ "$PROD_DB" = "$STAGING_DB" ]; then
@@ -171,7 +171,7 @@ function readSessionApiBase() {
171
171
  // PR-body deploy note, and the manual-confirm curl guidance. Precedence mirrors the
172
172
  // CLI's own base resolution: <PREFIX>_API_BASE env → the signed-in session's
173
173
  // api_base → branding publicOrigin → null (unknowable). There is NO hardcoded
174
- // founder host — 5 sites here baked in `https://amazonprimea.com`, so a ci-land /
174
+ // founder host — 5 sites here baked in `https://example.com`, so a ci-land /
175
175
  // manual-confirm on a migrated instance pointed the builder at the WRONG box; the
176
176
  // ci-land/guidance sibling of resolveDeployTarget()'s laptop-mode fix (task 1002232
177
177
  // ⊃ task 1002202). Pure over its injected inputs (env / sessionApiBase / branding)
@@ -306,7 +306,7 @@ async function shipMain() {
306
306
 
307
307
  // ---- Sandbox-first review gate (#927, ADR 0046) ----
308
308
  // On a dev box, a diff that touches game surfaces must be STAGED on the
309
- // builder's own live preview (sandbox-<login>.amazonprimea.com, ADR 0044)
309
+ // builder's own live preview (sandbox-<login>.example.com, ADR 0044)
310
310
  // and reviewed in a browser before the claim resolves — see it running,
311
311
  // get the chance to iterate, THEN decide to ship to the main game. Laptop
312
312
  // sessions, non-game diffs, quick-tunnel boxes, and --skip-stage all pass
@@ -54,7 +54,7 @@ function matchedApiBaseVar(env) {
54
54
  // null.
55
55
  //
56
56
  // There is deliberately NO hardcoded host. This file baked in
57
- // `https://amazonprimea.com` as its fallback, so a builder signed into any OTHER
57
+ // `https://example.com` as its fallback, so a builder signed into any OTHER
58
58
  // instance who shipped without an env override ran the ship's verification smoke
59
59
  // against the founder's box — which PASSED, because that box is healthy. The ship
60
60
  // then reported "smoke=clean" on the strength of testing a system it never
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // External uptime prober for amazonprimea.com (incident 2026-06-03, task #565).
2
+ // External uptime prober for example.com (incident 2026-06-03, task #565).
3
3
  //
4
4
  // WHY THIS EXISTS, AND WHY IT IS NOT src/bongos/uptime-poller.js:
5
5
  // The in-process poller (src/bongos/uptime-poller.js) runs INSIDE the Node
@@ -27,7 +27,7 @@
27
27
  // the step output). Non-zero only on its own internal error.
28
28
  //
29
29
  // USAGE:
30
- // node scripts/status-probe.mjs [--dir .] [--target https://amazonprimea.com/healthz]
30
+ // node scripts/status-probe.mjs [--dir .] [--target https://example.com/healthz]
31
31
  // [--attempts 3] [--timeout-ms 15000] [--gap-ms 10000]
32
32
 
33
33
  import { readFile, writeFile, mkdir } from 'node:fs/promises';
@@ -167,9 +167,9 @@ async function addDiscordGuildMember({ guildId, discordUserId, accessToken, role
167
167
 
168
168
  // Collect EVERY candidate auth token on the request, in priority order, with
169
169
  // duplicates removed. A browser can legitimately carry MORE THAN ONE
170
- // gds_session cookie: a host-only one (set on amazonprimea.com before the
170
+ // gds_session cookie: a host-only one (set on example.com before the
171
171
  // #726/#734 apex-scoping rollout) AND the current apex-scoped one
172
- // (.amazonprimea.com). The browser sends both in the Cookie header. We must try
172
+ // (.example.com). The browser sends both in the Cookie header. We must try
173
173
  // them ALL — picking only the first (as the old single-value extractToken did)
174
174
  // meant a stale/expired duplicate could shadow the live session and 401 the
175
175
  // builder (hit on the Discord link callback for builder 25). Order: Bearer
@@ -35,7 +35,7 @@ let reconnectDelayMs = 2000; // backoff before re-LISTEN; test-tunable via _set
35
35
  // exact same socket + database (PGHOST/PGDATABASE env overrides honored for
36
36
  // non-droplet environments). The DB-name default resolves through pool.js's
37
37
  // instanceDbName() — the SINGLE source for the instance's configured db.database
38
- // (from the branding pack) — instead of a second hardcoded "amazonprimea" literal
38
+ // (from the branding pack) — instead of a second hardcoded "example" literal
39
39
  // (ADR 0062 §5). A non-OTB instance LISTENs on its OWN DB, and there is one place
40
40
  // to change the default.
41
41
  function pgConfig() {
@@ -10,7 +10,7 @@
10
10
  // DB resolution (highest wins), NOT hard-defaulting to a host's DB name:
11
11
  // DATABASE_URL -> PGHOST/PGDATABASE env -> the instance's configured db.database
12
12
  // (config/branding.json, else config/branding.neutral.json)
13
- // OTB's branding pack carries db.database='amazonprimea', so prod (no DB env set) resolves to the
13
+ // OTB's branding pack carries db.database='example', so prod (no DB env set) resolves to the
14
14
  // exact same socket+database it used before this carve-out — live prod is unaffected. A fresh
15
15
  // instance points this at its own DB via env or its own branding pack; the neutral starter has
16
16
  // db.database=null so a misconfigured instance fails loudly rather than silently targeting OTB.
@@ -267,12 +267,12 @@ const REPOS_COOKIE = 'gds_oauth_repos';
267
267
  const HANDSHAKE_COOKIE_MS = 30 * 60 * 1000;
268
268
 
269
269
  // The apex domain the instance is served under, read from the instance branding
270
- // pack's cookieDomain (".amazonprimea.com" → "amazonprimea.com",
270
+ // pack's cookieDomain (".example.com" → "example.com",
271
271
  // ".cloudbongos.com" → "cloudbongos.com"). The session + OAuth-state cookies are
272
272
  // scoped to ".<apex>" so a single sign-in is shared across every subdomain
273
273
  // (apex, builders., status.) — the enabler for the dedicated builders subdomain
274
274
  // (#726). MUST come from config, not a hardcoded literal: a hardcoded
275
- // "amazonprimea.com" made every OTHER instance (e.g. cloudbongos.com) set a
275
+ // "example.com" made every OTHER instance (e.g. cloudbongos.com) set a
276
276
  // cookie for the wrong domain, which the browser drops → the OAuth state cookie
277
277
  // never persisted → "state mismatch / the gate is closed" (ADR 0062 §3/§5: domains
278
278
  // woven into auth, config swaps must not widen cookie scope). Each instance scopes
@@ -296,7 +296,7 @@ function reqHost(req) {
296
296
  }
297
297
 
298
298
  // The production-facing hosts that share one sign-in. Deliberately enumerated
299
- // (not "any *.amazonprimea.com") so staging.amazonprimea.com — a SEPARATE
299
+ // (not "any *.example.com") so staging.example.com — a SEPARATE
300
300
  // process + DB on :3001 — keeps a host-only cookie and never bleeds an
301
301
  // apex-scoped token into prod (or vice versa).
302
302
  // When COOKIE_APEX is "" (localhost / no configured cookieDomain) the set is
@@ -309,7 +309,7 @@ const APEX_COOKIE_HOSTS = new Set(
309
309
 
310
310
  // Cookie attributes that vary by host. On the production-facing hosts the
311
311
  // session cookie is scoped to the apex so it crosses subdomains (the enabler
312
- // for builders.amazonprimea.com, #726); everywhere else (localhost, staging)
312
+ // for builders.example.com, #726); everywhere else (localhost, staging)
313
313
  // it stays host-only. Returns a spread-able object.
314
314
  function sessionCookieDomainOpts(req) {
315
315
  if (APEX_COOKIE_HOSTS.has(reqHost(req))) {
@@ -320,7 +320,7 @@ function sessionCookieDomainOpts(req) {
320
320
 
321
321
  // Validate a caller-supplied post-sign-in return target. Accept ONLY:
322
322
  // - a relative path beginning with a single '/' (not '//', no backslash), or
323
- // - an absolute https URL whose host is the apex or a *.amazonprimea.com sub.
323
+ // - an absolute https URL whose host is the apex or a *.example.com sub.
324
324
  // Anything else (other origins, javascript:, protocol-relative) → null, so the
325
325
  // caller falls back to the safe default. This is an open-redirect guard.
326
326
  function safeReturnTo(raw) {
@@ -355,7 +355,7 @@ function recoveryStartHref(req) {
355
355
 
356
356
  // The canonical sign-in origin, read from the instance branding pack (oauthOrigin,
357
357
  // else publicOrigin) so a non-OTB Cloud Bongos instance pins its OAuth redirects to
358
- // ITS OWN apex instead of a hardcoded "amazonprimea.com" (ADR 0062 §3/§5; the
358
+ // ITS OWN apex instead of a hardcoded "example.com" (ADR 0062 §3/§5; the
359
359
  // branding contract). The fixed GDS_PUBLIC_ORIGIN env knob still wins for
360
360
  // dev/staging (auth.js's documented FIXED env name, not a <PREFIX>_ one). Resolved
361
361
  // once at module load; falls back to '' if branding fails, which leaves the env knob
@@ -535,7 +535,7 @@ module.exports = function buildAuthRouter() {
535
535
  const state = crypto.randomBytes(16).toString('hex');
536
536
  // redirect_uri is PINNED to the canonical origin (#734) — never derived from
537
537
  // the request host. GitHub only knows the apex callback, so a sign-in begun
538
- // on builders.amazonprimea.com must still hand GitHub the apex redirect_uri
538
+ // on builders.example.com must still hand GitHub the apex redirect_uri
539
539
  // or GitHub rejects it. Same posture the Discord flow already uses.
540
540
  const redirectUri = `${WEB_REDIRECT_ORIGIN}/api/gds/auth/web/callback`;
541
541
  res.cookie(STATE_COOKIE, state, {
@@ -551,7 +551,7 @@ module.exports = function buildAuthRouter() {
551
551
  // the page gates); otherwise fall back to the Referer (the page that kicked
552
552
  // off sign-in), so the dozens of client 401 redirects land a builder back
553
553
  // where they were with no per-call-site change. Both go through the
554
- // open-redirect allowlist (relative path or *.amazonprimea.com https).
554
+ // open-redirect allowlist (relative path or *.example.com https).
555
555
  const returnTo = safeReturnTo(req.query.return) || safeReturnTo(req.headers.referer);
556
556
  if (returnTo) {
557
557
  res.cookie(RETURN_COOKIE, returnTo, {
@@ -676,7 +676,7 @@ module.exports = function buildAuthRouter() {
676
676
  path: '/',
677
677
  expires: expiresAt,
678
678
  // Apex-scoped on the production hosts so one sign-in spans
679
- // amazonprimea.com + builders. + status. (#726); host-only elsewhere.
679
+ // example.com + builders. + status. (#726); host-only elsewhere.
680
680
  ...sessionCookieDomainOpts(req),
681
681
  });
682
682
  // A browser arriving with an older session name must not keep it: two
@@ -805,7 +805,7 @@ module.exports = function buildAuthRouter() {
805
805
  secure: req.secure || req.headers['x-forwarded-proto'] === 'https',
806
806
  maxAge: 10 * 60 * 1000,
807
807
  // Apex-scoped (#734 parity) so the state survives the host switch: the
808
- // link may start on builders.amazonprimea.com but DISCORD_REDIRECT_URI
808
+ // link may start on builders.example.com but DISCORD_REDIRECT_URI
809
809
  // always lands the callback on the apex. A host-only cookie would be
810
810
  // dropped on the hop and the state check would fail ("Link handshake
811
811
  // expired"). Mirrors the GitHub web-flow state cookie above.
@@ -1036,7 +1036,7 @@ module.exports = function buildAuthRouter() {
1036
1036
  const cookieToken = sessionCookieToken(req);
1037
1037
  if (!cookieToken) {
1038
1038
  // Name the instance's own sign-in host (from the branding pack), not a
1039
- // hardcoded "amazonprimea.com" (ADR 0062 §3/§5).
1039
+ // hardcoded "example.com" (ADR 0062 §3/§5).
1040
1040
  const signInHost = configuredOAuthOrigin().replace(/^https?:\/\//, '').split('/')[0] || 'the sign-in page';
1041
1041
  return res.fail('cookie_required', { status: 403, message: `This endpoint mints CLI bearers from an authenticated browser session. Sign in at ${signInHost} first; bearer-only requests are rejected so a leaked CLI token cannot mint replacements for itself.` });
1042
1042
  }
@@ -35,7 +35,7 @@ const SECURITY_DOC_CONTENT_MAX = 2_000_000;
35
35
 
36
36
  // Where the full ADR is expected to live on the droplet. Configurable so dev /
37
37
  // staging can point at a different file; the recommended prod path is
38
- // /etc/amazonprimea/security-adr.md (chmod 600, owned by the deploy user).
38
+ // /etc/example/security-adr.md (chmod 600, owned by the deploy user).
39
39
  function adrPath() {
40
40
  return (resolveEnv('SECURITY_ADR_PATH') || '').trim() || null;
41
41
  }
@@ -11,7 +11,7 @@
11
11
  // Three logical groups:
12
12
  // - /auth/* — GitHub Device Flow (CLI) + Authorization Code (web)
13
13
  // - /me, /tasks/*, /claims/*, /cost/*, /credits/*, ... — authenticated CLI/web ops
14
- // - /public/* — read-only, no auth, for status.amazonprimea.com
14
+ // - /public/* — read-only, no auth, for status.example.com
15
15
  //
16
16
  // All JSON. Same Express app as the game server.
17
17
 
package/src/branding.js CHANGED
@@ -186,7 +186,7 @@ const branding = () => (_cached ||= loadBranding());
186
186
 
187
187
  // The HTTP User-Agent the GDS sends on outbound API calls (GitHub, Discord),
188
188
  // derived from the instance branding pack so a non-OTB Cloud Bongos instance
189
- // identifies itself with ITS OWN name rather than a hardcoded "amazonprimea-gds"
189
+ // identifies itself with ITS OWN name rather than a hardcoded "example-gds"
190
190
  // (ADR 0062 §3/§5; the branding contract). Source order: the repo name (the
191
191
  // GitHub binding these calls actually target), else the env prefix, else a neutral
192
192
  // fallback. Falls back hard if branding fails so an outbound call never crashes.
@@ -10,7 +10,7 @@
10
10
  // GET /downloads/devbox/latest.json → { version, assets: { target: url } }
11
11
  // GET /downloads/devbox/<target> → 302 to the release asset
12
12
  //
13
- // so every URL a builder ever sees or shares stays on amazonprimea.com, and a
13
+ // so every URL a builder ever sees or shares stays on example.com, and a
14
14
  // release bump is a one-file config change that rides the normal ship flow.
15
15
  // Pure (config in, urls out) so tests need no server.
16
16
 
@@ -73,9 +73,9 @@ function envPrefix(b = safeBrand()) {
73
73
  // The default API base the CLI targets when there is no <PREFIX>_API_BASE env
74
74
  // override AND no logged-in session api_base — i.e. the last-resort fallback.
75
75
  // Resolves to THIS instance's own publicOrigin from the branding pack (OTB →
76
- // https://amazonprimea.com, vanilla → http://localhost:3000), so the portable
76
+ // https://example.com, vanilla → http://localhost:3000), so the portable
77
77
  // core never hard-codes another instance's URL (task 1002201 — pre-ADR-0139 the
78
- // literal 'https://amazonprimea.com' was baked into cli-lib, sending every
78
+ // literal 'https://example.com' was baked into cli-lib, sending every
79
79
  // unconfigured consumer at the founder's game box). Single source of truth: every
80
80
  // CLI base resolution routes through here. Last-resort http://localhost:3000 when
81
81
  // branding can't be read at all — a local dev origin, never a foreign prod, so an
package/src/module-api.js CHANGED
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
71
71
  // there. scripts/gds/bump-version.js still rewrites the literal below; it appends
72
72
  // the entry to that file. Look for a version's history there, not here.
73
73
  // ---------------------------------------------------------------------------
74
- const CORE_VERSION = '1.19.726'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.727'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
75
75
 
76
76
  // A namespaced logger so a module's log lines are attributable + consistent.
77
77
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -6,7 +6,7 @@
6
6
  //
7
7
  // No module in this tree names a FOREIGN origin today — every module here was
8
8
  // built in this repo. Some name THIS instance as their origin (e.g. the
9
- // provisioning module's "Off the Boats (the first Cloud Bongos instance…)"),
9
+ // provisioning module's "Example World (the first Cloud Bongos instance…)"),
10
10
  // which is still own-built. The split (core-loaded) side lights up only once a
11
11
  // module is actually pulled back in from the shared catalog under a different
12
12
  // project's name (ADR 0107 §8 pipeline, tasks 1770/1772).
@@ -17,7 +17,7 @@ function deriveProvenance(origin, ownProjectName) {
17
17
  const own = ownProjectName && String(ownProjectName).trim().toLowerCase();
18
18
  // "names this instance itself" (ADR 0107 §9) — an origin that IS, or leads
19
19
  // with, the own project name is own-built (a self-referential origin like
20
- // "Off the Boats (the first Cloud Bongos instance)" counts). Only an origin
20
+ // "Example World (the first Cloud Bongos instance)" counts). Only an origin
21
21
  // naming a DIFFERENT project is core-loaded from the shared catalog. (An
22
22
  // exact `===` was too brittle: it was written when no module set `origin`,
23
23
  // so it never met a real, descriptive value — task 1776 re-land.)