@bongos/core 1.19.265 → 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.265",
6
- "core_contract": "1.19.265",
7
- "source_commit": "273b4bc62e5af39cd2f8a9b03017b684249b7429",
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:19:44.827Z",
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": "a85fe056ad157be858f1419eb6f90b7e6f4ec2c74efbb08eff74e590ad69f691",
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": "712a84b80962707ce7da2ee914c67fa5ed7a0032028b71166a31eeda35518733"
4470
+ "sha256": "6f22594e4af013cef5cb741be874306be308300163055bd00a6c929d48b6de93"
4471
4471
  },
4472
4472
  {
4473
4473
  "path": "package.json",
4474
4474
  "mode": "0000644",
4475
- "sha256": "512cbdbfc69c237e2620b89d0c424eff4d5175b6ef91bba239c01e3f3714e169"
4475
+ "sha256": "0d77282b3bbfdbff7f582d9a7765a174a8881b18ef150dcbf6d2b640a104069a"
4476
4476
  },
4477
4477
  {
4478
4478
  "path": "public-docs/index.html",
@@ -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",
@@ -6117,7 +6117,7 @@
6117
6117
  {
6118
6118
  "path": "src/module-api.js",
6119
6119
  "mode": "0000644",
6120
- "sha256": "f1cba6e04ee2b596f61f0d459bad39496cc7f2ed4276a60fb744174f1328f05b"
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.265",
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.265",
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.265",
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",
@@ -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,
package/src/module-api.js CHANGED
@@ -957,8 +957,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
957
957
  // landed since 1.19.263 with no explicit bump. run 32396082154. (task 1002620)
958
958
  // 1.19.265 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
959
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)
960
962
  // ---------------------------------------------------------------------------
961
- const CORE_VERSION = '1.19.265'; // 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
962
964
 
963
965
  // A namespaced logger so a module's log lines are attributable + consistent.
964
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)', () => {