@bongos/core 1.19.666 → 1.19.668

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/.bongos-core.json CHANGED
@@ -2,22 +2,22 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.666",
6
- "core_contract": "1.19.666",
7
- "source_commit": "3fc1c7e12b4d5fa3451f618fb8a971a5da710db7",
5
+ "core_version": "1.19.668",
6
+ "core_contract": "1.19.668",
7
+ "source_commit": "7ef8e22537f40e46f6f068d2479fbbb853f91ac6",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-11T05:45:20.037Z",
9
+ "built_at": "2026-09-11T15:53:04.954Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 473,
13
13
  "agent_docs_stubbed": 24,
14
- "functional_verbatim": 2116,
14
+ "functional_verbatim": 2117,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2613,
20
- "tree_sha256": "18d8514d20465a8efc1d55968fb7382c7fef86fac6d286475bb414b792238821",
19
+ "file_count": 2614,
20
+ "tree_sha256": "f753736a9456c435a166c5d07d41ab343a26cf1d0ccbd1ddf50fe23325cb3bd3",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -2787,7 +2787,7 @@
2787
2787
  {
2788
2788
  "path": "docs/module-api-changelog.md",
2789
2789
  "mode": "0000644",
2790
- "sha256": "1a4f6805f1c7cc669b21c253e57d753e5e37c8a4d0b84ea27ad959be2b63c4dc"
2790
+ "sha256": "6eba5a3ec525e945d04f4665e23d6b3731df16547f7b51593c589ff2569c682c"
2791
2791
  },
2792
2792
  {
2793
2793
  "path": "docs/modules-contract.md",
@@ -4212,7 +4212,7 @@
4212
4212
  {
4213
4213
  "path": "modules/dev-box/app/src/session-store.js",
4214
4214
  "mode": "0000644",
4215
- "sha256": "faa5cca9f30740588731b9132ab1681536c90600d7bf86a9e0107785e5b5fed5"
4215
+ "sha256": "9fefb99a647184879d2960eda360b475f5ea14d6f7c78d46c4de67f2b9909baa"
4216
4216
  },
4217
4217
  {
4218
4218
  "path": "modules/dev-box/app/src/ssh-setup.js",
@@ -5402,7 +5402,7 @@
5402
5402
  {
5403
5403
  "path": "modules/hall-ui/public/shell.js",
5404
5404
  "mode": "0000644",
5405
- "sha256": "09c16d780e9e4027d7b8c9279e1acaae38f01360ed9af67cb7f0b98f0a494766"
5405
+ "sha256": "f0f6462bd7e536b73162c758db37d30ceec6b5e4ec74815df778d85978d7eb5e"
5406
5406
  },
5407
5407
  {
5408
5408
  "path": "modules/hall-ui/public/ship.wav",
@@ -6982,7 +6982,7 @@
6982
6982
  {
6983
6983
  "path": "modules/public-landing/public/index.html",
6984
6984
  "mode": "0000644",
6985
- "sha256": "c6ad936d8f4340a16f7faea30ec0b97b7a1c526a9a991d1e1c6ff1833ddb57ce"
6985
+ "sha256": "ea0c3be6fcddc0e93414ee3ce247c0aee57d74c285b0ecd2dc13095118447d81"
6986
6986
  },
6987
6987
  {
6988
6988
  "path": "modules/public-landing/public/index.probes.json",
@@ -7012,7 +7012,7 @@
7012
7012
  {
7013
7013
  "path": "modules/public-landing/public/projects.html",
7014
7014
  "mode": "0000644",
7015
- "sha256": "eca7a7b580db8a794f5e0e17c8bfbb106529f14bf43c6e627d8f32e1dc9d6a53"
7015
+ "sha256": "864b6ee7a8b1866196d6595914f614e388a51c2a160fd86f454ab4a32a4740d5"
7016
7016
  },
7017
7017
  {
7018
7018
  "path": "modules/public-landing/public/projects.probes.json",
@@ -7082,7 +7082,7 @@
7082
7082
  {
7083
7083
  "path": "modules/security/artifact-scan/detectors/credentials.js",
7084
7084
  "mode": "0000644",
7085
- "sha256": "ac793c3caa1b047770dc5729777881fa9a9c0e799eb46799fda038ed98338934"
7085
+ "sha256": "6ef164669b8947143ecc7095443ae2500b43ce61dd240d480598850c787920ef"
7086
7086
  },
7087
7087
  {
7088
7088
  "path": "modules/security/artifact-scan/detectors/dependencies.js",
@@ -7757,12 +7757,12 @@
7757
7757
  {
7758
7758
  "path": "package-lock.json",
7759
7759
  "mode": "0000644",
7760
- "sha256": "67316339ae447a8943fa26ed89e3974debbd19f41ca5d7082a35a7960632ca75"
7760
+ "sha256": "2b109c02111e9aff72bc2a9b6a1a85805c7544cca1e68399ceaf5f8de8df0f47"
7761
7761
  },
7762
7762
  {
7763
7763
  "path": "package.json",
7764
7764
  "mode": "0000644",
7765
- "sha256": "b54f7ae81efd2b4d6c154240adce30ba2a0e4b4356050680704276d4fd8f9f8a"
7765
+ "sha256": "41264c98f8188d3443d6195d223de91f9eeed86ce21ed880e0b0a138e72669ff"
7766
7766
  },
7767
7767
  {
7768
7768
  "path": "public-docs/index.html",
@@ -7947,7 +7947,7 @@
7947
7947
  {
7948
7948
  "path": "scripts/gds/box-infra.js",
7949
7949
  "mode": "0000644",
7950
- "sha256": "811545b6769947c5399f4be52782e90c1a6c2e628e72d7751266d2c7dafb62c3"
7950
+ "sha256": "7890dee972f792b633a86d5ac9e6195bafdfc6c197195b8ac3f00c4a0f80d5c0"
7951
7951
  },
7952
7952
  {
7953
7953
  "path": "scripts/gds/box-sync.js",
@@ -8032,7 +8032,7 @@
8032
8032
  {
8033
8033
  "path": "scripts/gds/cli-lib.js",
8034
8034
  "mode": "0000644",
8035
- "sha256": "c3f5d95c3e586ea711f4e0cef245da9f8106bf4c803aa4c7b2d0025657562680"
8035
+ "sha256": "24b6e3f2f99f7e584692d58fdd50d94e2b9e58905213307d71e3590858fafd22"
8036
8036
  },
8037
8037
  {
8038
8038
  "path": "scripts/gds/client-baseurl-guard.js",
@@ -8177,7 +8177,7 @@
8177
8177
  {
8178
8178
  "path": "scripts/gds/fetch-art-key.js",
8179
8179
  "mode": "0000644",
8180
- "sha256": "7fa67e4bcb4d28300db3793993133912d34cd5c0af49f0570c9def445deba1e2"
8180
+ "sha256": "9fb05213e80f27ac02cb40c6ceb95a7c92ca81b0a531d9cd67ba09b497017d6d"
8181
8181
  },
8182
8182
  {
8183
8183
  "path": "scripts/gds/fetch-sound-prefs.js",
@@ -8352,7 +8352,7 @@
8352
8352
  {
8353
8353
  "path": "scripts/gds/init.js",
8354
8354
  "mode": "0000644",
8355
- "sha256": "0e6f775304038af80d3ca3b060f174ec9fc9e39f4d4eead2bc1c1587845099bd"
8355
+ "sha256": "390df0043001a825bbd4709df767e8ef21089743b799fc9c638a5509e8222ae8"
8356
8356
  },
8357
8357
  {
8358
8358
  "path": "scripts/gds/install-git-hooks.js",
@@ -8527,7 +8527,7 @@
8527
8527
  {
8528
8528
  "path": "scripts/gds/paste-token.js",
8529
8529
  "mode": "0000644",
8530
- "sha256": "1a39d097cfe41343303b69cef6f08cfd52b9d9973b1e359a18d5168d14013e89"
8530
+ "sha256": "9036bdd526ed13d1518b0f12289a68d86e0078a093d22607f7f5377b6759969c"
8531
8531
  },
8532
8532
  {
8533
8533
  "path": "scripts/gds/portability-smoke-art.sh",
@@ -8537,7 +8537,7 @@
8537
8537
  {
8538
8538
  "path": "scripts/gds/portability-smoke-memory.sh",
8539
8539
  "mode": "0000644",
8540
- "sha256": "bec9e23a2b8092c6a2b1bb5edaed48900485e7296a3d7e683cce215ad7ec7ab9"
8540
+ "sha256": "6822594619d66509430fa42f51abb4a53a612274e232ec227502d2b2d51f3417"
8541
8541
  },
8542
8542
  {
8543
8543
  "path": "scripts/gds/preflight.js",
@@ -8872,7 +8872,7 @@
8872
8872
  {
8873
8873
  "path": "scripts/gds/setup.js",
8874
8874
  "mode": "0000644",
8875
- "sha256": "36b5c59af3cde0398e432db37f1cd645aab08ea70b308a5e53671a4fce06f7fe"
8875
+ "sha256": "15243de5b4bde57313c601bf96bd2a10bb86dedceb18cb0a31495b998d1ca835"
8876
8876
  },
8877
8877
  {
8878
8878
  "path": "scripts/gds/shell.js",
@@ -9022,7 +9022,7 @@
9022
9022
  {
9023
9023
  "path": "scripts/gds/smoke-write.sh",
9024
9024
  "mode": "0000644",
9025
- "sha256": "5468e6fdf5330fa2a67aa9a027d747efdf09908f9d676c567f2e324fd55a5155"
9025
+ "sha256": "cfa2f05cd72aad3975a683e334e32341c4cc10e34802091e693fe26f2e49781f"
9026
9026
  },
9027
9027
  {
9028
9028
  "path": "scripts/gds/spark.js",
@@ -9137,7 +9137,7 @@
9137
9137
  {
9138
9138
  "path": "scripts/hall-preview/refresh-fixtures.js",
9139
9139
  "mode": "0000644",
9140
- "sha256": "1f7f42a4c3213a97d6b2844c87fa88afd95c23a7d4897f1e5d0cac375a12fa93"
9140
+ "sha256": "3faeb959f81f32e23b11c9ab623df7899bae647c07837bca54c946e7807ef0f6"
9141
9141
  },
9142
9142
  {
9143
9143
  "path": "scripts/hall-preview/server.js",
@@ -9257,7 +9257,7 @@
9257
9257
  {
9258
9258
  "path": "src/bongos/auth.js",
9259
9259
  "mode": "0000644",
9260
- "sha256": "88e734e42d8fd15ba24d75cafcc611de90e16362200e198e9a9bc4ee825bfbaf"
9260
+ "sha256": "4ba2511e982a50e82cc7e600ad16905dc1765b89a6b11eedcec2a67cd86a19da"
9261
9261
  },
9262
9262
  {
9263
9263
  "path": "src/bongos/cascade-dispatch.js",
@@ -9327,7 +9327,7 @@
9327
9327
  {
9328
9328
  "path": "src/bongos/middleware/rate-limit.js",
9329
9329
  "mode": "0000644",
9330
- "sha256": "7a4a49df59dd3754fec468f1833514982b6e57c460dc531d5f6605cfe68d196f"
9330
+ "sha256": "16a4ec3664e0ae3ff2c38e75a04dacd1011d19b7a53631739ac39147578e5534"
9331
9331
  },
9332
9332
  {
9333
9333
  "path": "src/bongos/module-scope-map.js",
@@ -9357,7 +9357,7 @@
9357
9357
  {
9358
9358
  "path": "src/bongos/platform-visibility-gate.js",
9359
9359
  "mode": "0000644",
9360
- "sha256": "eea15ebe44e9450f2d62040c239828008e8953ea5ee465085d5f0e8e63fe6233"
9360
+ "sha256": "b09f1c0bcbb066ae80cbeebad730db8a8665dd077c3f2026c3b3d78298fdd866"
9361
9361
  },
9362
9362
  {
9363
9363
  "path": "src/bongos/pool.js",
@@ -9412,7 +9412,7 @@
9412
9412
  {
9413
9413
  "path": "src/bongos/routes/auth.js",
9414
9414
  "mode": "0000644",
9415
- "sha256": "cfed94a4ce1c1c6ef20d33cc12149d3b669e822e1b4affb06a22de576c8f7f12"
9415
+ "sha256": "511383c09afd0a89b568b071303a41f57dc20c5bd6284624230bf9e23056b8f5"
9416
9416
  },
9417
9417
  {
9418
9418
  "path": "src/bongos/routes/backup.js",
@@ -9517,12 +9517,12 @@
9517
9517
  {
9518
9518
  "path": "src/instance-config.js",
9519
9519
  "mode": "0000644",
9520
- "sha256": "08b655540d7297e827abcdfb576c37089c188d88b64a3b8a731e61c99d3c78d1"
9520
+ "sha256": "9338dde4ceeae35c208f2d434422642ce6851b3a2196c420463b85a3b23d2dc7"
9521
9521
  },
9522
9522
  {
9523
9523
  "path": "src/module-api.js",
9524
9524
  "mode": "0000644",
9525
- "sha256": "ae4d5ac8a868e23e7f9a456173658719bdbd44e4ed231d60fcd3fe9646c81d47"
9525
+ "sha256": "43b74af9de322914ac0f43a8cd4adacc1de90fb874692744450ff18beeaa67e7"
9526
9526
  },
9527
9527
  {
9528
9528
  "path": "src/module-loader/catalog.js",
@@ -10142,7 +10142,7 @@
10142
10142
  {
10143
10143
  "path": "tests/cli_sessions.mjs",
10144
10144
  "mode": "0000644",
10145
- "sha256": "ab1ee394c03eccadee0958ea38595e1f4e221146b593559e3474c9573d81ecf7"
10145
+ "sha256": "060821b27429a98d7120525efd8b40cdeb2f845c579db0f01b4b5f604b0122ca"
10146
10146
  },
10147
10147
  {
10148
10148
  "path": "tests/cli_surface.mjs",
@@ -11452,12 +11452,12 @@
11452
11452
  {
11453
11453
  "path": "tests/landing_page.mjs",
11454
11454
  "mode": "0000644",
11455
- "sha256": "c526200d83ab8a2a5c3b571012827ccf793c46be4dda4e974fee9af6262935db"
11455
+ "sha256": "1e37768b7408632f83f0e118da0226d09324999909e7962fc7f27268d4290f20"
11456
11456
  },
11457
11457
  {
11458
11458
  "path": "tests/lib_sh_resolution.mjs",
11459
11459
  "mode": "0000644",
11460
- "sha256": "97630ec5029469ec99c6a87160822f319833857f12a79e42b4a465e362836ef0"
11460
+ "sha256": "fdefb4971d75dcf6ab1000323211a9fbe732508ae1a0a28c36b8087383ae797e"
11461
11461
  },
11462
11462
  {
11463
11463
  "path": "tests/lifecycle-card.mjs",
@@ -11867,7 +11867,7 @@
11867
11867
  {
11868
11868
  "path": "tests/platform_visibility_gate.mjs",
11869
11869
  "mode": "0000644",
11870
- "sha256": "2dc7a56caeababd5bf249e968e4353f8c738aef459947fde15c7c511640c13aa"
11870
+ "sha256": "7a4a3677e25bd55a6ebb64130f724f030f0b57d0ccc07172de3860cbeb4a66d7"
11871
11871
  },
11872
11872
  {
11873
11873
  "path": "tests/post_login_landing.mjs",
@@ -12499,6 +12499,11 @@
12499
12499
  "mode": "0000644",
12500
12500
  "sha256": "1beb0554d1e29b853d54d17e4345ca7c62f1cd34c72fe6a20b9e2d712e7f2dce"
12501
12501
  },
12502
+ {
12503
+ "path": "tests/session_rename_fallback.mjs",
12504
+ "mode": "0000644",
12505
+ "sha256": "02a61cc6a9949276e88e25d65e75a752cea36fccc1f0e7cec8bf7e44c1dfc93f"
12506
+ },
12502
12507
  {
12503
12508
  "path": "tests/session_reward_on_land.mjs",
12504
12509
  "mode": "0000644",
@@ -12527,7 +12532,7 @@
12527
12532
  {
12528
12533
  "path": "tests/setup_device_flow_fallback.mjs",
12529
12534
  "mode": "0000644",
12530
- "sha256": "0a7c2f4a0ee050573040a88c6a246c773e7b13074115df4b4d715ab99c903a9c"
12535
+ "sha256": "f047b209ec3b0ea2fcffbee7c3b36d8cf01bb18e19cfcfa9d32267db672d834d"
12531
12536
  },
12532
12537
  {
12533
12538
  "path": "tests/setup_smoke.mjs",
@@ -1791,5 +1791,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
1791
1791
  landed since 1.19.664 with no explicit bump. run 34560552542. (task 1002620)
1792
1792
  1.19.666 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1793
1793
  landed since 1.19.665 with no explicit bump. run 34567142386. (task 1002620)
1794
+ 1.19.667 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1795
+ landed since 1.19.666 with no explicit bump. run 34576878372. (task 1002620)
1796
+ 1.19.668 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1797
+ landed since 1.19.667 with no explicit bump. run 34618700494. (task 1002620)
1794
1798
  ---------------------------------------------------------------------------
1795
1799
  ```
@@ -1,6 +1,6 @@
1
1
  // devbox-app/src/session-store.js — the app shares the GDS CLI's session file.
2
2
  //
3
- // ~/.config/<instance>/gds-session.json is the same file scripts/gds/cli-lib.js and
3
+ // ~/.config/<instance>/bongos-session.json is the same file scripts/gds/cli-lib.js and
4
4
  // paste-token.js read/write: { token, builder, api_base, ... }. Sharing it is
5
5
  // a deliberate UX decision (ADR 0045): pairing the app also signs in every
6
6
  // /builder-* skill on this machine, and a builder who already ran
@@ -16,12 +16,21 @@ const brand = require('./brand');
16
16
  // The instance's CLI config dir (branding configDir) — so the app shares the
17
17
  // exact session file the /builder-* CLI uses on this machine.
18
18
  const DIR = path.join(os.homedir(), '.config', brand.CONFIG_DIR);
19
- const FILE = path.join(DIR, 'gds-session.json');
20
- // Read-side legacy name only (pre-GDS rename) never written.
21
- const FILE_LEGACY = path.join(DIR, 'pms-session.json');
19
+ const FILE = path.join(DIR, 'bongos-session.json');
20
+ // Read-side legacy names only accepted on read, never written to, so the app
21
+ // keeps working on a machine whose CLI has not yet re-authenticated. Newest
22
+ // first, mirroring SESSION_FILENAMES in src/instance-config.js; this app ships as
23
+ // its own bundle (own brand module, no core imports), so the list is duplicated
24
+ // rather than imported, and pinned against the real one by
25
+ // tests/session_rename_fallback.mjs (task 1003704).
26
+ const FILES_LEGACY = [
27
+ path.join(DIR, 'gds-session.json'),
28
+ path.join(DIR, 'pms-session.json'),
29
+ ];
30
+ const FILES_READ = [FILE, ...FILES_LEGACY];
22
31
 
23
32
  function read() {
24
- for (const f of [FILE, FILE_LEGACY]) {
33
+ for (const f of FILES_READ) {
25
34
  try {
26
35
  const data = JSON.parse(fs.readFileSync(f, 'utf8'));
27
36
  if (data && typeof data.token === 'string' && data.token) return data;
@@ -48,11 +57,26 @@ function write({ token, builder, apiBase }) {
48
57
 
49
58
  // Sign-out: drop ONLY our credential fields; preserve everything else
50
59
  // (gemini_api_key etc.) so the app never destroys CLI-adjacent config.
60
+ //
61
+ // Strips EVERY accepted filename, not just the current one. read() falls through
62
+ // to an older name when the current file carries no token, so clearing FILE alone
63
+ // would leave a live token in a superseded file and the very next read would sign
64
+ // the builder straight back in. That was survivable while the only legacy name was
65
+ // the long-dead `pms-session.json`; with `gds-session.json` now on the read list
66
+ // it is the common case on every machine that has not re-authenticated yet
67
+ // (task 1003704).
51
68
  function clear() {
52
- const existing = read();
53
- if (!existing) return;
54
- const { token: _t, builder: _b, ...rest } = existing;
55
- fs.writeFileSync(FILE, `${JSON.stringify(rest, null, 2)}\n`, { mode: 0o600 });
69
+ for (const target of FILES_READ) {
70
+ let existing = null;
71
+ try {
72
+ existing = JSON.parse(fs.readFileSync(target, 'utf8'));
73
+ } catch {
74
+ continue; // missing or unparsable → nothing to strip
75
+ }
76
+ if (!existing || typeof existing !== 'object') continue;
77
+ const { token: _t, builder: _b, ...rest } = existing;
78
+ fs.writeFileSync(target, `${JSON.stringify(rest, null, 2)}\n`, { mode: 0o600 });
79
+ }
56
80
  }
57
81
 
58
82
  module.exports = { read, write, clear, FILE };
@@ -867,7 +867,7 @@
867
867
  // subdomains; a Max-Age=0 only matches the cookie whose Domain attribute
868
868
  // it names, so the host-only expire alone leaves the apex cookie live).
869
869
  var apex = location.hostname.split('.').slice(-2).join('.');
870
- ['gds_session', 'pms_session'].forEach(function (name) {
870
+ ['bongos_session', 'gds_session', 'pms_session'].forEach(function (name) {
871
871
  document.cookie = name + '=; Max-Age=0; path=/';
872
872
  document.cookie = name + '=; Max-Age=0; path=/; Domain=.' + apex;
873
873
  });
@@ -946,7 +946,7 @@ composition A; landing composition v3, picked by the owner 2026-08-27. No roll,
946
946
  function doLogout() {
947
947
  var finish = function () {
948
948
  var apex = location.hostname.split('.').slice(-2).join('.');
949
- ['gds_session', 'pms_session'].forEach(function (name) {
949
+ ['bongos_session', 'gds_session', 'pms_session'].forEach(function (name) {
950
950
  document.cookie = name + '=; Max-Age=0; path=/';
951
951
  document.cookie = name + '=; Max-Age=0; path=/; Domain=.' + apex;
952
952
  });
@@ -7215,7 +7215,7 @@ summary{min-height:24px;padding:3px 0;}
7215
7215
  function doLogout() {
7216
7216
  var finish = function () {
7217
7217
  var apex = location.hostname.split('.').slice(-2).join('.');
7218
- ['gds_session', 'pms_session'].forEach(function (name) {
7218
+ ['bongos_session', 'gds_session', 'pms_session'].forEach(function (name) {
7219
7219
  document.cookie = name + '=; Max-Age=0; path=/';
7220
7220
  document.cookie = name + '=; Max-Age=0; path=/; Domain=.' + apex;
7221
7221
  });
@@ -2,7 +2,7 @@
2
2
  // credential stores (task 1002544).
3
3
  //
4
4
  // The pattern list is CURATED AND NAMED, not clever: each entry is a specific
5
- // place secrets live — including our own ~/.config/otb/gds-session.json and
5
+ // place secrets live — including our own ~/.config/otb/bongos-session.json and
6
6
  // the Windows stores — spelled the way code spells it. A hit means "this
7
7
  // artifact's text names a credential store", nothing more; whether it READS it
8
8
  // is runtime behavior a static floor cannot see, and the finding says so.
@@ -10,7 +10,7 @@
10
10
  // Patterns are tiered by SIGNAL, because the co-occurrence critical (floor.js)
11
11
  // must not cry wolf:
12
12
  // FILE — a concrete on-disk secret store path (.aws/credentials, id_rsa,
13
- // gds-session.json). Co-located with a network sink this is the
13
+ // bongos-session.json). Co-located with a network sink this is the
14
14
  // strong read-then-send shape, so ONLY file-class hits arm the
15
15
  // co-occurrence critical.
16
16
  // ENV — an environment-variable NAME (GITHUB_TOKEN, NPM_TOKEN). Ordinary
@@ -29,7 +29,12 @@ const SEP = String.raw`[\\/]+`;
29
29
  // line (ReDoS) and would hang the floor before any report is persisted; a
30
30
  // bounded `[^\\/\n]*` cannot.
31
31
  const CREDENTIAL_PATTERNS = Object.freeze([
32
- ['our own GDS CLI session token', new RegExp(String.raw`gds-session\.json|\.config${SEP}otb`, 'i'), 'file'],
32
+ // EVERY session filename, not just the current one: the file is renamed forward
33
+ // (task 1003704) while the old names stay readable, so an artifact reading ANY of
34
+ // them is reaching for a live credential. Matching only the newest name would have
35
+ // let a reader of gds-session.json through; matching only the oldest, a reader of
36
+ // bongos-session.json. Keep this list in step with SESSION_FILENAMES.
37
+ ['our own Bongos CLI session token', new RegExp(String.raw`(?:bongos|gds|pms)-session\.json|\.config${SEP}otb`, 'i'), 'file'],
33
38
  ['SSH private key', new RegExp(String.raw`\.ssh${SEP}[^\\/\n]*(?:_rsa|_ed25519|_ecdsa)|\bid_rsa\b|\bid_ed25519\b|\bid_ecdsa\b`, 'i'), 'file'],
34
39
  ['AWS credentials file', new RegExp(String.raw`\.aws${SEP}credentials`, 'i'), 'file'],
35
40
  ['netrc', new RegExp(String.raw`(?:^|[^\w.])\.?_?netrc\b`, 'i'), 'file'],
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.666",
3
+ "version": "1.19.668",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.666",
9
+ "version": "1.19.668",
10
10
  "license": "AGPL-3.0-or-later",
11
11
  "dependencies": {
12
12
  "express": "^4.21.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.666",
3
+ "version": "1.19.668",
4
4
  "description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
5
5
  "license": "AGPL-3.0-or-later",
6
6
  "main": "src/platform-server.js",
@@ -238,7 +238,7 @@ function readCloudInit({ authorizedKeysBlock = '', boxEnv = '', gdsSession = '',
238
238
  // /etc/otb/box.env — empty by default (quick tunnel); the named-tunnel
239
239
  // connector token + stable hostname when BOX_NAMED_TUNNEL is on (#771).
240
240
  .replace(/__BOX_ENV_B64__/g, Buffer.from(boxEnv || '', 'utf8').toString('base64'))
241
- // /root/.config/otb/gds-session.json — the builder's GDS session, minted at
241
+ // /root/.config/otb/bongos-session.json — the builder's Bongos session, minted at
242
242
  // provision so box-source-fetch (#600) can authenticate on FIRST boot and
243
243
  // clone the rank-scoped repo. Without it the box never clones (the #818
244
244
  // chicken-and-egg: the session normally comes from /builder-setup, which
@@ -17,17 +17,32 @@ const os = require('node:os');
17
17
  const { execSync } = require('node:child_process');
18
18
  const ic = require('../../src/instance-config');
19
19
 
20
- // Session token path the WRITE target is the configured instance dir
21
- // (~/.config/<configDir>/gds-session.json; OTB → ~/.config/otb, unchanged). On
22
- // READ we try that file across every config read dir (configured + legacy otb),
23
- // then the legacy `pms-session.json` filename across the same dirs so a
24
- // pre-rename session, or one written by a differently-namespaced instance, still
25
- // resolves (R61 / task 1200). os.homedir() keeps it per-user on any machine.
26
- const SESSION_PATH = ic.configPath('gds-session.json');
27
- const SESSION_READ_PATHS = [
28
- ...ic.configReadPaths('gds-session.json'),
29
- ...ic.configReadPaths('pms-session.json'),
30
- ];
20
+ // Session token filenames, NEWEST FIRST. The WRITE target is the configured
21
+ // instance dir (~/.config/<configDir>/bongos-session.json; OTB → ~/.config/otb,
22
+ // unchanged). On READ we try each name across every config read dir (configured +
23
+ // legacy otb) so a pre-rename session, or one written by a differently-
24
+ // namespaced instance, still resolves (R61 / task 1200). os.homedir() keeps it
25
+ // per-user on any machine.
26
+ //
27
+ // WHY THE OLD NAMES STAY READABLE. This file is on disk on every builder machine
28
+ // and every live dev box. Renaming it with no fallback signs all of them out at
29
+ // once and every /builder-* command dies with 'no Bongos session'. So a read that
30
+ // resolves through a superseded name MIGRATES forward (see loadSession), and the
31
+ // old file is deliberately LEFT IN PLACE — a builder may roll back to an older
32
+ // CLI, which can only see the old name. Part 4 (task 1003706) deletes it behind a
33
+ // test of its absence. (task 1003704)
34
+ //
35
+ // Order is FILENAME-major, not directory-major: the newest name found in ANY read
36
+ // dir beats an older name in the configured dir. That is the precedence a rename
37
+ // wants, and it is the order the two-name version of this list already used.
38
+ // The list itself lives in instance-config (the lowest module that reads the
39
+ // file, and the only one cli-lib and paste-token.js can both import).
40
+ // Destructured, not read off `ic` as a member: knip cannot trace a namespace-only
41
+ // property access on this module and reports the export dead (the same blind spot
42
+ // task 1003703 closed for two other instance-config exports).
43
+ const { SESSION_FILENAMES } = require('../../src/instance-config');
44
+ const SESSION_PATH = ic.configPath(SESSION_FILENAMES[0]);
45
+ const SESSION_READ_PATHS = SESSION_FILENAMES.flatMap((n) => ic.configReadPaths(n));
31
46
  // The API base every CLI call targets, resolved ONCE through the single source of
32
47
  // truth in instance-config: <PREFIX>_API_BASE (then legacy GDS_/OTB_/PMS_) → the
33
48
  // persisted session's api_base → THIS instance's publicOrigin from the branding
@@ -218,14 +233,36 @@ async function readSessionFile(p) {
218
233
  }
219
234
  }
220
235
 
236
+ // Copy a session that resolved through a SUPERSEDED path forward to SESSION_PATH,
237
+ // so the next command reads the new name directly instead of walking the fallback
238
+ // list forever. The old file is left in place on purpose (see SESSION_FILENAMES).
239
+ //
240
+ // BEST-EFFORT BY DESIGN: a read-only home, a full disk, or a permissions problem
241
+ // must never turn a working loadSession() into a failing command. The caller
242
+ // already holds a valid session; failing to write the copy changes nothing about
243
+ // this invocation. So every error is swallowed and the session is still returned.
244
+ async function migrateSessionFile(session) {
245
+ try {
246
+ await fsp.mkdir(path.dirname(SESSION_PATH), { recursive: true });
247
+ await fsp.writeFile(SESSION_PATH, JSON.stringify(session, null, 2), { mode: 0o600 });
248
+ return true;
249
+ } catch (_) {
250
+ return false;
251
+ }
252
+ }
253
+
221
254
  async function loadSession() {
222
- // Try each read path in priority order (configured dir's gds-session.json,
223
- // legacy otb dir, then the legacy pms-session.json filename). We do NOT migrate
224
- // the file on read — it gets written at SESSION_PATH next time the user re-auths
225
- // or saveSession runs.
255
+ // Try each read path in priority order (configured dir's bongos-session.json,
256
+ // legacy otb dir, then each superseded filename across the same dirs). A hit on
257
+ // anything OTHER than SESSION_PATH is migrated forward SESSION_READ_PATHS[0]
258
+ // IS SESSION_PATH (configReadDirs puts the configured dir first), so the common
259
+ // case writes nothing.
226
260
  for (const p of SESSION_READ_PATHS) {
227
261
  const s = await readSessionFile(p);
228
- if (s) return s;
262
+ if (s) {
263
+ if (p !== SESSION_PATH) await migrateSessionFile(s);
264
+ return s;
265
+ }
229
266
  }
230
267
  return null;
231
268
  }
@@ -1137,6 +1174,8 @@ module.exports = {
1137
1174
  rewardPolicy,
1138
1175
  costPlusOnlyNote,
1139
1176
  SESSION_PATH,
1177
+ SESSION_FILENAMES,
1178
+ SESSION_READ_PATHS,
1140
1179
  loadSession,
1141
1180
  loadSessionSync,
1142
1181
  saveSession,
@@ -5,7 +5,7 @@
5
5
  // The art pipeline (modules/art-pipeline/pipeline/gen_api.py) runs LOCALLY and can't call the API
6
6
  // per generation, so SessionStart runs this once: GET /api/gds/me/art-key and,
7
7
  // based on the builder's live rank, write or remove the `shared_gemini_api_key`
8
- // field in ~/.config/otb/gds-session.json. gen_api.py reads that field as a
8
+ // field in ~/.config/otb/bongos-session.json. gen_api.py reads that field as a
9
9
  // fallback BELOW the builder's own key — so own key always wins, and a newcomer
10
10
  // with no own key falls back to the shared one we pay for.
11
11
  //
@@ -254,7 +254,7 @@ function buildBrandingConfig(spec) {
254
254
  // Every instance gets its OWN session/config dir (task 1002626). Without
255
255
  // this, instance-config.js falls back to the shared 'cloudbongos' dir, so
256
256
  // every un-branded instance on a machine reads/writes the SAME
257
- // ~/.config/cloudbongos/gds-session.json — signing in to one silently
257
+ // ~/.config/cloudbongos/bongos-session.json — signing in to one silently
258
258
  // evicts the CLI session of every other, including the hub. Same slug
259
259
  // family as the package name + provisioning slug.
260
260
  configDir: spec.configDir ? String(spec.configDir).trim() : slugify(productName, 'instance'),
@@ -2,7 +2,7 @@
2
2
  // scripts/gds/paste-token.js — V3.R91 / #401.
3
3
  //
4
4
  // Accept a CLI bearer minted by the builders' hall (POST /api/gds/auth/cli-token/issue)
5
- // and write it into ~/.config/otb/gds-session.json. Preserves any existing
5
+ // and write it into ~/.config/otb/bongos-session.json. Preserves any existing
6
6
  // fields (notably gemini_api_key registered via /builder-setup) so a token
7
7
  // paste never silently un-registers a builder's Gemini key.
8
8
  //
@@ -24,10 +24,13 @@
24
24
  const fs = require('node:fs');
25
25
  const path = require('node:path');
26
26
  const ic = require('../../src/instance-config');
27
+ // Destructured for the same reason as cli-lib: a namespace-only `ic.X` read is
28
+ // invisible to knip, which then calls the export dead code.
29
+ const { SESSION_FILENAMES, readSessionConfigSync } = require('../../src/instance-config');
27
30
 
28
31
  // WRITE the session to the configured instance dir (OTB → ~/.config/otb,
29
32
  // unchanged; a fresh instance → its neutral dir). R61 / task 1200.
30
- const SESSION_PATH = ic.configPath('gds-session.json');
33
+ const SESSION_PATH = ic.configPath(SESSION_FILENAMES[0]);
31
34
  // env → the EXISTING session's api_base → this instance's branding default.
32
35
  // On a RE-auth a session file already exists, and its api_base is the best signal
33
36
  // of which instance the builder is on — this file used to hardcode the founder
@@ -91,9 +94,11 @@ async function main() {
91
94
  // way, treat as a fresh write.
92
95
  let existing = {};
93
96
  try {
94
- // Read across config dirs (configured + legacy otb) so a session written the
95
- // old way still has its fields preserved on the next paste.
96
- const raw = ic.readConfigFileSync('gds-session.json');
97
+ // Read across config dirs (configured + legacy otb) AND across every accepted
98
+ // filename, so a session written the old way still has its fields preserved on
99
+ // the next paste. This is the re-auth path: a miss here does not fail loudly,
100
+ // it silently drops the builder's gemini_api_key (task 1003704).
101
+ const raw = readSessionConfigSync();
97
102
  if (raw) existing = JSON.parse(raw);
98
103
  } catch (_) {
99
104
  /* fresh session; nothing to merge */
@@ -95,7 +95,7 @@ if [ -z "$REMOTE" ]; then bad "could not resolve origin remote for fresh-clone t
95
95
  # --- 2. the fresh clone leaks NO secrets / NO builder memory ------------
96
96
  LEAKS=0
97
97
  CFG_DIR=$(gds_node "process.stdout.write(require('../../src/instance-config').configDirName())" 2>/dev/null) || CFG_DIR=""
98
- for p in ".env.local" "spaces.env" ".config/${CFG_DIR:-otb}/gds-session.json" "etc/${CFG_DIR:-otb}"; do
98
+ for p in ".env.local" "spaces.env" ".config/${CFG_DIR:-otb}/bongos-session.json" ".config/${CFG_DIR:-otb}/gds-session.json" "etc/${CFG_DIR:-otb}"; do
99
99
  if [ -e "$TMP/clone/$p" ]; then echo " leak: $p present in clone"; LEAKS=$((LEAKS+1)); fi
100
100
  done
101
101
  # builder_memory is server-side only — no memory dir should ship in-repo