@bongos/core 1.19.264 → 1.19.266

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.264",
6
- "core_contract": "1.19.264",
7
- "source_commit": "bf5cc3668f703f2110626798f6c78e6728d46192",
5
+ "core_version": "1.19.266",
6
+ "core_contract": "1.19.266",
7
+ "source_commit": "d91db4e58ad64674e65d64d611241e88e02188ac",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-20T17:10:47.719Z",
9
+ "built_at": "2026-08-20T17:59:23.193Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 318,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1705,
20
- "tree_sha256": "355cac3de0571ef24bf2a01412c36cef27c3150840aa9f02b8f672a56e7caceb",
20
+ "tree_sha256": "22cc9e757ec02b637af6ec28f6d00b5daa91a92f742361641d8921f5ecd27996",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -4467,12 +4467,12 @@
4467
4467
  {
4468
4468
  "path": "package-lock.json",
4469
4469
  "mode": "0000644",
4470
- "sha256": "da4bc7f536408bd310a6793f1a5fe79c8bd34200116f6654a0c44a757a2eb542"
4470
+ "sha256": "6f22594e4af013cef5cb741be874306be308300163055bd00a6c929d48b6de93"
4471
4471
  },
4472
4472
  {
4473
4473
  "path": "package.json",
4474
4474
  "mode": "0000644",
4475
- "sha256": "f7bd93c3e267ae64b19a7bcbc53f0c34f99e7dc92eb3d09af5692f4ca160d2af"
4475
+ "sha256": "0d77282b3bbfdbff7f582d9a7765a174a8881b18ef150dcbf6d2b640a104069a"
4476
4476
  },
4477
4477
  {
4478
4478
  "path": "public-docs/index.html",
@@ -5062,7 +5062,7 @@
5062
5062
  {
5063
5063
  "path": "scripts/gds/diagram-facts.js",
5064
5064
  "mode": "0000644",
5065
- "sha256": "fe57f283f06985234123a46b5ae055f4ecd9df26834cb99e58228a5cb649e0aa"
5065
+ "sha256": "2aba736613cacecbc81b40b813db619eaa83871a8c2aad213ab73869347c7f56"
5066
5066
  },
5067
5067
  {
5068
5068
  "path": "scripts/gds/discipline-modes.json",
@@ -5117,7 +5117,7 @@
5117
5117
  {
5118
5118
  "path": "scripts/gds/fitness.js",
5119
5119
  "mode": "0000644",
5120
- "sha256": "81b35af96345cfdca3f30a9d4f333715c4dd431657a9aa73b5794c02ef75686f"
5120
+ "sha256": "a5fa6432b70c9b18d39d08837edd17987982a12595c1a55bb44585f9af71628d"
5121
5121
  },
5122
5122
  {
5123
5123
  "path": "scripts/gds/gate-review.js",
@@ -5167,7 +5167,7 @@
5167
5167
  {
5168
5168
  "path": "scripts/gds/gen-diagrams.js",
5169
5169
  "mode": "0000644",
5170
- "sha256": "569a06e7cb448dab63a3acbcbf9c5366e394252c38edbe477d4d58282a9984c4"
5170
+ "sha256": "d002fe7dd2564dea5965c0801a5d58a61e6d29b3bf6823299177c78612bf492b"
5171
5171
  },
5172
5172
  {
5173
5173
  "path": "scripts/gds/gen-file-map.js",
@@ -6117,7 +6117,7 @@
6117
6117
  {
6118
6118
  "path": "src/module-api.js",
6119
6119
  "mode": "0000644",
6120
- "sha256": "87b51e22fba9b2f7b17c0628175b359ad761fb916ee6a1c93887ad473d42f588"
6120
+ "sha256": "c1a2c62a325a9d5516729a15e8bc8939aa05d2c1e25db859a8ec519e04605186"
6121
6121
  },
6122
6122
  {
6123
6123
  "path": "src/module-loader/catalog.js",
@@ -6937,7 +6937,7 @@
6937
6937
  {
6938
6938
  "path": "tests/fitness.mjs",
6939
6939
  "mode": "0000644",
6940
- "sha256": "ebb93b7bdd90c0775f71eb949a6e47022570bdb35c901bd4522413fefa750e14"
6940
+ "sha256": "fb9f8fe63f0f9447ab82ba171b718855e4157846ae4a292e907ff895faa892a3"
6941
6941
  },
6942
6942
  {
6943
6943
  "path": "tests/fitness_ratchets.mjs",
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.264",
3
+ "version": "1.19.266",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.264",
9
+ "version": "1.19.266",
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.264",
3
+ "version": "1.19.266",
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",
@@ -153,10 +153,12 @@ async function liveVersions() {
153
153
  // 2026-05-30), NOT the seed refs — the V3 renumber (migration 021) made
154
154
  // seed-ref R##s diverge from live ids in a couple of places (so a source_ref
155
155
  // lookup would be unreliable). On an instance that imported the origin backlog
156
- // under new ids they resolve through the IMPORT_ID_OFFSETS probe below. In particular the bounty-AWARDING gate is the
157
- // "auto-confirmation flow that awards drachmae" task (#286 / live ref R67), not
158
- // the security-ADR-stub task that the old hand-authored .mmd loosely called
159
- // "R68" (#287). Each entry documents the piece it drives.
156
+ // under new ids they resolve through the IMPORT_ID_OFFSETS probe below.
157
+ //
158
+ // In particular the bounty-AWARDING gate is the "auto-confirmation flow that
159
+ // awards drachmae" task (#286 / live ref R67), not the security-ADR-stub task
160
+ // that the old hand-authored .mmd loosely called "R68" (#287). Each entry
161
+ // documents the piece it drives.
160
162
  const CONCEPTUAL_TASK_IDS = {
161
163
  // 04-architecture (the MEMORY layer) — ADR 0024 cloneable-memory chain.
162
164
  273: 'R54 — builder_memory store schema',
@@ -184,16 +186,23 @@ const CONCEPTUAL_TASK_IDS = {
184
186
  // 897 — the per-builder sandbox live game preview on the box
185
187
  // 919 — the scoped dev-box session (box token deny-by-default)
186
188
  // 1025 — server-mediated branch publish (box uploads bundle, server pushes)
187
- // 859 — CI self-deploy (Actions deploys main→droplet; no key on any box)
188
189
  // 1027 — hardware-verify of the box→prod flow end-to-end (now SHIPPED)
189
190
  // 1028 — replaced the standing push PAT with a GitHub App (now SHIPPED)
191
+ //
192
+ // Every id here MUST drive a piece of the diagram. An id no consumer reads is
193
+ // not merely dead weight: conceptualFacts() below degrades the WHOLE bundle to
194
+ // null the moment any single id is unreachable, so an unused id can silently
195
+ // stop 03 + 04 from regenerating at all (the failure shape task 1002667 fixed
196
+ // for the offset case). Do NOT re-add 859 (CI self-deploy): the deploy leg is
197
+ // the standalone AUTO-PULL of ADR 0108/0129, not a task-gated Actions job, so
198
+ // gen-diagrams.js deliberately excludes it — see its comment at `box → prod`.
199
+ // Removed in task 1002674.
190
200
  const DEV_BOX_TASK_IDS = {
191
201
  904: 'devbox-app — desktop on-off switch',
192
202
  774: 'browser-only box terminal (ttyd over tunnel)',
193
203
  897: 'per-builder sandbox live preview',
194
204
  919: 'scoped dev-box session (box token deny-by-default)',
195
205
  1025: 'server-mediated branch publish (box uploads bundle, server pushes)',
196
- 859: 'CI self-deploy (Actions deploys main to the droplet)',
197
206
  1027: 'hardware-verify the box-to-prod flow end-to-end',
198
207
  1028: 'GitHub App hardening (replace the standing push PAT)',
199
208
  };
@@ -579,6 +579,23 @@ function discoveredModuleKeys(modulesDir) {
579
579
  for (const root of MODULE_ROOTS) for (const k of _moduleKeysIn(path.join(root, 'modules'))) keys.add(k);
580
580
  return [...keys];
581
581
  }
582
+ // task 1002790: two questions, previously conflated and asserted EQUAL. BROAD
583
+ // (every dir) stays broad — the migration checks need it, since a .sql in a
584
+ // manifest-less dir must still be namespace/stem-checked (schema_migrations is
585
+ // stem-keyed; a collision is silently SKIPPED). NARROW = carries module.json,
586
+ // which is what makes a module a module (ADR 0083) and what kernel-naming means.
587
+ function manifestModuleKeys(modulesDir) {
588
+ const manifested = (dir) => _moduleKeysIn(dir).filter((k) => fs.existsSync(path.join(dir, k, 'module.json')));
589
+ if (modulesDir) return manifested(modulesDir);
590
+ return [...new Set(MODULE_ROOTS.flatMap((r) => manifested(path.join(r, 'modules'))))];
591
+ }
592
+ // The DIFFERENCE as an instruction, not a bare diff — and a WARNING, because a
593
+ // dir without a manifest is the normal transient shape of scaffolding a module.
594
+ function manifestlessModuleDirs(modulesDir) {
595
+ const narrow = new Set(manifestModuleKeys(modulesDir));
596
+ return discoveredModuleKeys(modulesDir).filter((k) => !narrow.has(k)).sort().map((k) =>
597
+ `modules/${k}/ has no module.json — it is a directory, not a module. Add the manifest (ADR 0083) or remove the dir. Warning, not a failure: scaffolding a module dir before its manifest is normal and must not red CI.`);
598
+ }
582
599
  // Absolute path to a discovered module's dir, resolving WHICH root holds it (core package or
583
600
  // instance repo). Today both roots coincide → the single checkout.
584
601
  function moduleDir(key) {
@@ -618,7 +635,7 @@ function scanKernelForModuleKeys(text, keys) {
618
635
  }
619
636
 
620
637
  function checkCoreCarriesNoModuleCode() {
621
- const keys = discoveredModuleKeys();
638
+ const keys = manifestModuleKeys(); // task 1002790 — NARROW: a manifest-less dir is not a module
622
639
  const violations = [];
623
640
  for (const relFile of KERNEL_FILES) {
624
641
  if (KERNEL_NAMES_MODULES_OK.has(relFile)) continue; // the registry legitimately names every module
@@ -631,8 +648,8 @@ function checkCoreCarriesNoModuleCode() {
631
648
  ok: violations.length === 0,
632
649
  hardFail: violations.length > 0,
633
650
  violations,
634
- warnings: [],
635
- note: `kernel machinery (${KERNEL_FILES.length} files) names no discovered module key${keys.length ? ` (keys: ${keys.join(', ')})` : ' (none yet)'} (ADR 0083 §Decision #4).`,
651
+ warnings: manifestlessModuleDirs(), // task 1002790 — named, and never a hard fail
652
+ note: `kernel machinery (${KERNEL_FILES.length} files) names no module key${keys.length ? ` (keys: ${keys.join(', ')})` : ' (none yet)'} (ADR 0083 §Decision #4). A key is a modules/ dir carrying module.json; the migration checks deliberately scan every dir (task 1002790).`,
636
653
  };
637
654
  }
638
655
 
@@ -1951,6 +1968,7 @@ module.exports = {
1951
1968
  kernelDomainImport,
1952
1969
  KERNEL_FILES,
1953
1970
  discoveredModuleKeys,
1971
+ manifestModuleKeys, manifestlessModuleDirs, // task 1002790 — narrow defn + the difference
1954
1972
  moduleMigrationViolations,
1955
1973
  moduleNamespace,
1956
1974
  resolvesToModule,
@@ -589,7 +589,11 @@ const CONCEPTUAL_TARGETS = [
589
589
  }
590
590
 
591
591
  if (changed.length === 0 && !assertChanged) {
592
- console.log('gen-diagrams: mechanical diagrams already current — no changes.');
592
+ // task 1002674: say WHICH set was checked. The old wording claimed only
593
+ // "mechanical", which reads as "the conceptual pair was skipped" — the
594
+ // degraded case — even on a fully successful run. Verifying that 03 + 04
595
+ // actually regenerated then meant reading the source.
596
+ console.log(`gen-diagrams: all ${TARGETS.length} diagram(s) already current — no changes${f.conceptual ? '' : ' (conceptual pair SKIPPED — see above)'}.`);
593
597
  process.exit(0);
594
598
  }
595
599
 
package/src/module-api.js CHANGED
@@ -955,8 +955,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
955
955
  // landed since 1.19.262 with no explicit bump. run 32305228786. (task 1002620)
956
956
  // 1.19.264 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
957
957
  // landed since 1.19.263 with no explicit bump. run 32396082154. (task 1002620)
958
+ // 1.19.265 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
959
+ // landed since 1.19.264 with no explicit bump. run 32396925426. (task 1002620)
960
+ // 1.19.266 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
961
+ // landed since 1.19.265 with no explicit bump. run 32400609982. (task 1002620)
958
962
  // ---------------------------------------------------------------------------
959
- const CORE_VERSION = '1.19.264'; // CI auto-patch carrier (ADR 0161); see changelog above
963
+ const CORE_VERSION = '1.19.266'; // CI auto-patch carrier (ADR 0161); see changelog above
960
964
 
961
965
  // A namespaced logger so a module's log lines are attributable + consistent.
962
966
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
package/tests/fitness.mjs CHANGED
@@ -2,6 +2,8 @@
2
2
  import assert from 'node:assert/strict';
3
3
  import { test } from 'node:test';
4
4
  import { createRequire } from 'node:module';
5
+ import fs from 'node:fs';
6
+ import os from 'node:os';
5
7
  import path from 'node:path';
6
8
  import { fileURLToPath } from 'node:url';
7
9
  import { onDiskModuleKeys } from './helpers.mjs';
@@ -166,7 +168,59 @@ test('core-carries-no-module-code: the live kernel machinery is clean', () => {
166
168
  // platform-identity), so it asserted a topology that no longer existed — task 1002470.
167
169
  // Derived from an INDEPENDENT readdir of modules/, so a discovery regression in
168
170
  // fitness.js still diverges from disk and fails here.
169
- assert.deepEqual(fitness.discoveredModuleKeys().sort(), onDiskModuleKeys());
171
+ //
172
+ // task 1002790: compare the definition this check ACTUALLY uses. It used to
173
+ // deepEqual discoveredModuleKeys() (every directory) against onDiskModuleKeys()
174
+ // (only directories carrying module.json) — two different questions asserted
175
+ // equal, so any transient dir-without-manifest was a hard CI failure. That is
176
+ // the normal shape of scaffolding a module, and goal 1000038's own task graph
177
+ // produced it (1002486 created modules/agents/migrations/ while 1002485 created
178
+ // the manifest, with no dependency edge): building in graph order red the gate.
179
+ assert.deepEqual(fitness.manifestModuleKeys().sort(), onDiskModuleKeys());
180
+ });
181
+
182
+ test('a modules/ dir without a manifest is a NAMED warning, never a hard failure', () => {
183
+ // The regression this task exists to prevent: mid-scaffold state must not red
184
+ // CI, and when it is reported the message must say what to do rather than
185
+ // showing a bare "+ agents" diff.
186
+ const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'fitness-modules-'));
187
+ const modules = path.join(tmp, 'modules');
188
+ fs.mkdirSync(path.join(modules, 'realmod'), { recursive: true });
189
+ fs.writeFileSync(path.join(modules, 'realmod', 'module.json'), '{"key":"realmod"}');
190
+ fs.mkdirSync(path.join(modules, 'scaffolded'), { recursive: true });
191
+
192
+ // Broad vs narrow now answer differently, which is the whole point.
193
+ assert.deepEqual(fitness.discoveredModuleKeys(modules).sort(), ['realmod', 'scaffolded']);
194
+ assert.deepEqual(fitness.manifestModuleKeys(modules).sort(), ['realmod']);
195
+
196
+ const warnings = fitness.manifestlessModuleDirs(modules);
197
+ assert.equal(warnings.length, 1, 'exactly the manifest-less dir is reported');
198
+ assert.match(warnings[0], /modules\/scaffolded\//, 'the warning NAMES the offender');
199
+ assert.match(warnings[0], /no module\.json/, 'and says what is missing');
200
+ assert.doesNotMatch(warnings[0], /realmod/, 'a real module is not reported');
201
+
202
+ // A fully-scaffolded tree reports nothing.
203
+ fs.writeFileSync(path.join(modules, 'scaffolded', 'module.json'), '{"key":"scaffolded"}');
204
+ assert.deepEqual(fitness.manifestlessModuleDirs(modules), []);
205
+ });
206
+
207
+ test('the migration checks keep the BROAD definition — narrowing would lose coverage', () => {
208
+ // The caution the task called out: a .sql dropped in a manifest-less dir must
209
+ // still be namespace/stem-checked, because schema_migrations is stem-keyed and
210
+ // a collision is SILENTLY skipped. So discoveredModuleKeys stays broad, and the
211
+ // migration checks must still be calling it.
212
+ const src = fs.readFileSync(path.join(ROOT, 'scripts/gds/fitness.js'), 'utf8');
213
+ const additive = src.slice(src.indexOf('function checkModuleMigrationsAdditive'));
214
+ assert.match(
215
+ additive.slice(0, 600),
216
+ /discoveredModuleKeys\(\)/,
217
+ 'checkModuleMigrationsAdditive must scan every modules/ dir, not just manifested ones',
218
+ );
219
+ // And the kernel-naming check must use the NARROW one (a stray dir with a
220
+ // common-word name must not be able to red an unrelated check).
221
+ const kernel = src.slice(src.indexOf('function checkCoreCarriesNoModuleCode'));
222
+ assert.match(kernel.slice(0, 400), /manifestModuleKeys\(\)/,
223
+ 'checkCoreCarriesNoModuleCode must use the manifest-scoped definition');
170
224
  });
171
225
 
172
226
  test('the discovered-module roster is derived from a NON-EMPTY disk read (mutation check)', () => {