@bongos/core 1.19.725 → 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 (229) hide show
  1. package/.bongos-core.json +179 -494
  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 +4 -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/gate-review.js +14 -6
  64. package/scripts/gds/gen-diagrams.js +1 -1
  65. package/scripts/gds/leak-scan-allowlist.js +293 -0
  66. package/scripts/gds/learning-capture.js +1 -1
  67. package/scripts/gds/linkify-refs.js +2 -2
  68. package/scripts/gds/local-preview-lib.js +1 -1
  69. package/scripts/gds/mirror-lineage-check.js +1 -1
  70. package/scripts/gds/mirror-redact.js +17 -2
  71. package/scripts/gds/newcomer-floor.templates.json +1 -1
  72. package/scripts/gds/package-core.js +18 -1
  73. package/scripts/gds/paste-token.js +1 -1
  74. package/scripts/gds/provision-units.js +2 -2
  75. package/scripts/gds/publish-manifest.js +15 -0
  76. package/scripts/gds/repo-metrics.js +1 -1
  77. package/scripts/gds/sandbox-stage.js +1 -1
  78. package/scripts/gds/seed-bongos-coreB-tranche1-tasks.js +1 -1
  79. package/scripts/gds/seed-bongos-coreB-tranche2-tasks.js +1 -1
  80. package/scripts/gds/seed-bongos-goal-hierarchy-tasks.js +1 -1
  81. package/scripts/gds/seed-bongos-tasks.js +2 -2
  82. package/scripts/gds/seed-gds-v4-tasks.js +1 -1
  83. package/scripts/gds/seed-medusa-tasks.js +10 -10
  84. package/scripts/gds/seed-module-upstreaming.js +1 -1
  85. package/scripts/gds/seed-productization-tasks.js +6 -6
  86. package/scripts/gds/seed-provisioning-tasks.js +2 -2
  87. package/scripts/gds/seed-staging.sh +19 -6
  88. package/scripts/gds/ship-deploy-target.js +1 -1
  89. package/scripts/gds/ship-flow.js +1 -1
  90. package/scripts/gds/smoke-gds.js +1 -1
  91. package/scripts/status-probe.mjs +2 -2
  92. package/src/bongos/auth-discord.js +2 -2
  93. package/src/bongos/live-channel.js +1 -1
  94. package/src/bongos/permission-path-check.js +80 -3
  95. package/src/bongos/pool.js +1 -1
  96. package/src/bongos/routes/auth.js +11 -11
  97. package/src/bongos/routes/security.js +1 -1
  98. package/src/bongos/routes.js +1 -1
  99. package/src/branding.js +1 -1
  100. package/src/devbox-downloads.js +1 -1
  101. package/src/instance-config.js +2 -2
  102. package/src/module-api.js +1 -1
  103. package/src/module-loader/provenance.js +2 -2
  104. package/tests/art_stage.mjs +2 -2
  105. package/tests/auth_anthropic_identity.mjs +1 -1
  106. package/tests/auth_duplicate_cookie.mjs +1 -1
  107. package/tests/auth_error_brand.mjs +1 -1
  108. package/tests/auth_inactive_builder.mjs +1 -1
  109. package/tests/backup_cli.mjs +4 -4
  110. package/tests/bongos_box_connect.mjs +2 -2
  111. package/tests/bongos_downloads.mjs +2 -2
  112. package/tests/bongos_login.mjs +5 -5
  113. package/tests/box_connect_e2e.mjs +2 -2
  114. package/tests/box_dns_repoint.mjs +10 -10
  115. package/tests/box_host_keys.mjs +1 -1
  116. package/tests/box_onboard.mjs +9 -9
  117. package/tests/box_scope_session.mjs +1 -1
  118. package/tests/box_terminal_ssrf.mjs +7 -7
  119. package/tests/boxes.mjs +9 -9
  120. package/tests/branding.mjs +2 -2
  121. package/tests/bump_version.mjs +2 -2
  122. package/tests/cf_tunnel.mjs +40 -40
  123. package/tests/cli_token_reissue.mjs +7 -7
  124. package/tests/cloud_bongos_pack.mjs +1 -1
  125. package/tests/currency_label.mjs +8 -8
  126. package/tests/dev_lib.mjs +4 -4
  127. package/tests/devbox_dmg_backdrop.mjs +1 -1
  128. package/tests/devbox_downloads.mjs +2 -2
  129. package/tests/devbox_icons.mjs +1 -1
  130. package/tests/discord_approvals.mjs +1 -1
  131. package/tests/discord_oauth.mjs +2 -2
  132. package/tests/executed_closure.mjs +6 -1
  133. package/tests/first_admin_bootstrap.mjs +1 -1
  134. package/tests/gate_approvals.mjs +5 -5
  135. package/tests/government_protected_surfaces.mjs +137 -0
  136. package/tests/grade_aggregates_unavailable.mjs +1 -1
  137. package/tests/hook_user_agents.mjs +2 -2
  138. package/tests/init.mjs +6 -6
  139. package/tests/instance_config.mjs +1 -1
  140. package/tests/instance_manifest.mjs +5 -5
  141. package/tests/instance_mismatch_guard.mjs +13 -13
  142. package/tests/leak_scan_allowlist.mjs +94 -0
  143. package/tests/migrate_root_resolution.mjs +4 -4
  144. package/tests/mirror_redact.mjs +28 -4
  145. package/tests/module_catalog.mjs +5 -5
  146. package/tests/module_submissions.mjs +3 -3
  147. package/tests/package_core.mjs +1 -1
  148. package/tests/parallel-load.mjs +6 -6
  149. package/tests/projects_hub.mjs +2 -2
  150. package/tests/provision.mjs +50 -50
  151. package/tests/provisioning_github_app_routes.mjs +1 -1
  152. package/tests/provisioning_onboard_mode.mjs +2 -2
  153. package/tests/publish_reconciler.mjs +4 -4
  154. package/tests/sandbox_stage.mjs +1 -1
  155. package/tests/scrubber_corpus.mjs +3 -3
  156. package/tests/search_isolation.mjs +1 -1
  157. package/tests/session_records.mjs +1 -1
  158. package/tests/ship_card.mjs +6 -6
  159. package/tests/ship_ci_deploy.mjs +1 -1
  160. package/tests/single_host_hall.mjs +9 -9
  161. package/tests/smoke_preflight.mjs +1 -1
  162. package/tests/smoke_target.mjs +1 -1
  163. package/tests/status-probe.mjs +1 -1
  164. package/tests/status_mirror_sync.mjs +1 -1
  165. package/docs/adr/0004-amazonprimea-name-and-trademark-acceptance.md +0 -45
  166. package/docs/design/mocks/_schemes.css +0 -604
  167. package/docs/design/mocks/component-sheet.html +0 -428
  168. package/docs/design/mocks/hall/_tokens.css +0 -370
  169. package/docs/design/mocks/hall/board/v1.html +0 -846
  170. package/docs/design/mocks/hall/board/v2.html +0 -858
  171. package/docs/design/mocks/hall/board/v3.html +0 -884
  172. package/docs/design/mocks/hall/goals/v1.html +0 -1212
  173. package/docs/design/mocks/hall/goals/v2.html +0 -1192
  174. package/docs/design/mocks/hall/goals/v3.html +0 -1205
  175. package/docs/design/mocks/hall/hall-sheet.html +0 -244
  176. package/docs/design/mocks/hall/reading/v1.html +0 -1125
  177. package/docs/design/mocks/hall/reading/v2.html +0 -1177
  178. package/docs/design/mocks/hall/reading/v3.html +0 -1150
  179. package/docs/design/mocks/hall/settings/v1.html +0 -1238
  180. package/docs/design/mocks/hall/settings/v2.html +0 -1235
  181. package/docs/design/mocks/hall/settings/v3.html +0 -1299
  182. package/docs/design/mocks/hall/task/v1.html +0 -633
  183. package/docs/design/mocks/hall/task/v2.html +0 -646
  184. package/docs/design/mocks/hall/task/v3.html +0 -647
  185. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg +0 -0
  186. package/docs/design/mocks/hub/assets/r3-space-deepfield-half.jpg.json +0 -13
  187. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg +0 -0
  188. package/docs/design/mocks/hub/assets/r3-space-dust-half.jpg.json +0 -13
  189. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg +0 -0
  190. package/docs/design/mocks/hub/assets/r3-space-nebula-half.jpg.json +0 -13
  191. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg +0 -0
  192. package/docs/design/mocks/hub/assets/r3-space-starfield-half.jpg.json +0 -13
  193. package/docs/design/mocks/hub/hub-sheet.html +0 -192
  194. package/docs/design/mocks/hub/mine.html +0 -465
  195. package/docs/design/mocks/hub/picker.html +0 -421
  196. package/docs/design/mocks/hub/planets.html +0 -356
  197. package/docs/design/mocks/hub/v1.html +0 -1209
  198. package/docs/design/mocks/hub/v2.html +0 -1257
  199. package/docs/design/mocks/hub/v3.html +0 -1496
  200. package/docs/design/mocks/hub/wizard.html +0 -421
  201. package/docs/design/mocks/landing/landing-sheet.html +0 -131
  202. package/docs/design/mocks/landing/v1.html +0 -956
  203. package/docs/design/mocks/landing/v2.html +0 -708
  204. package/docs/design/mocks/landing/v3.html +0 -911
  205. package/docs/design/mocks/landing-page-mock.html +0 -687
  206. package/docs/design/mocks/landing-palettes.html +0 -103
  207. package/docs/design/mocks/projects-hub-mock.html +0 -991
  208. package/docs/design/mocks/projects-hub-variants.html +0 -146
  209. package/docs/design/mocks/projects-page-mock.html +0 -167
  210. package/docs/design/mocks/world/blue-hud/_tokens.css +0 -246
  211. package/docs/design/mocks/world/blue-hud/hall.html +0 -595
  212. package/docs/design/mocks/world/blue-hud/landing.html +0 -424
  213. package/docs/design/mocks/world/blue-hud/status.html +0 -410
  214. package/docs/design/mocks/world/chrome-blobs/_tokens.css +0 -479
  215. package/docs/design/mocks/world/chrome-blobs/hall.html +0 -553
  216. package/docs/design/mocks/world/chrome-blobs/landing-b.html +0 -581
  217. package/docs/design/mocks/world/chrome-blobs/landing.html +0 -328
  218. package/docs/design/mocks/world/chrome-blobs/status.html +0 -416
  219. package/docs/design/mocks/world/natgeo-editorial/_tokens.css +0 -377
  220. package/docs/design/mocks/world/natgeo-editorial/hall.html +0 -649
  221. package/docs/design/mocks/world/natgeo-editorial/landing-b.html +0 -743
  222. package/docs/design/mocks/world/natgeo-editorial/landing.html +0 -475
  223. package/docs/design/mocks/world/natgeo-editorial/status.html +0 -437
  224. package/docs/design/mocks/world/organic-cards/_tokens.css +0 -462
  225. package/docs/design/mocks/world/organic-cards/hall.html +0 -625
  226. package/docs/design/mocks/world/organic-cards/landing-b.html +0 -736
  227. package/docs/design/mocks/world/organic-cards/landing.html +0 -420
  228. package/docs/design/mocks/world/organic-cards/status.html +0 -458
  229. package/docs/design/mocks/world/world-sheet.html +0 -156
@@ -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.725'; // 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.)
@@ -82,13 +82,13 @@ await ta('main: no sandbox here → rebuilds, reports no sandbox, not surfaced',
82
82
  await ta('main: box context → restarts, waits healthy, prints the sandbox URL', async () => {
83
83
  let restarted = false;
84
84
  const deps = baseDeps({
85
- resolvePreviewContext: () => ({ kind: 'box', url: 'https://sandbox-x.amazonprimea.com', healthUrl: 'http://127.0.0.1:3000/', restart: () => { restarted = true; } }),
85
+ resolvePreviewContext: () => ({ kind: 'box', url: 'https://sandbox-x.example.com', healthUrl: 'http://127.0.0.1:3000/', restart: () => { restarted = true; } }),
86
86
  });
87
87
  const r = await art.main(['--tiles', 'container_a'], deps);
88
88
  assert.equal(r.ok, true);
89
89
  assert.equal(r.surfaced, true);
90
90
  assert.equal(restarted, true);
91
- assert.ok(deps.logs.some((l) => l.includes('https://sandbox-x.amazonprimea.com')));
91
+ assert.ok(deps.logs.some((l) => l.includes('https://sandbox-x.example.com')));
92
92
  assert.ok(deps.logs.some((l) => /container_a/.test(l)), 'affected tiles printed');
93
93
  });
94
94
 
@@ -49,7 +49,7 @@ const t = async (name, fn) => {
49
49
  catch (e) { fail++; console.log(`FAIL ${name}\n ${e.stack || e.message}`); }
50
50
  };
51
51
 
52
- const LINKED = { builder_id: 1, github_login: 'lars589', rank: 'archon', status: 'active', anthropic_user_id: 'uuid-real' };
52
+ const LINKED = { builder_id: 1, github_login: 'example-owner', rank: 'archon', status: 'active', anthropic_user_id: 'uuid-real' };
53
53
 
54
54
  await t('linked builder + DIFFERENT header (2nd Claude account) → next() called, NOT 403 (pin removed)', async () => {
55
55
  nextSession = LINKED;
@@ -1,6 +1,6 @@
1
1
  // tests/auth_duplicate_cookie.mjs — regression for the duplicate gds_session
2
2
  // cookie 401 (#851). A browser can carry TWO gds_session cookies: a stale
3
- // host-only one (set on amazonprimea.com before the #726/#734 apex-scoping
3
+ // host-only one (set on example.com before the #726/#734 apex-scoping
4
4
  // rollout) AND the current apex-scoped one. The old extractToken() returned the
5
5
  // FIRST value only, so a stale duplicate could shadow the live session and 401
6
6
  // the builder (hit on the Discord link callback for builder 25). extractTokens()
@@ -21,7 +21,7 @@ const { renderAuthErrorPage } = authMod;
21
21
  const KEYS = ['titleSuffix', 'epigraph', 'heading', 'subtitle', 'ctaLabel'];
22
22
  // Instance-specific terms that must never appear in the NEUTRAL/vanilla copy —
23
23
  // exactly what was leaking onto cloudbongos.com before this fix.
24
- const OTB_LORE = [/archon/i, /\bgate\b/i, /chronicles/i, /amazonprimea/i, /\bboats\b/i, /drachma/i];
24
+ const OTB_LORE = [/archon/i, /\bgate\b/i, /chronicles/i, /example/i, /\bboats\b/i, /drachma/i];
25
25
 
26
26
  // A vanilla boot has no instance config → the neutral starter alone (the
27
27
  // fail-to-vanilla path), exactly as a fresh `node src/platform-server.js` would.
@@ -59,7 +59,7 @@ await t('inactive builder with a live session → 403 builder_inactive, next() N
59
59
  });
60
60
 
61
61
  await t('active builder → next() called, req.builder populated (incl. status)', async () => {
62
- nextSession = { builder_id: 1, github_login: 'lars589', rank: 'archon', status: 'active' };
62
+ nextSession = { builder_id: 1, github_login: 'example-owner', rank: 'archon', status: 'active' };
63
63
  const req = { headers: { authorization: 'Bearer abc123' } };
64
64
  const res = fakeRes();
65
65
  let nexted = false;
@@ -46,7 +46,7 @@ function extractTimestamp(filename, dbName) {
46
46
  }
47
47
 
48
48
  t('extractTimestamp: well-formed filename', () => {
49
- const ts = extractTimestamp('amazonprimea-2026-06-29T040001Z.sql.gz', 'amazonprimea');
49
+ const ts = extractTimestamp('example-2026-06-29T040001Z.sql.gz', 'example');
50
50
  assert.equal(ts, '2026-06-29T040001Z');
51
51
  });
52
52
  t('extractTimestamp: different db name', () => {
@@ -58,7 +58,7 @@ t('extractTimestamp: different db name', () => {
58
58
  // These verify the shape the CLI backup.js expects from GET /backup/status.
59
59
 
60
60
  t('status: latest_dump null when no dumps', () => {
61
- const response = { backup_dir: '/var/backups/gds', db_name: 'amazonprimea', latest_dump: null, trigger_running: false };
61
+ const response = { backup_dir: '/var/backups/gds', db_name: 'example', latest_dump: null, trigger_running: false };
62
62
  assert.equal(response.latest_dump, null);
63
63
  assert.equal(response.trigger_running, false);
64
64
  });
@@ -66,9 +66,9 @@ t('status: latest_dump null when no dumps', () => {
66
66
  t('status: latest_dump populated when dumps exist', () => {
67
67
  const response = {
68
68
  backup_dir: '/var/backups/gds',
69
- db_name: 'amazonprimea',
69
+ db_name: 'example',
70
70
  latest_dump: {
71
- filename: 'amazonprimea-2026-06-29T040001Z.sql.gz',
71
+ filename: 'example-2026-06-29T040001Z.sql.gz',
72
72
  timestamp: '2026-06-29T040001Z',
73
73
  size_bytes: 614400,
74
74
  count: 7,
@@ -6,7 +6,7 @@ import { test } from 'node:test';
6
6
  import crypto from 'node:crypto';
7
7
  import lib from '../scripts/gds/box-connect-lib.js';
8
8
 
9
- const HOST = 'box-alice.dev.amazonprimea.com';
9
+ const HOST = 'box-alice.dev.example.com';
10
10
 
11
11
  test('rankAtLeast gates --local at Metic+', () => {
12
12
  assert.equal(lib.rankAtLeast('metic', 'metic'), true);
@@ -69,7 +69,7 @@ test('buildKnownHostsUpsert drops the stale line for the host, keeps others, app
69
69
  // ACCUMULATED: the client kept verifying against the first, now-wrong entry
70
70
  // ("Host denied (verification failed)") on a box that had just re-reported keys.
71
71
  test('buildKnownHostsUpsert drops a host,ip entry for this box (the accumulation bug)', () => {
72
- const existing = `${HOST},64.225.49.206 ssh-ed25519 STALE\n`;
72
+ const existing = `${HOST},192.0.2.30 ssh-ed25519 STALE\n`;
73
73
  const next = lib.buildKnownHostsUpsert(existing, HOST, 'ssh-ed25519 AAAANEW');
74
74
  assert.ok(!next.includes('STALE'), 'a `host,ip` field-1 names this host and must be replaced');
75
75
  assert.ok(next.includes(`${HOST} ssh-ed25519 AAAANEW`));
@@ -23,7 +23,7 @@ function t(name, fn) {
23
23
  }
24
24
 
25
25
  const CFG = {
26
- releases_repo: 'lars589/amazonprimea-bongos',
26
+ releases_repo: 'example-owner/example-bongos',
27
27
  version: '1.2.3',
28
28
  assets: {
29
29
  'mac-arm64': 'bongos-1.2.3-darwin-arm64',
@@ -39,7 +39,7 @@ t('maps a known target to the versioned release-asset URL', () => {
39
39
  const d = buildBongosDownloads(CFG);
40
40
  assert.equal(
41
41
  d.redirectFor('mac-arm64'),
42
- 'https://github.com/lars589/amazonprimea-bongos/releases/download/v1.2.3/bongos-1.2.3-darwin-arm64'
42
+ 'https://github.com/example-owner/example-bongos/releases/download/v1.2.3/bongos-1.2.3-darwin-arm64'
43
43
  );
44
44
  });
45
45
 
@@ -17,11 +17,11 @@ const { normalizeInstanceBase, pollDecision } = require('../scripts/gds/login.js
17
17
  const LOGIN_JS = path.join(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'), 'scripts', 'gds', 'login.js');
18
18
 
19
19
  test('normalizeInstanceBase adds https, strips trailing slashes + a pasted /api/gds', () => {
20
- assert.equal(normalizeInstanceBase('amazonprimea.com'), 'https://amazonprimea.com');
21
- assert.equal(normalizeInstanceBase('https://amazonprimea.com/'), 'https://amazonprimea.com');
22
- assert.equal(normalizeInstanceBase('https://amazonprimea.com///'), 'https://amazonprimea.com');
23
- assert.equal(normalizeInstanceBase('https://amazonprimea.com/api/gds'), 'https://amazonprimea.com');
24
- assert.equal(normalizeInstanceBase('https://amazonprimea.com/api/gds/'), 'https://amazonprimea.com');
20
+ assert.equal(normalizeInstanceBase('example.com'), 'https://example.com');
21
+ assert.equal(normalizeInstanceBase('https://example.com/'), 'https://example.com');
22
+ assert.equal(normalizeInstanceBase('https://example.com///'), 'https://example.com');
23
+ assert.equal(normalizeInstanceBase('https://example.com/api/gds'), 'https://example.com');
24
+ assert.equal(normalizeInstanceBase('https://example.com/api/gds/'), 'https://example.com');
25
25
  assert.equal(normalizeInstanceBase('http://localhost:3000'), 'http://localhost:3000');
26
26
  });
27
27
 
@@ -138,8 +138,8 @@ t('installed managed-settings.json at the override dir, keyed off the session lo
138
138
  const f = path.join(settingsDir, 'managed-settings.json');
139
139
  assert.ok(fs.existsSync(f), 'managed-settings.json not written');
140
140
  const s = JSON.parse(fs.readFileSync(f, 'utf8'));
141
- assert.equal(s.sshConfigs[0].sshHost, 'root@box-e2etester.dev.amazonprimea.com');
142
- assert.deepEqual(s.sshHostAllowlist, ['*.dev.amazonprimea.com']);
141
+ assert.equal(s.sshConfigs[0].sshHost, 'root@box-e2etester.dev.example.com');
142
+ assert.deepEqual(s.sshHostAllowlist, ['*.dev.example.com']);
143
143
  });
144
144
 
145
145
  t('did NOT leak the GDS token into stdout/stderr', () => {
@@ -71,8 +71,8 @@ function runHook(scenario, extraEnv = {}, retries = '4') {
71
71
  ...process.env,
72
72
  PATH: `${tmp}:${process.env.PATH}`,
73
73
  CLOUDFLARE_API_TOKEN: 'faketoken',
74
- CLOUDFLARE_ZONE: 'amazonprimea.com',
75
- BOX_HOSTNAME: 'box-test.dev.amazonprimea.com',
74
+ CLOUDFLARE_ZONE: 'example.com',
75
+ BOX_HOSTNAME: 'box-test.dev.example.com',
76
76
  BOX_DNS_BACKOFF_BASE: '0', // no real sleeps in tests
77
77
  BOX_DNS_RETRIES: retries,
78
78
  FAKE_CF_SCENARIO: scenario,
@@ -87,7 +87,7 @@ function runHook(scenario, extraEnv = {}, retries = '4') {
87
87
  {
88
88
  const r = runHook('retry_zone', { BOX_IP: '1.2.3.4' });
89
89
  assert.equal(r.status, 0, `retry should self-heal to exit 0; got ${r.status} :: ${r.out}`);
90
- assert.match(r.out, /updated A box-test\.dev\.amazonprimea\.com -> 1\.2\.3\.4/, r.out);
90
+ assert.match(r.out, /updated A box-test\.dev\.example\.com -> 1\.2\.3\.4/, r.out);
91
91
  const attempts = parseInt(fs.readFileSync(counterFile, 'utf8'));
92
92
  assert.ok(attempts >= 2, `zone lookup should have been retried (>=2 attempts), got ${attempts}`);
93
93
  }
@@ -115,19 +115,19 @@ function runHook(scenario, extraEnv = {}, retries = '4') {
115
115
 
116
116
  const hit = runHook('delete_hit', { BOX_DNS_DELETE: '1' });
117
117
  assert.equal(hit.status, 0, `delete of a present record exits 0; got ${hit.status} :: ${hit.out}`);
118
- assert.match(hit.out, /deleted A box-test\.dev\.amazonprimea\.com/, hit.out);
118
+ assert.match(hit.out, /deleted A box-test\.dev\.example\.com/, hit.out);
119
119
  }
120
120
 
121
121
  // ── Part B: runDnsHook / runDnsHookBlackhole contract + the idea-309 repoint ────
122
122
  {
123
123
  const box = require('../scripts/gds/box.js');
124
- const upOk = box.runDnsHook('box-x.dev.amazonprimea.com', '1.2.3.4', 'exit 0');
124
+ const upOk = box.runDnsHook('box-x.dev.example.com', '1.2.3.4', 'exit 0');
125
125
  assert.equal(upOk.ok, true, 'runDnsHook returns ok:true when the hook succeeds');
126
126
 
127
- const upFail = box.runDnsHook('box-x.dev.amazonprimea.com', '1.2.3.4', 'exit 1');
127
+ const upFail = box.runDnsHook('box-x.dev.example.com', '1.2.3.4', 'exit 1');
128
128
  assert.equal(upFail.ok, false, 'runDnsHook returns ok:false when the hook FAILS (no silent swallow)');
129
129
 
130
- const noIp = box.runDnsHook('box-x.dev.amazonprimea.com', null, 'exit 1');
130
+ const noIp = box.runDnsHook('box-x.dev.example.com', null, 'exit 1');
131
131
  assert.equal(noIp.ok, true, 'runDnsHook is a no-op (ok:true skipped) when ip is absent');
132
132
 
133
133
  // idea 309: on deprovision the box lifecycle REPOINTS the record to the
@@ -137,15 +137,15 @@ function runHook(scenario, extraEnv = {}, retries = '4') {
137
137
  const probe = path.join(tmp, 'blackhole-ip');
138
138
  process.env.PROBE_FILE = probe;
139
139
  const captureHook = `node -e 'require("fs").writeFileSync(process.env.PROBE_FILE, process.env.BOX_IP || "MISSING")'`;
140
- const bhOk = box.runDnsHookBlackhole('box-x.dev.amazonprimea.com', captureHook);
140
+ const bhOk = box.runDnsHookBlackhole('box-x.dev.example.com', captureHook);
141
141
  assert.equal(bhOk.ok, true, 'runDnsHookBlackhole returns ok:true when the hook succeeds');
142
142
  assert.equal(fs.readFileSync(probe, 'utf8'), '192.0.2.1', 'runDnsHookBlackhole must REPOINT to the 192.0.2.1 sentinel (not delete)');
143
143
  delete process.env.PROBE_FILE;
144
144
 
145
- const bhFail = box.runDnsHookBlackhole('box-x.dev.amazonprimea.com', 'exit 1');
145
+ const bhFail = box.runDnsHookBlackhole('box-x.dev.example.com', 'exit 1');
146
146
  assert.equal(bhFail.ok, false, 'runDnsHookBlackhole returns ok:false when the hook FAILS (best-effort, but still reports)');
147
147
 
148
- const bhNoHook = box.runDnsHookBlackhole('box-x.dev.amazonprimea.com', null);
148
+ const bhNoHook = box.runDnsHookBlackhole('box-x.dev.example.com', null);
149
149
  assert.equal(bhNoHook.ok, true, 'runDnsHookBlackhole is a no-op (ok:true skipped) when no hook is configured');
150
150
  }
151
151
 
@@ -47,7 +47,7 @@ const RSA = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/FqVQUVRAmcDHRBeEZZwuW0xgsAP
47
47
 
48
48
  // 4) a hostname prefix (3 fields) → refused, not silently trimmed
49
49
  {
50
- const r = validateHostKeyLines(`box-x.dev.amazonprimea.com ${ED}`);
50
+ const r = validateHostKeyLines(`box-x.dev.example.com ${ED}`);
51
51
  assert.equal(r.ok, false);
52
52
  assert.equal(r.error, 'expect_type_and_key_only');
53
53
  }
@@ -131,28 +131,28 @@ console.log('managed-settings:');
131
131
  t('buildManagedSettings: shape matches the template; allowlist pins the passed sshZone', () => {
132
132
  // world + sshZone are supplied by the caller from the branding pack (task 1705);
133
133
  // the renderer is pure and bakes exactly what it's given.
134
- const s = o.buildManagedSettings({ login: 'alice', hostname: 'box-alice.dev.amazonprimea.com', world: 'Amazonprimea', sshZone: 'dev.amazonprimea.com' });
134
+ const s = o.buildManagedSettings({ login: 'alice', hostname: 'box-alice.dev.example.com', world: 'Example', sshZone: 'dev.example.com' });
135
135
  assert.equal(s.sshConfigs[0].id, 'otb-alice');
136
- assert.equal(s.sshConfigs[0].name, 'Amazonprimea Dev Box');
137
- assert.equal(s.sshConfigs[0].sshHost, 'root@box-alice.dev.amazonprimea.com');
136
+ assert.equal(s.sshConfigs[0].name, 'Example Dev Box');
137
+ assert.equal(s.sshConfigs[0].sshHost, 'root@box-alice.dev.example.com');
138
138
  assert.equal(s.sshConfigs[0].startDirectory, '~/workspace');
139
- assert.deepEqual(s.sshHostAllowlist, ['*.dev.amazonprimea.com']);
139
+ assert.deepEqual(s.sshHostAllowlist, ['*.dev.example.com']);
140
140
  });
141
141
 
142
142
  t('buildManagedSettings: bad login / hostname throw coded errors (no injection into the JSON)', () => {
143
- assert.throws(() => o.buildManagedSettings({ login: 'a/b', hostname: 'x.dev.amazonprimea.com' }), /BAD_LOGIN|invalid login/);
143
+ assert.throws(() => o.buildManagedSettings({ login: 'a/b', hostname: 'x.dev.example.com' }), /BAD_LOGIN|invalid login/);
144
144
  assert.throws(() => o.buildManagedSettings({ login: 'alice', hostname: 'evil"\nhost' }), /BAD_HOSTNAME|invalid hostname/);
145
145
  });
146
146
 
147
147
  console.log('connect guide:');
148
148
 
149
149
  t('renderConnectGuide: bakes the apiBase into the bootstrap URLs', () => {
150
- const g = o.renderConnectGuide({ apiBase: 'https://staging.amazonprimea.com' });
151
- assert.ok(g.includes('https://staging.amazonprimea.com/api/gds/box/connect.sh'));
150
+ const g = o.renderConnectGuide({ apiBase: 'https://staging.example.com' });
151
+ assert.ok(g.includes('https://staging.example.com/api/gds/box/connect.sh'));
152
152
  assert.ok(g.includes('/api/gds/box/connect.ps1'));
153
153
  // the supplied apiBase is baked verbatim (the caller PINS the origin — it is never
154
154
  // a hardcoded host brand, task 1705)
155
- assert.ok(o.renderConnectGuide({ apiBase: 'https://amazonprimea.com' }).includes('https://amazonprimea.com/api/gds/box/connect.sh'));
155
+ assert.ok(o.renderConnectGuide({ apiBase: 'https://example.com' }).includes('https://example.com/api/gds/box/connect.sh'));
156
156
  });
157
157
 
158
158
  console.log('DB query shapes (fake pool):');
@@ -297,7 +297,7 @@ await ta('GET /box/managed-settings: → 200 JSON keyed off the session login',
297
297
  assert.equal(r.status, 200);
298
298
  const b = await r.json();
299
299
  assert.equal(b.sshConfigs[0].id, 'otb-alice');
300
- assert.equal(b.sshConfigs[0].sshHost, 'root@box-alice.dev.amazonprimea.com');
300
+ assert.equal(b.sshConfigs[0].sshHost, 'root@box-alice.dev.example.com');
301
301
  });
302
302
 
303
303
  await ta('GET /box/connect.sh: PUBLIC, no auth → 200; bakes the PINNED origin and IGNORES a spoofed Host (blocker #2/#5)', async () => {
@@ -85,7 +85,7 @@ await t('box session + allowBoxScope (middleware ran) → next() called, req.bui
85
85
 
86
86
  // ---- cli / web sessions are unaffected by the box gate -----------------------
87
87
  await t('cli session on a non-box route → unaffected, next() called', async () => {
88
- nextSession = { builder_id: 1, github_login: 'lars589', rank: 'archon', status: 'active', source: 'cli' };
88
+ nextSession = { builder_id: 1, github_login: 'example-owner', rank: 'archon', status: 'active', source: 'cli' };
89
89
  const req = { headers: { authorization: 'Bearer clitoken' } }; // no allowBoxScope
90
90
  const res = fakeRes();
91
91
  let nexted = false;
@@ -24,9 +24,9 @@ const test = (name, fn) => {
24
24
  catch (e) { fail++; console.log(`FAIL ${name}\n ${e.message}`); }
25
25
  };
26
26
 
27
- const LOGIN = 'lars589';
27
+ const LOGIN = 'example-owner';
28
28
  // The dev-box apex is INJECTED rather than taken from the live instance branding
29
- // (task 1002470). Two reasons: the neutral core has no amazonprimea.com apex, so the
29
+ // (task 1002470). Two reasons: the neutral core has no example.com apex, so the
30
30
  // three allow-cases could not pass; and every reject-case below was passing for the
31
31
  // WRONG reason — an apex mismatch, not the rule it names. With a pinned apex,
32
32
  // 'rejects another builder's term- host' really does prove the login binding.
@@ -34,10 +34,10 @@ const APEX = 'apex.example';
34
34
 
35
35
  // ---- allowed: the two legitimate tunnel shapes -------------------------------
36
36
  test('allows the named-tunnel apex host bound to the caller login', () => {
37
- assert.equal(isSafeTerminalUrl(`https://term-lars589.${APEX}`, LOGIN, APEX), true);
37
+ assert.equal(isSafeTerminalUrl(`https://term-example-owner.${APEX}`, LOGIN, APEX), true);
38
38
  });
39
39
  test(`allows the named-tunnel dev-zone host (term-<login>.dev.${APEX})`, () => {
40
- assert.equal(isSafeTerminalUrl(`https://term-lars589.dev.${APEX}/`, LOGIN, APEX), true);
40
+ assert.equal(isSafeTerminalUrl(`https://term-example-owner.dev.${APEX}/`, LOGIN, APEX), true);
41
41
  });
42
42
  test('allows a Cloudflare quick-tunnel host (*.trycloudflare.com)', () => {
43
43
  assert.equal(isSafeTerminalUrl('https://random-words-1234.trycloudflare.com', LOGIN, APEX), true);
@@ -66,10 +66,10 @@ for (const bad of [
66
66
 
67
67
  // ---- rejected: wrong scheme / shape / cross-login ----------------------------
68
68
  test('rejects http (must be https)', () => {
69
- assert.equal(isSafeTerminalUrl(`http://term-lars589.${APEX}`, LOGIN, APEX), false);
69
+ assert.equal(isSafeTerminalUrl(`http://term-example-owner.${APEX}`, LOGIN, APEX), false);
70
70
  });
71
71
  test('rejects embedded credentials (user:pass@host)', () => {
72
- assert.equal(isSafeTerminalUrl(`https://user:pass@term-lars589.${APEX}`, LOGIN, APEX), false);
72
+ assert.equal(isSafeTerminalUrl(`https://user:pass@term-example-owner.${APEX}`, LOGIN, APEX), false);
73
73
  });
74
74
  test('rejects another builder\'s term- host (login binding)', () => {
75
75
  assert.equal(isSafeTerminalUrl(`https://term-someoneelse.${APEX}`, LOGIN, APEX), false);
@@ -89,7 +89,7 @@ test('rejects garbage / unparseable', () => {
89
89
  assert.equal(isSafeTerminalUrl(null, LOGIN, APEX), false);
90
90
  });
91
91
  test('rejects when login is empty (cannot bind the term- form)', () => {
92
- assert.equal(isSafeTerminalUrl(`https://term-lars589.${APEX}`, '', APEX), false);
92
+ assert.equal(isSafeTerminalUrl(`https://term-example-owner.${APEX}`, '', APEX), false);
93
93
  });
94
94
 
95
95
  console.log(`\n${pass} passed, ${fail} failed`);
package/tests/boxes.mjs CHANGED
@@ -898,10 +898,10 @@ t('#903: rendered cloud-init user-data stays under DigitalOcean\'s 64KB cap', ()
898
898
  .split('__CLOUDFLARED_SERVICE_B64__').join(gz('cloudflared.service'))
899
899
  .split('__CLOUDFLARED_RUN_B64__').join(gz('cloudflared-run.sh'))
900
900
  .split('__CLOSE_BOX_B64__').join(gz('close-box.sh'))
901
- .split('__REPO_URL__').join('git@github.com:owner/amazonprimea.git')
901
+ .split('__REPO_URL__').join('git@github.com:owner/example.git')
902
902
  .split('__BUILDER_AUTHORIZED_KEYS_B64__').join(Buffer.from('ssh-ed25519 AAAA...k1\nssh-ed25519 AAAA...k2\n').toString('base64'))
903
- .split('__BOX_ENV_B64__').join(Buffer.from('BOX_TUNNEL_TOKEN=' + 'x'.repeat(200) + '\nBOX_TERMINAL_HOSTNAME=term-x.amazonprimea.com\nBOX_TERMINAL_CREDENTIAL=' + 'a'.repeat(48) + '\nBOX_PREVIEW_HOSTNAME=sandbox-x.amazonprimea.com\n').toString('base64'))
904
- .split('__GDS_SESSION_B64__').join(Buffer.from(JSON.stringify({ token: 'x'.repeat(64), builder: { id: 1, github_login: 'x', rank: 'archon' }, api_base: 'https://amazonprimea.com' })).toString('base64'));
903
+ .split('__BOX_ENV_B64__').join(Buffer.from('BOX_TUNNEL_TOKEN=' + 'x'.repeat(200) + '\nBOX_TERMINAL_HOSTNAME=term-x.example.com\nBOX_TERMINAL_CREDENTIAL=' + 'a'.repeat(48) + '\nBOX_PREVIEW_HOSTNAME=sandbox-x.example.com\n').toString('base64'))
904
+ .split('__GDS_SESSION_B64__').join(Buffer.from(JSON.stringify({ token: 'x'.repeat(64), builder: { id: 1, github_login: 'x', rank: 'archon' }, api_base: 'https://example.com' })).toString('base64'));
905
905
  const bytes = Buffer.byteLength(out, 'utf8');
906
906
  assert.ok(bytes < 64 * 1024, `rendered cloud-init is ${bytes}B; must stay under DO's 65536B cap`);
907
907
  });
@@ -1193,13 +1193,13 @@ t('planDropletDrift: a droplet a live box owns is in sync (no drift)', () => {
1193
1193
  t('planDropletDrift: ZOMBIE — droplet exists but its box row is destroyed (the bug)', () => {
1194
1194
  // The exact task-1289 shape: deprovision marked the row destroyed + nulled
1195
1195
  // droplet_id, but the droplet was never actually deleted.
1196
- const droplets = [{ id: 222, name: 'otb-box-lars589', tags: ['otb-builder-box', 'builder:lars589'], created_at: '2026-05-01T00:00:00Z' }];
1197
- const boxRows = [{ builder_id: 3, github_login: 'lars589', state: 'destroyed', droplet_id: null }];
1196
+ const droplets = [{ id: 222, name: 'otb-box-example-owner', tags: ['otb-builder-box', 'builder:example-owner'], created_at: '2026-05-01T00:00:00Z' }];
1197
+ const boxRows = [{ builder_id: 3, github_login: 'example-owner', state: 'destroyed', droplet_id: null }];
1198
1198
  const { zombies, ghosts } = boxes.planDropletDrift({ droplets, boxRows, nowMs: NOW });
1199
1199
  assert.equal(ghosts.length, 0);
1200
1200
  assert.equal(zombies.length, 1);
1201
1201
  assert.equal(zombies[0].dropletId, '222');
1202
- assert.equal(zombies[0].login, 'lars589');
1202
+ assert.equal(zombies[0].login, 'example-owner');
1203
1203
  assert.equal(zombies[0].builderId, 3, 'maps the zombie back to its builder for edge teardown');
1204
1204
  });
1205
1205
 
@@ -1383,8 +1383,8 @@ function sweepHarness({ idleRows, parkThrows = null }) {
1383
1383
 
1384
1384
  await ta('cmdSweepIdle: an idle box is PARKED — snapshot retained, no snapshot delete', async () => {
1385
1385
  const NOW_ROW = {
1386
- id: 3, builder_id: 3, state: 'active', droplet_id: '591743808', droplet_name: 'box-lars589',
1387
- github_login: 'lars589', last_activity_at: new Date(Date.now() - 5 * 3600_000).toISOString(),
1386
+ id: 3, builder_id: 3, state: 'active', droplet_id: '591743808', droplet_name: 'box-example-owner',
1387
+ github_login: 'example-owner', last_activity_at: new Date(Date.now() - 5 * 3600_000).toISOString(),
1388
1388
  claude_active: false, snapshot_id: null,
1389
1389
  };
1390
1390
  const h = sweepHarness({ idleRows: [NOW_ROW] });
@@ -1414,7 +1414,7 @@ await ta('cmdSweepIdle: an idle box is PARKED — snapshot retained, no snapshot
1414
1414
 
1415
1415
  await ta('cmdSweepIdle: dry-run reports "would park" and touches nothing', async () => {
1416
1416
  const row = {
1417
- id: 3, builder_id: 3, state: 'active', droplet_id: '591743808', github_login: 'lars589',
1417
+ id: 3, builder_id: 3, state: 'active', droplet_id: '591743808', github_login: 'example-owner',
1418
1418
  last_activity_at: new Date(Date.now() - 5 * 3600_000).toISOString(), claude_active: false,
1419
1419
  };
1420
1420
  const h = sweepHarness({ idleRows: [row] });
@@ -21,7 +21,7 @@ const NEUTRAL = {
21
21
 
22
22
  // A GENERIC sample instance pack — exercises the resolver's override/merge/precedence logic
23
23
  // without baking any real instance's identity into the (published) test. (task 1002219 / audit H5:
24
- // swept the former customer-1 sample — Off the Boats / amazonprimea / Hermeslines — to neutral.)
24
+ // swept the former customer-1 sample — Example World / example / Hermeslines — to neutral.)
25
25
  const SAMPLE = {
26
26
  identity: { productName: 'Acme Rockets', worldName: 'Acme', company: { name: 'Acme Corp', site: 'https://acme.example' } },
27
27
  llmProjectName: 'Acme Rockets',
@@ -95,7 +95,7 @@ test('deepMerge does not mutate its inputs', () => {
95
95
  test('the committed neutral pack loads + resolves to the neutral identity (the trunk carries no instance branding.json)', () => {
96
96
  // The neutral trunk ships config/branding.neutral.json only — no config/branding.json — so
97
97
  // loadBranding resolves to the plain Cloud Bongos identity (task 1002219 / audit H5: this used to
98
- // assert the customer-1 OTB identity, stale since the amazonprimea→cloudbongos rebrand, ADR 0139/0140).
98
+ // assert the customer-1 OTB identity, stale since the example→cloudbongos rebrand, ADR 0139/0140).
99
99
  const b = loadBranding({ env: {} });
100
100
  assert.equal(b.identity.productName, 'Cloud Bongos');
101
101
  assert.equal(b.identity.worldName, 'Cloud Bongos');
@@ -146,7 +146,7 @@ test('a HUMAN release commit never matches — skipping it would swallow its pub
146
146
  });
147
147
 
148
148
  test('work-merge subjects, junk, and empties never match', () => {
149
- assert.equal(isReleaseCommit('Merge pull request #30 from lars589/claude/cloudbongos-npm-registry-b9a57f'), false);
149
+ assert.equal(isReleaseCommit('Merge pull request #30 from example-owner/claude/cloudbongos-npm-registry-b9a57f'), false);
150
150
  assert.equal(isReleaseCommit('fix(ship): protection-aware deploy mode'), false);
151
151
  assert.equal(isReleaseCommit(''), false);
152
152
  assert.equal(isReleaseCommit(null), false);
@@ -190,7 +190,7 @@ test('publish.yml wires the terminator: guard step present, every armed step gat
190
190
  test('laneReleasedVersions reads the versions this lane announced', () => {
191
191
  const subjects = [
192
192
  'release: core 1.19.368 — CI auto-patch carrier (publish-on-merge, ADR 0161)',
193
- 'Merge pull request #385 from lars589/some-branch',
193
+ 'Merge pull request #385 from example-owner/some-branch',
194
194
  'release: core 1.19.367 — CI auto-patch carrier (publish-on-merge, ADR 0161)',
195
195
  'feat(security): something unrelated',
196
196
  ];