@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
@@ -518,3 +518,140 @@ test('the floor decision reads the hit\'s registry floor, so a re-map takes effe
518
518
  const atFloor = ppc.checkPermissionPaths({ changedFiles: ['migrations/001.sql'], builderRank: 'metic' });
519
519
  assert.equal(atFloor.hardFail, false);
520
520
  });
521
+
522
+
523
+ // ---------------------------------------------------------------------------
524
+ // task 1002874 — NFC + case-folding, the last piece of R101's ADR 0151 §4 scope.
525
+ //
526
+ // R101 shipped the registry with matching left exact-BYTES, deliberately and
527
+ // declared: its hard constraint was byte-identical behaviour, and normalisation
528
+ // changes what matches. This IS that change, so these come in two halves — the
529
+ // wall must now hold against a re-spelling, and nothing protected before may have
530
+ // stopped being protected.
531
+ // ---------------------------------------------------------------------------
532
+
533
+ // A real literal surface from the registry, not a fixture: this cannot pass
534
+ // against a glob that no longer exists.
535
+ const LITERAL = ppc.PROTECTED_SURFACES.find((s) => !s.glob.includes('*') && !s.glob.endsWith('/'));
536
+
537
+ test('a CASE variant of a protected path is still protected', () => {
538
+ assert.ok(LITERAL, 'no literal surface in the registry — this test is reading the wrong shape');
539
+ assert.ok(ppc.surfaceFor(LITERAL.glob), 'the exact spelling must match (sanity)');
540
+ // macOS by default and Windows are case-INsensitive: this names the SAME file.
541
+ assert.ok(ppc.surfaceFor(LITERAL.glob.toUpperCase()),
542
+ 'an uppercased spelling of a protected file must not step over the wall');
543
+ const mixed = LITERAL.glob.replace(/(^|\/)([a-z])/g, (m, s, c) => s + c.toUpperCase());
544
+ assert.ok(ppc.surfaceFor(mixed), `a mixed-case spelling must not step over the wall: ${mixed}`);
545
+ });
546
+
547
+ test('the REPORTED path keeps its original case — only matching is folded', () => {
548
+ const shouty = LITERAL.glob.toUpperCase();
549
+ const [hit] = ppc.matchProtected([shouty]);
550
+ assert.ok(hit, 'the case variant must be caught');
551
+ assert.equal(hit.file, shouty,
552
+ 'findings, refusals and grader issues all carry this path; a lowercased one names '
553
+ + 'nothing on a case-SENSITIVE filesystem (Linux, i.e. CI) and would ENOENT for a file that exists');
554
+ assert.equal(hit.glob, LITERAL.glob, 'and the registry glob is reported verbatim, not folded');
555
+ });
556
+
557
+ test('an NFD-composed path matches its NFC glob', () => {
558
+ // The registry is pure ASCII today, so this exercises the mechanism directly:
559
+ // one filename, two different byte strings, either of which a checkout can hand you.
560
+ const nfc = 'modules/caf\u00e9/secret.js';
561
+ const nfd = 'modules/cafe\u0301/secret.js';
562
+ assert.notEqual(nfc, nfd, 'the two spellings must really differ in bytes, or this proves nothing');
563
+ const fold = (s) => s.normalize('NFC').toLowerCase();
564
+ const re = ppc.globToRegExp(fold(nfc));
565
+ assert.ok(re.test(fold(nfd)), 'NFD and NFC spellings of one filename must match the same glob');
566
+ assert.ok(re.test(fold(nfc.toUpperCase())), 'and case must not separate them either');
567
+ });
568
+
569
+ test('STRICTLY WIDENING: every glob still matches a path it matched before', () => {
570
+ // The regression that would matter is a path silently becoming UNprotected, so
571
+ // walk the whole registry and synthesise a concrete path from each glob.
572
+ let checked = 0;
573
+ for (const s of ppc.PROTECTED_SURFACES) {
574
+ const sample = s.glob.endsWith('/')
575
+ ? `${s.glob}probe.js`
576
+ : s.glob.replace(/\*\*/g, 'x/y').replace(/\*/g, 'z');
577
+ assert.ok(ppc.surfaceFor(sample), `${s.glob} no longer protects ${sample} — this change must never narrow`);
578
+ checked += 1;
579
+ }
580
+ assert.ok(checked >= 40, `only ${checked} surfaces walked — the registry read is not working`);
581
+ });
582
+
583
+ test('an UNprotected path is still unprotected — folding must not over-reach', () => {
584
+ for (const p of ['README.md', 'docs/notes.md', 'tests/example.mjs']) {
585
+ assert.equal(ppc.surfaceFor(p), null, `${p} must not become protected by normalisation`);
586
+ }
587
+ });
588
+
589
+ test('the matcher never uses a LOCALE-sensitive case fold (the Turkish-I hazard)', () => {
590
+ const src = fs.readFileSync(path.join(ROOT, 'src', 'bongos', 'permission-path-check.js'), 'utf8')
591
+ .replace(/\/\*[\s\S]*?\*\//g, '')
592
+ .replace(/\/\/[^\n]*/g, '');
593
+ assert.ok(src.length > 1000, `comment-stripping left only ${src.length} chars — the scan is reading nothing`);
594
+ assert.ok(!/toLocaleLowerCase|toLocaleUpperCase/.test(src),
595
+ 'toLocaleLowerCase("tr") maps I to dotless i — measured — so a Turkish locale would fold '
596
+ + 'two different paths together. Plain toLowerCase is locale-independent by specification '
597
+ + 'and is the correct primitive here; the ADR note warning against it does not apply to JS.');
598
+ assert.match(src, /toLowerCase\(\)/, 'and the fold must actually be applied');
599
+ assert.match(src, /normalize\('NFC'\)/, 'as must NFC composition');
600
+ });
601
+
602
+
603
+ // ---------------------------------------------------------------------------
604
+ // task 1002874, round 2 — the fold has to reach every PROTECTED matcher, not just
605
+ // the one in permission-path-check.
606
+ //
607
+ // Round 1 fixed matchProtected/surfaceFor and trusted the task description's claim
608
+ // that all eleven substrate consumers route through them. They do not.
609
+ // gate-review.js — the CI ESCALATE / HARD_FLOOR classifier — imported the RAW
610
+ // PROTECTED_GLOBS plus globToRegExp and compiled its own byte-exact regexes, so an
611
+ // uppercased spelling of a gate surface still walked past the auto-merge gate after
612
+ // the wall itself was fixed. Its isCanonicalPath() rejects non-NFC and non-ASCII
613
+ // but does not case-fold, so it never covered this.
614
+ // ---------------------------------------------------------------------------
615
+
616
+ test('compileGlobMatcher folds BOTH sides', () => {
617
+ const m = ppc.compileGlobMatcher(['src/bongos/auth.js', 'migrations/']);
618
+ assert.ok(m('src/bongos/auth.js'), 'exact still matches');
619
+ assert.ok(m('SRC/BONGOS/AUTH.JS'), 'case variant matches');
620
+ assert.ok(m('Migrations/001.sql'), 'a folded subtree prefix still matches');
621
+ assert.ok(!m('docs/readme.md'), 'and an unrelated path does not');
622
+ assert.ok(!m(''), 'empty is never a match');
623
+ assert.ok(!m(null), 'nor is a missing path');
624
+ });
625
+
626
+ test('gate-review classifies a CASE-VARIANT gate surface as hard-floor', () => {
627
+ const gr = require(path.join(ROOT, 'scripts', 'gds', 'gate-review.js'));
628
+ const literal = gr.HARD_FLOOR_GLOBS.find((g) => !g.includes('*') && !g.endsWith('/'));
629
+ assert.ok(literal, 'no literal hard-floor glob — this test is reading the wrong shape');
630
+ assert.ok(gr.matchesHardFloor(literal), 'the exact spelling must escalate (sanity)');
631
+ assert.ok(gr.matchesHardFloor(literal.toUpperCase()),
632
+ 'an uppercased gate surface must still escalate — otherwise CI auto-merge is bypassable '
633
+ + 'by re-spelling, which is the hole this task exists to close');
634
+ });
635
+
636
+ test('no consumer compiles a PROTECTED glob list byte-exact', () => {
637
+ // The drift guard. Both globToRegExp and the raw glob lists are exported, so a
638
+ // consumer can rebuild the byte-exact matcher by accident — which is exactly what
639
+ // gate-review had done. globToRegExp stays exported because ALLOW-lists
640
+ // legitimately need it: folding publish-manifest's PUBLISH_ALLOWLIST would widen
641
+ // what reaches the public OSS mirror, i.e. publish MORE. So the ban is narrow —
642
+ // pairing a PROTECTED list with the raw compiler in one file.
643
+ const dir = path.join(ROOT, 'scripts', 'gds');
644
+ const files = fs.readdirSync(dir).filter((f) => f.endsWith('.js'));
645
+ assert.ok(files.length > 20, `only ${files.length} scripts scanned — the sweep is not reading the CLI directory`);
646
+ const offenders = [];
647
+ for (const f of files) {
648
+ const src = fs.readFileSync(path.join(dir, f), 'utf8')
649
+ .replace(/\/\*[\s\S]*?\*\//g, '').replace(/\/\/[^\n]*/g, '');
650
+ const usesRawCompiler = /globToRegExp\s*\(/.test(src);
651
+ const usesProtectedList = /(PROTECTED_GLOBS|HARD_FLOOR_GLOBS)\s*\.\s*map/.test(src);
652
+ if (usesRawCompiler && usesProtectedList) offenders.push(f);
653
+ }
654
+ assert.deepEqual(offenders, [],
655
+ `these compile a protected-surface list with the raw byte-exact compiler; use `
656
+ + `compileGlobMatcher so the fold reaches them too: ${offenders.join(', ')}`);
657
+ });
@@ -76,7 +76,7 @@ await test('gradeByBuilder: quality-filtered, and pass_rate is NULL (not 0.000)
76
76
  const sql = (await captureSql(() => db.gradeByBuilder(30)))[0];
77
77
  assertQualityFiltered(sql, 'gradeByBuilder');
78
78
  // The old shape ROUND(COALESCE(AVG(...),0),3) fabricated a 0.000 fail-streak
79
- // for an all-outage window — the lars589 symptom. COALESCE must be gone from
79
+ // for an all-outage window — the example-owner symptom. COALESCE must be gone from
80
80
  // the pass_rate expression so it reads NULL ("no graded work") instead.
81
81
  assert.ok(!sql.includes('ROUND(COALESCE(AVG'), 'pass_rate must not coalesce an empty window to 0');
82
82
  assert.ok(/AVG\(CASE WHEN g\.passed THEN 1 ELSE 0 END\) FILTER/.test(sql), 'pass_rate must average quality rows only');
@@ -3,8 +3,8 @@
3
3
  // task 2122 (demo-audit fix B) — the scaffolded .claude/hooks must NOT hardcode a
4
4
  // founder-instance brand in their outbound HTTP User-Agent. Those hooks are copied
5
5
  // into a consumer instance by claude-materialize, whose rebrand maps domain HOSTS
6
- // (amazonprimea.com), config dirs, and env prefixes — but NOT a bare brand token
7
- // like `amazonprimea-gds-cli` (no TLD). So a branded UA there leaks the founder's
6
+ // (example.com), config dirs, and env prefixes — but NOT a bare brand token
7
+ // like `example-gds-cli` (no TLD). So a branded UA there leaks the founder's
8
8
  // host-brand into every scaffolded instance (criterion gcarry-prod-vanilla).
9
9
  //
10
10
  // Invariant: every `'User-Agent': '<value>'` literal in .claude/hooks/*.js uses the
package/tests/init.mjs CHANGED
@@ -27,8 +27,8 @@ function test(name, fn) {
27
27
  const fullSpec = () => init.normalizeSpec({
28
28
  identity: { productName: 'Cloud Bongos' },
29
29
  tagline: 'Building software is laying down a beat.',
30
- repo: { owner: 'lars589', name: 'cloud-bongos' },
31
- firstAdmin: 'lars589',
30
+ repo: { owner: 'example-owner', name: 'cloud-bongos' },
31
+ firstAdmin: 'example-owner',
32
32
  currency: { label: 'credits' },
33
33
  domains: { publicOrigin: 'http://localhost:3000' },
34
34
  modules: ['art-pipeline'],
@@ -48,8 +48,8 @@ test('buildBrandingConfig: lean overrides only (no theme block)', () => {
48
48
  const b = init.buildBrandingConfig(fullSpec());
49
49
  assert.equal(b.identity.productName, 'Cloud Bongos');
50
50
  assert.equal(b.identity.worldName, 'Cloud Bongos'); // defaults to productName
51
- assert.equal(b.repo.owner, 'lars589');
52
- assert.equal(b.firstAdmin, 'lars589');
51
+ assert.equal(b.repo.owner, 'example-owner');
52
+ assert.equal(b.firstAdmin, 'example-owner');
53
53
  assert.equal(b.currency.label, 'credits');
54
54
  assert.equal(b.envPrefix, 'BONGOS'); // canonical since task 1003703
55
55
  assert.equal(b.copy.tagline, 'Building software is laying down a beat.');
@@ -219,8 +219,8 @@ test('versionPayload: always sends an explicit, valid track', () => {
219
219
  // ---- provisioning arm (ADR 0111 §3, task 1946) ----
220
220
  const provSpec = (over = {}) => init.normalizeSpec({
221
221
  identity: { productName: 'Cloud Bongos' },
222
- repo: { owner: 'lars589', name: 'cloud-bongos' },
223
- firstAdmin: 'lars589',
222
+ repo: { owner: 'example-owner', name: 'cloud-bongos' },
223
+ firstAdmin: 'example-owner',
224
224
  version: { id: 'V1', name: 'V1', done_when: 'x' },
225
225
  provisioning: over,
226
226
  });
@@ -177,7 +177,7 @@ test('resolveDocsRoot: the explicit instance root when set, else coreRoot (no-op
177
177
  // Regression fixture for a bug that locked a builder out of re-authenticating.
178
178
  // Three call sites resolved the API base three different ways and none reached
179
179
  // the instance the builder was actually signed into:
180
- // * paste-token.js hardcoded 'https://amazonprimea.com' (a straggler the task
180
+ // * paste-token.js hardcoded 'https://example.com' (a straggler the task
181
181
  // 1002201 sweep missed), so a token minted by cloudbongos.com was verified
182
182
  // against the founder's host and rejected 401 — a VALID token, wrong host.
183
183
  // * reauth.js used the module-level branding default, so it printed a
@@ -14,10 +14,10 @@ const RANK_TIER = { xenos: 1, thetes: 2, metic: 3, archon: 4 };
14
14
 
15
15
  // A client-safe branding projection (the shape clientBranding() returns).
16
16
  const BRAND_OTB = {
17
- identity: { productName: 'Off the Boats', worldName: 'Amazonprimea', company: { name: 'Hermeslines' } },
17
+ identity: { productName: 'Example World', worldName: 'Example', company: { name: 'Hermeslines' } },
18
18
  currency: { label: 'drachmae', symbol: '' },
19
19
  theme: { colors: {}, fonts: { display: '', body: '', links: [] }, favicon: '', backdrop: '' },
20
- copy: { tagline: 'Straight off the boats', hallName: 'Builders’ Hall', notFound: 'Page not found.' },
20
+ copy: { tagline: 'Straight example world', hallName: 'Builders’ Hall', notFound: 'Page not found.' },
21
21
  rankLabels: { xenos: 'Xenos', thetes: 'Thetes', metic: 'Metic', archon: 'Archon' },
22
22
  // the per-project policy the platform pushes (task 1003140) — the settings read-back
23
23
  project: { platformVisibility: 'gated', joinability: 'invite_only' },
@@ -37,12 +37,12 @@ const MODULES_VANILLA = {
37
37
  enabled: { game: false, 'art-pipeline': false, discord: false, 'dev-box': false },
38
38
  disciplines: ['engineer'],
39
39
  };
40
- const REPO = { owner: 'lars589', repo: 'amazonprimea', branch: 'main', blob_base: 'x', tree_base: 'y' };
40
+ const REPO = { owner: 'example-owner', repo: 'example', branch: 'main', blob_base: 'x', tree_base: 'y' };
41
41
 
42
42
  test('manifest: schema id + headline name + embedded brand', () => {
43
43
  const m = buildInstanceManifest({ branding: BRAND_OTB, modules: MODULES_OTB, rankTier: RANK_TIER, repo: REPO, authConfigured: true, openEnrollment: false, devBoxEnabled: true });
44
44
  assert.equal(m.schema, MANIFEST_SCHEMA);
45
- assert.equal(m.name, 'Off the Boats');
45
+ assert.equal(m.name, 'Example World');
46
46
  assert.equal(m.brand, BRAND_OTB);
47
47
  assert.deepEqual(m.modules, MODULES_OTB);
48
48
  });
@@ -69,7 +69,7 @@ test('manifest: rank label falls back to the key when unlabelled', () => {
69
69
 
70
70
  test('manifest: repo projects to public clone coords; null on error', () => {
71
71
  const ok = buildInstanceManifest({ branding: BRAND_OTB, modules: MODULES_OTB, rankTier: RANK_TIER, repo: REPO, authConfigured: true, openEnrollment: false, devBoxEnabled: true });
72
- assert.deepEqual(ok.repo, { owner: 'lars589', repo: 'amazonprimea', branch: 'main', url: 'https://github.com/lars589/amazonprimea' });
72
+ assert.deepEqual(ok.repo, { owner: 'example-owner', repo: 'example', branch: 'main', url: 'https://github.com/example-owner/example' });
73
73
  const none = buildInstanceManifest({ branding: BRAND_VANILLA, modules: MODULES_VANILLA, rankTier: RANK_TIER, repo: { error: 'no_repo_info' }, authConfigured: false, openEnrollment: false, devBoxEnabled: false });
74
74
  assert.equal(none.repo, null);
75
75
  });
@@ -7,7 +7,7 @@
7
7
  //
8
8
  // The guard stops the CLI from silently borrowing a DIFFERENT instance's session
9
9
  // (the 2026-07-08 demo-session failure, where a fresh demo clone used the
10
- // founder's amazonprimea.com session and offered to write into the wrong live
10
+ // founder's example.com session and offered to write into the wrong live
11
11
  // backlog). Both helpers are deterministic with no DB/network/fs, so they
12
12
  // unit-test standalone. Run: node tests/instance_mismatch_guard.mjs
13
13
 
@@ -25,14 +25,14 @@ function test(name, fn) {
25
25
  }
26
26
 
27
27
  const DEMO = { domains: { publicOrigin: 'https://demo.cloudbongos.com' } };
28
- const OTB = { domains: { publicOrigin: 'https://amazonprimea.com' } };
28
+ const OTB = { domains: { publicOrigin: 'https://example.com' } };
29
29
  const noEnv = {}; // no <PREFIX>_API_BASE override in scope
30
30
  const branded = () => true; // simulate a checkout that HAS config/branding.json (a declared instance)
31
31
  const neutral = () => false; // simulate a NEUTRAL checkout (portable core — no config/branding.json)
32
32
 
33
33
  test('instanceOriginHost: extracts host, tolerates trailing slash', () => {
34
- assert.equal(cli.instanceOriginHost('https://amazonprimea.com'), 'amazonprimea.com');
35
- assert.equal(cli.instanceOriginHost('https://amazonprimea.com/'), 'amazonprimea.com');
34
+ assert.equal(cli.instanceOriginHost('https://example.com'), 'example.com');
35
+ assert.equal(cli.instanceOriginHost('https://example.com/'), 'example.com');
36
36
  assert.equal(cli.instanceOriginHost('https://demo.cloudbongos.com/api/gds'), 'demo.cloudbongos.com');
37
37
  });
38
38
 
@@ -43,20 +43,20 @@ test('instanceOriginHost: unparseable input → null (edge)', () => {
43
43
  });
44
44
 
45
45
  test('match: same-host session + branding → no mismatch (the OTB/normal case)', () => {
46
- const r = cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com' }, brand: OTB, env: noEnv, hasInstanceConfig: branded });
46
+ const r = cli.detectInstanceMismatch({ session: { api_base: 'https://example.com' }, brand: OTB, env: noEnv, hasInstanceConfig: branded });
47
47
  assert.equal(r.mismatch, false);
48
48
  });
49
49
 
50
50
  test('match: scheme/trailing-slash differences still match on host', () => {
51
- const r = cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com/' }, brand: OTB, env: noEnv, hasInstanceConfig: branded });
51
+ const r = cli.detectInstanceMismatch({ session: { api_base: 'https://example.com/' }, brand: OTB, env: noEnv, hasInstanceConfig: branded });
52
52
  assert.equal(r.mismatch, false);
53
53
  });
54
54
 
55
- test('mismatch: demo repo + founder amazonprimea session → REFUSE (the reported failure)', () => {
56
- const r = cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com' }, brand: DEMO, env: noEnv, hasInstanceConfig: branded });
55
+ test('mismatch: demo repo + founder example session → REFUSE (the reported failure)', () => {
56
+ const r = cli.detectInstanceMismatch({ session: { api_base: 'https://example.com' }, brand: DEMO, env: noEnv, hasInstanceConfig: branded });
57
57
  assert.equal(r.mismatch, true);
58
58
  assert.equal(r.expected, 'https://demo.cloudbongos.com');
59
- assert.equal(r.actual, 'https://amazonprimea.com');
59
+ assert.equal(r.actual, 'https://example.com');
60
60
  });
61
61
 
62
62
  test('mismatch: demo repo + cloudbongos.com session (sibling instance) → REFUSE', () => {
@@ -66,15 +66,15 @@ test('mismatch: demo repo + cloudbongos.com session (sibling instance) → REFUS
66
66
 
67
67
  test('env-override: an explicit *_API_BASE override wins (dev/staging) → no mismatch', () => {
68
68
  const r = cli.detectInstanceMismatch({
69
- session: { api_base: 'https://amazonprimea.com' }, brand: DEMO,
69
+ session: { api_base: 'https://example.com' }, brand: DEMO,
70
70
  env: { GDS_API_BASE: 'http://localhost:3000' },
71
71
  });
72
72
  assert.equal(r.mismatch, false);
73
73
  });
74
74
 
75
75
  test('no-branding: repo declares no publicOrigin → cannot assert a mismatch → no mismatch', () => {
76
- assert.equal(cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com' }, brand: {}, env: noEnv, hasInstanceConfig: branded }).mismatch, false);
77
- assert.equal(cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com' }, brand: { domains: {} }, env: noEnv, hasInstanceConfig: branded }).mismatch, false);
76
+ assert.equal(cli.detectInstanceMismatch({ session: { api_base: 'https://example.com' }, brand: {}, env: noEnv, hasInstanceConfig: branded }).mismatch, false);
77
+ assert.equal(cli.detectInstanceMismatch({ session: { api_base: 'https://example.com' }, brand: { domains: {} }, env: noEnv, hasInstanceConfig: branded }).mismatch, false);
78
78
  });
79
79
 
80
80
  test('NEUTRAL checkout (no config/branding.json) → trust the session, NO mismatch (task 1002399)', () => {
@@ -88,7 +88,7 @@ test('NEUTRAL checkout (no config/branding.json) → trust the session, NO misma
88
88
 
89
89
  test('neutral guard is precedence-safe: env override still wins even when neutral', () => {
90
90
  // env override short-circuits before the neutral check — order-independent.
91
- const r = cli.detectInstanceMismatch({ session: { api_base: 'https://amazonprimea.com' }, brand: DEMO, env: { GDS_API_BASE: 'http://localhost:3000' }, hasInstanceConfig: neutral });
91
+ const r = cli.detectInstanceMismatch({ session: { api_base: 'https://example.com' }, brand: DEMO, env: { GDS_API_BASE: 'http://localhost:3000' }, hasInstanceConfig: neutral });
92
92
  assert.equal(r.mismatch, false);
93
93
  });
94
94
 
@@ -0,0 +1,94 @@
1
+ // tests/leak_scan_allowlist.mjs
2
+ //
3
+ // Task 1003869 — the named exceptions to the prior-instance leak scan. The allowlist is
4
+ // a security carve-out, so what matters is not that it permits the right things but that
5
+ // it CANNOT permit the wrong ones: scoping is per (path, literal), a listed file does not
6
+ // become a free pass, and an entry that stops matching is reported rather than forgotten.
7
+ //
8
+ // Run: node tests/leak_scan_allowlist.mjs
9
+
10
+ import { strict as assert } from 'node:assert';
11
+ import { createRequire } from 'node:module';
12
+
13
+ const require = createRequire(import.meta.url);
14
+ const A = require('../scripts/gds/leak-scan-allowlist.js');
15
+ const { allowReason, partitionHits, unusedEntries, FILE_ALLOWLIST, WELL_KNOWN_PUBLIC_IPS } = A;
16
+ const { PRIOR_INSTANCE_FLOOR } = require('../scripts/gds/package-core.js');
17
+
18
+ // This test file is itself published, so it derives the literals it exercises rather
19
+ // than spelling them out — the same self-leak invariant the allowlist module holds.
20
+ const OWNER = PRIOR_INSTANCE_FLOOR.owners[0];
21
+ const TOKEN = PRIOR_INSTANCE_FLOOR.tokens[0];
22
+
23
+ let passed = 0, failed = 0;
24
+ function t(name, fn) {
25
+ try { fn(); passed++; console.log(` PASS ${name}`); }
26
+ catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
27
+ }
28
+
29
+ // ── every entry carries its reason ───────────────────────────────────────────────────
30
+ t('every entry names a path, at least one literal, and a substantive reason', () => {
31
+ for (const e of FILE_ALLOWLIST) {
32
+ assert.ok(e.path && typeof e.path === 'string', 'entry needs a path');
33
+ assert.ok(Array.isArray(e.classes) && e.classes.length > 0, `${e.path} needs classes`);
34
+ assert.ok(typeof e.reason === 'string' && e.reason.length > 40,
35
+ `${e.path} needs a reason that explains itself, not a label`);
36
+ }
37
+ for (const [ip, why] of Object.entries(WELL_KNOWN_PUBLIC_IPS)) {
38
+ assert.ok(typeof why === 'string' && why.length > 10, `${ip} needs a reason`);
39
+ }
40
+ });
41
+
42
+ // ── scoping: a listed file is NOT a free pass ────────────────────────────────────────
43
+ t('an allowlisted file still fails on a literal it was not listed for', () => {
44
+ // mirror-redact.js is listed for public-ip only. An owner login appearing there would
45
+ // be a real leak — the SELF-LEAK INVARIANT that file documents about itself.
46
+ assert.ok(allowReason('scripts/gds/mirror-redact.js', 'public-ip', '8.8.8.8'));
47
+ assert.equal(allowReason('scripts/gds/mirror-redact.js', `literal:${OWNER}`, OWNER), null,
48
+ 'a literal whose class is not named for this path must still fail');
49
+ });
50
+ t('an entry does not leak across to another path', () => {
51
+ // audit-authorship.sh may carry the owner login; an arbitrary script may not.
52
+ assert.ok(allowReason('scripts/gds/audit-authorship.sh', `literal:${OWNER}`, OWNER));
53
+ assert.equal(allowReason('scripts/gds/some-other-script.js', `literal:${OWNER}`, OWNER), null);
54
+ });
55
+ t('an unlisted file gets no exception at all', () => {
56
+ assert.equal(allowReason('src/bongos/routes/auth.js', `literal:${TOKEN}`, TOKEN), null);
57
+ assert.equal(allowReason('src/anything.js', 'public-ip', '203.0.113.9'), null,
58
+ 'an address that is not well-known is not covered anywhere');
59
+ });
60
+
61
+ // ── well-known addresses are global, and exact ───────────────────────────────────────
62
+ t('a well-known public address is covered in any file, but only by exact match', () => {
63
+ assert.ok(allowReason('tests/anything.mjs', 'public-ip', '8.8.8.8'));
64
+ assert.ok(allowReason('modules/whatever/x.js', 'public-ip', '1.1.1.1'));
65
+ // An address that is not on the well-known list is covered NOWHERE — the whole point of
66
+ // the sweep. Asserted with RFC 5737 documentation addresses rather than this instance's
67
+ // real ones: a test that pins "our droplet must not be allowlisted" by NAMING the droplet
68
+ // puts it straight back into the published trunk, which is the leak it is guarding against.
69
+ assert.equal(allowReason('tests/anything.mjs', 'public-ip', '198.51.100.7'), null);
70
+ assert.equal(allowReason('tests/anything.mjs', 'public-ip', '192.0.2.99'), null);
71
+ });
72
+
73
+ // ── partition + staleness ────────────────────────────────────────────────────────────
74
+ t('partitionHits separates covered hits from real ones and attaches the reason', () => {
75
+ const hits = [
76
+ { path: 'tests/mirror_redact.mjs', label: 'public-ip', sample: '8.8.8.8' },
77
+ { path: 'src/bongos/routes/auth.js', label: `literal:${TOKEN}`, sample: TOKEN },
78
+ ];
79
+ const { allowed, remaining } = partitionHits(hits);
80
+ assert.equal(allowed.length, 1);
81
+ assert.ok(allowed[0].reason.length > 10, 'a covered hit carries the reason it was covered');
82
+ assert.equal(remaining.length, 1);
83
+ assert.equal(remaining[0].path, 'src/bongos/routes/auth.js');
84
+ });
85
+ t('unusedEntries reports an entry that has stopped matching', () => {
86
+ // No hits at all → every file entry is stale, which is the signal to prune.
87
+ assert.ok(unusedEntries([]).length > 0);
88
+ // A hit that covers one entry removes exactly that one from the stale list.
89
+ const stale = unusedEntries([{ path: 'scripts/gds/mirror-redact.js', label: 'public-ip', sample: '8.8.8.8' }]);
90
+ assert.ok(!stale.some((s) => s.path === 'scripts/gds/mirror-redact.js' && s.literal === 'public-ip'));
91
+ });
92
+
93
+ console.log(`\n${passed} passed, ${failed} failed`);
94
+ process.exit(failed ? 1 : 0);
@@ -72,7 +72,7 @@ function printRoots({ cwd, initCwd } = {}) {
72
72
  }
73
73
 
74
74
  // A synthetic consumer: a dir with a bongos.config.json pointing at itself, exactly
75
- // as the post-split amazonprimea repo carries (bongos.config.json { instanceRoot: "." }).
75
+ // as the post-split example repo carries (bongos.config.json { instanceRoot: "." }).
76
76
  function makeConsumer() {
77
77
  const dir = mkFixture('r89-consumer-');
78
78
  writeFileSync(path.join(dir, 'bongos.config.json'), JSON.stringify({ instanceRoot: '.' }));
@@ -249,7 +249,7 @@ t('the pre-fix unquoted loop now fails loudly instead of silently skipping', ()
249
249
  // ==========================================================================
250
250
  // WHICH DATABASE does migrate target? (task 1002755)
251
251
  //
252
- // scripts/migrate.sh:52 used to read `DB="${PGDATABASE:-amazonprimea}"` — one host instance's
252
+ // scripts/migrate.sh:52 used to read `DB="${PGDATABASE:-example}"` — one host instance's
253
253
  // database name, baked into a script the core ships to EVERY instance. With no PGDATABASE in the
254
254
  // environment, a co-hosted box silently aimed at a stranger's database and everywhere else died
255
255
  // with a confusing "database ... does not exist" — after the caller had already moved its version
@@ -314,7 +314,7 @@ t('an instance that names no database is REFUSED, never defaulted', () => {
314
314
  assert.match(r.stderr, /cannot determine which database/i);
315
315
  assert.match(r.stderr, /Refusing to guess/i);
316
316
  // the regression itself: it must not reach for another instance's database
317
- assert.doesNotMatch(`${r.stdout}${r.stderr}`, /amazonprimea/i);
317
+ assert.doesNotMatch(`${r.stdout}${r.stderr}`, /example/i);
318
318
  });
319
319
 
320
320
  t('--print-migrations stays DB-free — a dry run must not require a database name', () => {
@@ -333,7 +333,7 @@ t('migrate.sh hardcodes no instance database name', () => {
333
333
  const code = src.split(/\r?\n/).filter((l) => !/^\s*#/.test(l)).join('\n');
334
334
  assert.doesNotMatch(code, /PGDATABASE:-\s*[A-Za-z]/,
335
335
  'PGDATABASE must have no literal fallback — resolve from the branding pack instead');
336
- assert.doesNotMatch(code, /amazonprimea/i, 'no instance database name in executable lines');
336
+ assert.doesNotMatch(code, /example/i, 'no instance database name in executable lines');
337
337
  });
338
338
 
339
339
  console.log(`\nmigrate_root_resolution: ${passed} passed, ${failed} failed`);
@@ -104,12 +104,12 @@ t('isPublicRoutableIPv4 classifier boundaries', () => {
104
104
 
105
105
  // ── IPv6 floor: global unicast redacted, loopback/link-local/ULA kept ─────────────────
106
106
  t('public IPv6 (the droplet) redacted; loopback/link-local/ULA kept', () => {
107
- const out = redactText('v6 2604:a880:800:14:0:2:ee66:b000 keep fe80::1 fc00::5 ::1', rules);
107
+ const out = redactText('v6 2606:4700:4700::1111 keep fe80::1 fc00::5 ::1', rules);
108
108
  assert.ok(!out.includes('2604:a880'), `public IPv6 leaked: ${out}`);
109
109
  assert.ok(out.includes('fe80::1') && out.includes('fc00::5') && out.includes('::1'), out);
110
110
  });
111
111
  t('isPublicRoutableIPv6 + a "12:34:56" timestamp is NOT treated as an IP', () => {
112
- assert.equal(isPublicRoutableIPv6('2604:a880:800:14:0:2:ee66:b000'), true);
112
+ assert.equal(isPublicRoutableIPv6('2606:4700:4700::1111'), true);
113
113
  assert.equal(isPublicRoutableIPv6('fe80::1'), false);
114
114
  assert.equal(isPublicRoutableIPv6('fc00::5'), false);
115
115
  assert.equal(isPublicRoutableIPv6('::1'), false);
@@ -127,14 +127,38 @@ t('reserved ::/8 is NOT a public IP — degenerate shorthand in binary is not a
127
127
  }
128
128
  // ...and the narrowing did NOT blunt the gate: real global unicast still fires, in
129
129
  // both the detector and the redactor.
130
- for (const s of ['2000::1', '2001:db8::1', '2606:4700:4700::1111', '3fff::1']) {
130
+ for (const s of ['2000::1', '2606:4700:4700::1111', '3fff::1']) {
131
131
  assert.equal(isPublicRoutableIPv6(s), true, `${s} is a real public address and must still be flagged`);
132
132
  }
133
+ // 2001:db8::/32 is RESERVED FOR DOCUMENTATION (RFC 3849) — the IPv6 analogue of the
134
+ // RFC 5737 TEST-NET ranges v4 already exempts, and for the same reason: it is the
135
+ // address an example is SUPPOSED to use, nothing is reachable there, and flagging it
136
+ // only punishes docs for being written correctly (task 1003869). It was listed above
137
+ // as "a real public address" until then, which RFC 3849 says it is not.
138
+ for (const s of ['2001:db8::1', '2001:0db8:85a3:0000:0000:8a2e:0370:7334']) {
139
+ assert.equal(isPublicRoutableIPv6(s), false, `${s} is the RFC 3849 doc range and must not be flagged`);
140
+ }
133
141
  assert.equal(firstPublicIP('sprite bytes :: more bytes'), null, 'binary-ish shorthand is not reported');
134
142
  assert.equal(firstPublicIP('origin 2606:4700:4700::1111'), '2606:4700:4700::1111');
135
143
  assert.ok(!redactText('host 2606:4700:4700::1111', []).includes('2606:4700'), 'a real public IPv6 is still redacted');
136
144
  });
137
145
 
146
+ // ── candidate guards: things that LOOK like an address but are not one ───────────────
147
+ t('a leading-zero octet is packed numeric data, not an address (task 1003869)', () => {
148
+ // The committed GitHub logo path contains "…5.47 7.59.4.07.5…". The candidate regex
149
+ // reads 7.59.4.07 as a dotted quad, and it flagged ten phantom public-ip leaks across
150
+ // the design mocks and the landing page. No notation writes a host with a leading-zero
151
+ // octet ("07" is octal), so the guard costs nothing on a genuinely leaked address.
152
+ assert.equal(firstPublicIP('M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.5-.17'), null);
153
+ assert.equal(firstPublicIP('host 7.59.4.07'), null);
154
+ assert.equal(firstPublicIP('host 7.59.4.7'), '7.59.4.7', 'the same quad without the zero IS an address');
155
+ });
156
+ t('RFC 2544 benchmarking space 198.18/15 is not instance topology', () => {
157
+ assert.equal(isPublicRoutableIPv4(198, 18, 0, 1), false);
158
+ assert.equal(isPublicRoutableIPv4(198, 19, 255, 254), false);
159
+ assert.equal(isPublicRoutableIPv4(198, 20, 0, 1), true, 'the neighbouring /15 is ordinary public space');
160
+ });
161
+
138
162
  // ── the DETECTOR is stricter than redaction ───────────────────────────────────────────
139
163
  t('findLeaks catches a raw literal substring a bounded rule would miss', () => {
140
164
  // "azoltanb" has no word boundary around zoltan; a \bzoltan\b rule misses it, the
@@ -143,7 +167,7 @@ t('findLeaks catches a raw literal substring a bounded rule would miss', () => {
143
167
  assert.ok(findLeaks('inline widgetco reference', literals).length > 0);
144
168
  });
145
169
  t('findLeaks is clean on fully-redacted output (fixed point)', () => {
146
- const dirty = 'https://widgetco.com by zoltan at 8.8.8.8 and 2604:a880:800:14:0:2:ee66:b000';
170
+ const dirty = 'https://widgetco.com by zoltan at 8.8.8.8 and 2606:4700:4700::1111';
147
171
  const clean = redactText(dirty, rules);
148
172
  assert.deepEqual(findLeaks(clean, literals), [], `residual leaks: ${JSON.stringify(findLeaks(clean, literals))}`);
149
173
  });
@@ -121,7 +121,7 @@ test('buildCatalog: keeps the DECLARED manifest fields beside the display credit
121
121
 
122
122
  test('buildCatalog: source and provenance are independent axes', () => {
123
123
  const rows = catalog.buildCatalog({
124
- loaded: [loadedIn(CORE, 'provisioning', { origin: 'Off the Boats', author: 'Off the Boats' })],
124
+ loaded: [loadedIn(CORE, 'provisioning', { origin: 'Example World', author: 'Example World' })],
125
125
  coreRoot: CORE, instanceRoot: INST,
126
126
  ownProjectName: 'Mercury',
127
127
  });
@@ -156,7 +156,7 @@ test('buildCatalog: survives a manifest with nothing but the required keys', ()
156
156
  const sample = () => catalog.buildCatalog({
157
157
  loaded: [
158
158
  loadedIn(CORE, 'economy', { description: 'drachmae and credits' }),
159
- loadedIn(CORE, 'provisioning', { author: 'Off the Boats', origin: 'Off the Boats', license: 'AGPL-3.0' }),
159
+ loadedIn(CORE, 'provisioning', { author: 'Example World', origin: 'Example World', license: 'AGPL-3.0' }),
160
160
  loadedIn(INST, 'game', { description: 'the world' }),
161
161
  ],
162
162
  enabled: { economy: true, game: true },
@@ -174,7 +174,7 @@ test('searchCatalog: matches key, description, author, origin and licence; empty
174
174
  assert.equal(catalog.searchCatalog(rows, '').length, 3);
175
175
  assert.equal(catalog.searchCatalog(rows, ' ').length, 3);
176
176
  assert.deepEqual(catalog.searchCatalog(rows, 'DRACHMAE').map((r) => r.key), ['economy'], 'case-insensitive, over description');
177
- assert.deepEqual(catalog.searchCatalog(rows, 'off the boats').map((r) => r.key), ['provisioning'], 'over the credit');
177
+ assert.deepEqual(catalog.searchCatalog(rows, 'example world').map((r) => r.key), ['provisioning'], 'over the credit');
178
178
  assert.deepEqual(catalog.searchCatalog(rows, 'agpl').map((r) => r.key), ['provisioning'], 'over the licence');
179
179
  assert.deepEqual(catalog.searchCatalog(rows, 'nothing-matches-this'), []);
180
180
  });
@@ -202,7 +202,7 @@ test('formatCatalog: renders every row with its credit, and marks the inferred o
202
202
  assert.match(out, /2 in the core catalog \(1 enabled\) · 1 built here · 3 total/);
203
203
  assert.match(out, /\[x\]\s+economy/, 'an enabled module is marked [x]');
204
204
  assert.match(out, /\[ \]\s+provisioning/, 'a disabled module is marked [ ]');
205
- assert.match(out, /Off the Boats/, 'a declared credit is shown');
205
+ assert.match(out, /Example World/, 'a declared credit is shown');
206
206
  assert.match(out, /credit not declared in module\.json/, 'the inferred-credit footnote appears when one is shown');
207
207
  });
208
208
 
@@ -227,7 +227,7 @@ test('formatCatalog: a search with no hits says so instead of printing an empty
227
227
 
228
228
  test('cmdList: --json emits the rows + summary, and honours --catalog/--search', () => {
229
229
  const lines = [];
230
- const code = mod.cmdList(['--json', '--catalog', '--search', 'off the boats'], {
230
+ const code = mod.cmdList(['--json', '--catalog', '--search', 'example world'], {
231
231
  log: (s) => lines.push(s),
232
232
  gather: () => ({ rows: sample(), skipped: [], errors: [], core: '1.19.0' }),
233
233
  });
@@ -59,14 +59,14 @@ await test('createModuleSubmission() INSERTs, jsonb-casts manifest/files/sign_of
59
59
  const precheckPassedAt = new Date('2026-07-08T00:00:00.000Z');
60
60
  nextRows = [{
61
61
  id: 1, module_key: 'widget', submitted_by: 42, manifest, sign_off: signOff,
62
- precheck_passed_at: precheckPassedAt, source_repo: 'lars589/amazonprimea',
62
+ precheck_passed_at: precheckPassedAt, source_repo: 'example-owner/example',
63
63
  status: 'pending', reviewed_by: null, reviewed_at: null, review_notes: null,
64
64
  submitted_at: '2026-07-08T00:00:01.000Z',
65
65
  }];
66
66
 
67
67
  const row = await moduleSubmissions.createModuleSubmission({
68
68
  moduleKey: 'widget', submittedBy: 42, manifest, files, signOff, precheckPassedAt,
69
- sourceRepo: 'lars589/amazonprimea',
69
+ sourceRepo: 'example-owner/example',
70
70
  });
71
71
 
72
72
  const { text, params } = lastCall();
@@ -83,7 +83,7 @@ await test('createModuleSubmission() INSERTs, jsonb-casts manifest/files/sign_of
83
83
  assert.equal(params[3], JSON.stringify(files));
84
84
  assert.equal(params[4], JSON.stringify(signOff));
85
85
  assert.equal(params[5], precheckPassedAt);
86
- assert.equal(params[6], 'lars589/amazonprimea');
86
+ assert.equal(params[6], 'example-owner/example');
87
87
 
88
88
  assert.equal(row.id, 1);
89
89
  assert.equal(row.status, 'pending');
@@ -585,7 +585,7 @@ t('scanArtifactForLeaks: flags a prior-instance literal in any shipped file', ()
585
585
 
586
586
  t('scanArtifactForLeaks: flags a public IP but not a private/localhost one', () => {
587
587
  const r = scanArtifactForLeaks([
588
- { path: 'a.js', content: 'host = 104.236.254.243\n' }, // public → flagged
588
+ { path: 'a.js', content: 'host = 1.2.3.4\n' }, // public → flagged
589
589
  { path: 'b.js', content: 'host = 127.0.0.1; lan = 10.0.0.5\n' }, // localhost + private → not
590
590
  ]);
591
591
  const byPath = Object.fromEntries(r.literalHits.map((h) => [h.path, h.label]));