@bongos/core 1.19.707 → 1.19.708

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,11 +2,11 @@
2
2
  "artifact": "bongos-core",
3
3
  "manifest_schema": 1,
4
4
  "generator": "scripts/gds/package-core.js",
5
- "core_version": "1.19.707",
6
- "core_contract": "1.19.707",
7
- "source_commit": "81f4406107cc23fffd1cd396faeba854cfab702e",
5
+ "core_version": "1.19.708",
6
+ "core_contract": "1.19.708",
7
+ "source_commit": "42f201a980e11b8b417c2afa527230ed1ab05775",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-13T06:08:10.442Z",
9
+ "built_at": "2026-09-13T06:14:54.451Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 477,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 2639,
20
- "tree_sha256": "b1f44a9ac5209bb3aef35739af94352c50892f50161818d2e805cdcb9fb92687",
20
+ "tree_sha256": "369223629e32da5858cc92a00ab2643eaa169ca59d1d89d6ab77ab8c50e3fd57",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -2802,7 +2802,7 @@
2802
2802
  {
2803
2803
  "path": "docs/module-api-changelog.md",
2804
2804
  "mode": "0000644",
2805
- "sha256": "59033d82daa55e0e2bb8f357d076e5e0c36b6d708ec764ed28946248da86a1c6"
2805
+ "sha256": "fd622c24f29995f2c8ebdd272cf5784f05285bbafc6c3da490308ed5e1730ba7"
2806
2806
  },
2807
2807
  {
2808
2808
  "path": "docs/modules-contract.md",
@@ -7782,12 +7782,12 @@
7782
7782
  {
7783
7783
  "path": "package-lock.json",
7784
7784
  "mode": "0000644",
7785
- "sha256": "0beecf6840022e259986573a8a0b444f9d4848dc0758f009b83e346f54769a1f"
7785
+ "sha256": "4f9b97401aebd998dd23bf3ec95a333fd6c596c0ea5551dc02dc6e863ad92742"
7786
7786
  },
7787
7787
  {
7788
7788
  "path": "package.json",
7789
7789
  "mode": "0000644",
7790
- "sha256": "bed665bc57c56a76e572401a1baed5fd08bfcca74a1a32e2dc744b6af2f79399"
7790
+ "sha256": "9002e7fc0a70168d56042d71c7905aa045b541dbc36d61e88180a8dfb1e0f559"
7791
7791
  },
7792
7792
  {
7793
7793
  "path": "public-docs/index.html",
@@ -7982,7 +7982,7 @@
7982
7982
  {
7983
7983
  "path": "scripts/gds/box-infra.js",
7984
7984
  "mode": "0000644",
7985
- "sha256": "7890dee972f792b633a86d5ac9e6195bafdfc6c197195b8ac3f00c4a0f80d5c0"
7985
+ "sha256": "431691aed02a415c619dc0ba33106ac1e832e539260eff5f526debebe2d8ffff"
7986
7986
  },
7987
7987
  {
7988
7988
  "path": "scripts/gds/box-sync.js",
@@ -9567,7 +9567,7 @@
9567
9567
  {
9568
9568
  "path": "src/module-api.js",
9569
9569
  "mode": "0000644",
9570
- "sha256": "6bf49d3b72dbd08d6ede9514f8381efcb22d45602ed5f5de84893c1181b38dce"
9570
+ "sha256": "98205e89563b71f2e6ddbe44a9639464bdc589c20f3f0a8de12a2b968ac06569"
9571
9571
  },
9572
9572
  {
9573
9573
  "path": "src/module-loader/catalog.js",
@@ -10012,7 +10012,7 @@
10012
10012
  {
10013
10013
  "path": "tests/box_infra_resolve.mjs",
10014
10014
  "mode": "0000644",
10015
- "sha256": "cf261fa549f36d47ee42343bac2a297b132638aedf03beb8f521370b0c45c0e3"
10015
+ "sha256": "fde24a8c273a098c89bbbce6c006fa4400448c9522b93707f5cd3f4fb358c515"
10016
10016
  },
10017
10017
  {
10018
10018
  "path": "tests/box_onboard.mjs",
@@ -1873,5 +1873,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1873
1873
  landed since 1.19.705 with no explicit bump. run 34740247460. (task 1002620)
1874
1874
  1.19.707 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1875
1875
  landed since 1.19.706 with no explicit bump. run 34741980536. (task 1002620)
1876
+ 1.19.708 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1877
+ landed since 1.19.707 with no explicit bump. run 34742245823. (task 1002620)
1876
1878
  ---------------------------------------------------------------------------
1877
1879
  ```
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.707",
3
+ "version": "1.19.708",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.707",
9
+ "version": "1.19.708",
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.707",
3
+ "version": "1.19.708",
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",
@@ -216,6 +216,9 @@ function readCloudInit({ authorizedKeysBlock = '', boxEnv = '', gdsSession = '',
216
216
  // below — they are minted per-provision, not read from infra/. A missing inlined
217
217
  // file is COLLECTED and fails loud after the render (ADR 0150) — a half-wired box
218
218
  // (that component silently never boots) is a bug, not something to warn past.
219
+ //
220
+ // Every name passed to fileGzB64 below is INSTANCE-owned and deliberately absent
221
+ // from the neutral core's own infra/ — see infra/README.md (ADR 0150).
219
222
  const missingInfra = [];
220
223
  const fileGzB64 = (name) => {
221
224
  try {
@@ -267,6 +270,36 @@ function readCloudInit({ authorizedKeysBlock = '', boxEnv = '', gdsSession = '',
267
270
  + `— a box would boot half-wired (ADR 0150). Fix the instance infra/ before provisioning.`,
268
271
  );
269
272
  }
273
+ // ADR 0150 prong B named this escalation and never implemented it: "assert no
274
+ // __…_B64__ placeholders survive the render, so a *partial* infra/ also surfaces
275
+ // rather than half-wiring". The missingInfra check above only catches files THIS
276
+ // file knows to ask for. It cannot catch the other direction — an instance
277
+ // template carrying a token box-infra.js does not substitute. That renders a
278
+ // cloud-init with the literal token in it, and cloud-init happily writes the
279
+ // garbage as a file: the box boots half-wired, silently, which is the one
280
+ // outcome ADR 0150 exists to prevent.
281
+ //
282
+ // The stakes are not hypothetical for one of them. __BUILDER_AUTHORIZED_KEYS_B64__
283
+ // is the baked SSH key block; if a template misspells it, the substitution never
284
+ // happens and the box comes up with a garbage authorized_keys — permanently
285
+ // unreachable over SSH, exactly the failure task 1003635 was filed about (it
286
+ // guessed the wrong mechanism, but the outcome it named was reachable this way).
287
+ //
288
+ // Same pattern the happy-path test has always asserted, now enforced in the code
289
+ // rather than only in the test.
290
+ // The pattern is the placeholder CONVENTION, so this assumes a template never
291
+ // carries a literal __UPPER_SNAKE__ it means to keep. Nothing in this tree does,
292
+ // and a false positive fails loud and legibly (it names the token) rather than
293
+ // shipping a bad box — the safe direction to be wrong in. An instance that ever
294
+ // needs a literal one should escape it in the template, not weaken this check.
295
+ const survivors = [...new Set(rendered.match(/__[A-Z0-9_]+__/g) || [])];
296
+ if (survivors.length) {
297
+ throw new Error(
298
+ `box cloud-init under ${infraDir} left ${survivors.length} placeholder(s) unsubstituted: `
299
+ + `${survivors.join(', ')} — box-infra.js does not know these tokens, so the box would `
300
+ + `boot half-wired (ADR 0150). Reconcile the instance template with this renderer.`,
301
+ );
302
+ }
270
303
  return rendered;
271
304
  }
272
305
 
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.707'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.708'; // 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');
@@ -17,8 +17,12 @@ import { createRequire } from 'node:module';
17
17
  import fs from 'node:fs';
18
18
  import os from 'node:os';
19
19
  import path from 'node:path';
20
+ import { fileURLToPath } from 'node:url';
20
21
  import { makeRunner } from './helpers.mjs';
21
22
 
23
+ // This repo's root — the boundary tests at the bottom read the REAL tree.
24
+ const REPO_ROOT = path.join(path.dirname(fileURLToPath(import.meta.url)), '..');
25
+
22
26
  const require = createRequire(import.meta.url);
23
27
  const box = require('../scripts/gds/box.js');
24
28
 
@@ -153,5 +157,90 @@ await test('readCloudInit renders a non-empty cloud-init with no leftover __PLAC
153
157
  assert.ok(!/__[A-Z0-9_]+__/.test(out), 'no unsubstituted __PLACEHOLDER__ tokens remain');
154
158
  });
155
159
 
160
+ // ===========================================================================
161
+ // An UNKNOWN placeholder half-wires the box (task 1003635, ADR 0150 prong B)
162
+ //
163
+ // missingInfra only catches files this renderer knows to ask for. The other
164
+ // direction — an instance template carrying a token box-infra.js never
165
+ // substitutes — used to render straight through, leaving the literal token in
166
+ // the cloud-init for cloud-init to write out as a file. ADR 0150 named the
167
+ // assertion as an escalation and it was never implemented.
168
+ // ===========================================================================
169
+
170
+ await test('an UNKNOWN __TOKEN__ in the instance template is refused, not rendered through', () => {
171
+ const { infra } = makeInfra();
172
+ fs.appendFileSync(path.join(infra, TEMPLATE), '\n# __SOME_FUTURE_THING_B64__\n');
173
+ assert.throws(
174
+ () => box.readCloudInit({ infraDir: infra }),
175
+ (err) => /__SOME_FUTURE_THING_B64__/.test(err.message) && /placeholder|half-wired|ADR 0150/i.test(err.message),
176
+ 'an unsubstituted placeholder must fail loud — rendering it through writes garbage onto the box',
177
+ );
178
+ });
179
+
180
+ await test('a misspelled AUTHORIZED_KEYS token cannot ship a permanently SSH-unreachable box', () => {
181
+ // The stakes case. A template that spells the key block even slightly wrong
182
+ // gets no substitution, so the box boots with a garbage authorized_keys and
183
+ // nobody can SSH in — the outcome task 1003635 reported, by the mechanism it
184
+ // did not find. It must be refused before DigitalOcean is touched.
185
+ const { infra } = makeInfra();
186
+ fs.appendFileSync(path.join(infra, TEMPLATE), '\n# __BUILDER_AUTHORIZED_KEY_B64__\n');
187
+ assert.throws(
188
+ () => box.readCloudInit({ infraDir: infra, authorizedKeysBlock: 'ssh-ed25519 AAAA' }),
189
+ /__BUILDER_AUTHORIZED_KEY_B64__/,
190
+ );
191
+ });
192
+
193
+ await test('the happy path still renders — the assertion does not fire on a correct template', () => {
194
+ const { infra } = makeInfra();
195
+ const out = box.readCloudInit({
196
+ infraDir: infra, authorizedKeysBlock: 'ssh-ed25519 AAAA', boxEnv: 'X=1', gdsSession: '{"t":1}',
197
+ });
198
+ assert.ok(out && out.length > 0, 'a correct template must still render');
199
+ });
200
+
201
+ // ===========================================================================
202
+ // The core / instance boundary (task 1003635)
203
+ //
204
+ // The absence of the cloud-init set from the core's own infra/ was filed once as
205
+ // a P1 outage ("a dev box becomes permanently SSH-unreachable"). It is not one —
206
+ // ADR 0150 says the neutral core ships no box cloud-init, and the two throws
207
+ // above are what make a missing one legible instead of dangerous. These pin that
208
+ // boundary against the REAL tree so the next reader gets a test telling them so.
209
+ // ===========================================================================
210
+
211
+ await test('the INLINED list is exactly what box-infra.js actually asks fileGzB64 for', () => {
212
+ // The list above says "kept in sync with box.js's fileGzB64 calls" — by hand.
213
+ // Derive it instead, so adding a 10th inlined file cannot leave these tests
214
+ // silently proving less than they claim.
215
+ const SRC = fs.readFileSync(path.join(REPO_ROOT, 'scripts/gds/box-infra.js'), 'utf8');
216
+ const called = [...SRC.matchAll(/fileGzB64\('([^']+)'\)/g)].map((m) => m[1]);
217
+ assert.ok(called.length > 0, 'found no fileGzB64 calls — did box-infra.js move or get renamed?');
218
+ assert.deepEqual([...new Set(called)].sort(), [...INLINED].sort(),
219
+ 'the INLINED fixture list has drifted from box-infra.js — the happy-path test would stop covering every inlined file');
220
+ });
221
+
222
+ await test('the neutral core ships NO box cloud-init — that is ADR 0150, not a missing file', () => {
223
+ const coreInfra = path.join(REPO_ROOT, 'infra');
224
+ assert.ok(!fs.existsSync(path.join(coreInfra, TEMPLATE)),
225
+ `the core now ships infra/${TEMPLATE}. ADR 0150 says it must not ("The neutral core still ships no infra/") — the cloud-init is instance-owned. If that decision changed, amend ADR 0150 and this test together.`);
226
+ for (const name of INLINED) {
227
+ assert.ok(!fs.existsSync(path.join(coreInfra, name)),
228
+ `infra/${name} is a cloud-init asset and belongs to the host instance, not the core (ADR 0150)`);
229
+ }
230
+ });
231
+
232
+ await test("core infra/ carries only the CLONE-RIDE scripts, which is why it looks half-empty", () => {
233
+ // The other population: these run on the box out of /workspace/infra/, arriving
234
+ // with the cloned source rather than through cloud-init. Their presence beside
235
+ // nine absences is the thing that reads as "files are missing" — infra/README.md
236
+ // exists to answer that, so it is required to stay.
237
+ const coreInfra = path.join(REPO_ROOT, 'infra');
238
+ for (const name of ['box-heartbeat.sh', 'box-report-host-keys.sh', 'box-report-terminal.sh', 'box-report-version.sh']) {
239
+ assert.ok(fs.existsSync(path.join(coreInfra, name)), `infra/${name} rides the clone and must stay in the core`);
240
+ }
241
+ assert.ok(fs.existsSync(path.join(coreInfra, 'README.md')),
242
+ 'infra/README.md explains the two populations — without it the nine absences read as breakage again (task 1003635)');
243
+ });
244
+
156
245
  for (const d of tmps) { try { fs.rmSync(d, { recursive: true, force: true }); } catch { /* best-effort */ } }
157
246
  summary();