@bongos/core 1.19.182 → 1.19.183

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.182",
6
- "core_contract": "1.19.182",
7
- "source_commit": "e5417ea88504c51b0cc9af06d143ec9b3d37c0ed",
5
+ "core_version": "1.19.183",
6
+ "core_contract": "1.19.183",
7
+ "source_commit": "37af85f9638cba28604263e9e629479bcd665d8b",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-16T21:13:59.751Z",
9
+ "built_at": "2026-08-16T21:31:50.598Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 308,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 1608,
20
- "tree_sha256": "101a4745dd8d3b2a32eb0658b962706986782e31b92eb968862d929b7e5e05b7",
20
+ "tree_sha256": "38eea74a9e17746ec68a481e09daf00c98e4ae5c8ca74897cf299c09b09a70b1",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -2947,7 +2947,7 @@
2947
2947
  {
2948
2948
  "path": "modules/governance/protected-surfaces.json",
2949
2949
  "mode": "0000644",
2950
- "sha256": "4c7b1737c3f30d6c6f7916a2539f8b768d5a1a52357e361cde2618643a46e53e"
2950
+ "sha256": "461e27529acfc69373354ec6fdf7dfeb2f8619af456d9be2470bb3653eeb4a37"
2951
2951
  },
2952
2952
  {
2953
2953
  "path": "modules/governance/rank-roles.js",
@@ -4247,12 +4247,12 @@
4247
4247
  {
4248
4248
  "path": "package-lock.json",
4249
4249
  "mode": "0000644",
4250
- "sha256": "1817517e0566226b12320fb61a3a216cbb08c4536cd0e5b959567438b81f9993"
4250
+ "sha256": "944c48f52c7c17f20ddf4de7d00b2ae145ed7f2b427339dcd61045d0ab664135"
4251
4251
  },
4252
4252
  {
4253
4253
  "path": "package.json",
4254
4254
  "mode": "0000644",
4255
- "sha256": "090d46542c940a8327bb953057f47a8e51e56c9ecc86755af99a7e941eea4247"
4255
+ "sha256": "39ac6bb8918f513dca0cdf3139dcb6369ec0d727ec0fb0d471e9b2e0dbda06b2"
4256
4256
  },
4257
4257
  {
4258
4258
  "path": "public-docs/index.html",
@@ -5177,7 +5177,7 @@
5177
5177
  {
5178
5178
  "path": "scripts/gds/publish-manifest.js",
5179
5179
  "mode": "0000644",
5180
- "sha256": "46c017b3c133b02c1b22a83ee34e6132ca2d471a7afef2a9de056cbb6b4725a9"
5180
+ "sha256": "93e1d1cf68ceb30c6fc188f8d53094c7498ba9f1e4eb95a64f8ba883ba3897cc"
5181
5181
  },
5182
5182
  {
5183
5183
  "path": "scripts/gds/pulse.js",
@@ -5687,7 +5687,7 @@
5687
5687
  {
5688
5688
  "path": "src/bongos/module-scope-map.js",
5689
5689
  "mode": "0000644",
5690
- "sha256": "dde61de24af4bdb3ed0d00267873ee700c959166a4f86ab3a3283e8813f65bc6"
5690
+ "sha256": "162c15a20ee4ec9bfa0227b674efac51c7a11da65f9e8f612558fb023e2fe666"
5691
5691
  },
5692
5692
  {
5693
5693
  "path": "src/bongos/module-submissions.js",
@@ -5722,7 +5722,7 @@
5722
5722
  {
5723
5723
  "path": "src/bongos/route-rank-check.js",
5724
5724
  "mode": "0000644",
5725
- "sha256": "1802c2589279319abafbda1c3519dff39a43cb52d160b4c4610c6d6f3d79affd"
5725
+ "sha256": "89cdc73dd76e6b296a7d6a43ea3946eb83d180eb4e14961991dd3d8352b76738"
5726
5726
  },
5727
5727
  {
5728
5728
  "path": "src/bongos/routes.js",
@@ -5857,7 +5857,7 @@
5857
5857
  {
5858
5858
  "path": "src/module-api.js",
5859
5859
  "mode": "0000644",
5860
- "sha256": "bcbce9e29c6f05fc39ad8e52b4aa13b170962a06dbd3b6b5befba810a48e29d8"
5860
+ "sha256": "4acf151f0537e8948a570c7cf97a39964de64496c0e70d5b4000a47df85b23f5"
5861
5861
  },
5862
5862
  {
5863
5863
  "path": "src/module-loader/catalog.js",
@@ -6817,7 +6817,7 @@
6817
6817
  {
6818
6818
  "path": "tests/governance_protected_surfaces.mjs",
6819
6819
  "mode": "0000644",
6820
- "sha256": "d230c59b809cefd1a7502763a594f700ba723d8509faf9cb165b1b4ab49c6c16"
6820
+ "sha256": "8e7cb6db6c08b16d79bd6567bcb8d6724817ce65460e5574bcaf7cb6432ee049"
6821
6821
  },
6822
6822
  {
6823
6823
  "path": "tests/governance_require_permission.mjs",
@@ -34,7 +34,8 @@
34
34
  { "glob": "modules/lifecycle/routes/", "group": "authz", "why": "BV1.R86: the lifecycle routes carved out of src/bongos/routes/ — the gates follow the routes" },
35
35
  { "glob": "src/bongos/routes.js", "group": "authz", "why": "the route MOUNT table (a new ungated route lands here)" },
36
36
  { "glob": "server.js", "group": "authz", "why": "the Express entrypoint — wires every router + host routing" },
37
- { "glob": "modules/governance/", "group": "authz", "why": "the governance module (ADR 0151) — its resolver, catalog, gates AND this registry ARE the authz core; the glob is the prospective carve so CREATION is gated as strictly as edits (ADR 0086 §4)" },
37
+ { "glob": "modules/governance/", "group": "authz", "why": "the governance module (ADR 0151) — its resolver, catalog, gates AND this registry ARE the authz core; the glob is the prospective carve so CREATION is gated as strictly as edits (ADR 0086 §4). Renamed to modules/government/ by goal 1000068 (ADR 0174); BOTH globs are listed for the transition and this one is dropped with the folder in R04." },
38
+ { "glob": "modules/government/", "group": "authz", "why": "the same authz core under its post-ADR-0174 name (goal 1000068, task 1003003). Listed BEFORE the folder moves, deliberately: `protected` is DERIVED from this registry, so a module key whose globs are absent here computes protected:false — which would silently drop the Archon gate on goal creation AND the pre-push block on these files for the whole window between the key landing and the folder arriving. The prospective-carve precedent is the modules/governance/ entry directly above (ADR 0086 §4)." },
38
39
  { "glob": "modules/dev-box/boxes.js", "group": "box-access", "why": "boxScopeForRank / provision floor — decides who gets a full source clone" },
39
40
  { "glob": "modules/dev-box/box-access.js", "group": "box-access", "why": "decideSourceAccess (rank → starter|full source)" },
40
41
  { "glob": "modules/dev-box/box-credential.js", "group": "box-access", "why": "mints the box source credential" },
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.182",
3
+ "version": "1.19.183",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.182",
9
+ "version": "1.19.183",
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.182",
3
+ "version": "1.19.183",
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",
@@ -61,7 +61,8 @@ const PUBLISH_ALLOWLIST = [
61
61
  'modules/sessions/',
62
62
  'modules/autonomy/',
63
63
  'modules/security/',
64
- 'modules/governance/', // configurable roles & permissions (BV1 goal 1000030, ADR 0151) — the rank/permission machinery publishes AS the open-source methodology (ADR 0065 §4 / ADR 0098); it is in PROTECTED_GLOBS for write-protection, NOT publish-exclusion. default:true.
64
+ 'modules/governance/', // configurable roles & permissions (BV1 goal 1000030, ADR 0151) — the rank/permission machinery publishes AS the open-source methodology (ADR 0065 §4 / ADR 0098); it is in PROTECTED_GLOBS for write-protection, NOT publish-exclusion. default:true. Renamed → modules/government/ (ADR 0174); dropped with the folder in goal 1000068 R04.
65
+ 'modules/government/', // the same machinery under its post-ADR-0174 name (goal 1000068, task 1003003). Added in lockstep with the protected-surfaces.json entry: publish_manifest asserts every PROTECTED_GLOB is either topology-excluded or publishable, so registering the glob as protected WITHOUT this line default-denies the module from the published core — the open-source methodology would silently lose its permission machinery at the next release.
65
66
  'modules/hall-ui/',
66
67
  'modules/status-ui/',
67
68
  'modules/dev-box/',
@@ -174,8 +174,29 @@ const MODULE_GLOBS = {
174
174
  // role templates (R96), listed here as goal territory; the module code lands in
175
175
  // R93+ (the carve precedes the feature — ADR 0086 §4). Written as exact paths,
176
176
  // not 'config/governance*.json' — the touches convention has no wildcards. ---
177
+ // RENAMED governance → government (goal 1000068, task 1003003, ADR 0174).
178
+ // Both keys live through the transition and BOTH carry BOTH sets of globs,
179
+ // so the wall is identical whichever key a goal names and whichever name
180
+ // the folder currently has on disk. The `government` key must land BEFORE
181
+ // R04 moves the folder: goals carry scope_modules by KEY, so moving the
182
+ // folder first would leave goal 1000068's own wall not matching the files
183
+ // its remaining tasks need to touch, blocking the rename mid-goal.
184
+ // `modules/government/` is registered in protected-surfaces.json in the
185
+ // same change — `protected` DERIVES from that registry, so without it this
186
+ // key would compute protected:false and silently drop the Archon gate.
187
+ government: [
188
+ 'modules/government/', 'modules/governance/',
189
+ 'config/government.json', 'config/government.neutral.json',
190
+ 'config/governance.json', 'config/governance.neutral.json',
191
+ ],
192
+ // DEPRECATED ALIAS — kept for one release so goals and tasks already
193
+ // scoped to `governance` keep resolving. Removed by goal 1000068 R05
194
+ // (task 1003006), the release that drops the /governance/* route aliases;
195
+ // the two removals are the same compatibility window and should land
196
+ // together.
177
197
  governance: [
178
- 'modules/governance/',
198
+ 'modules/government/', 'modules/governance/',
199
+ 'config/government.json', 'config/government.neutral.json',
179
200
  'config/governance.json', 'config/governance.neutral.json',
180
201
  ],
181
202
  // --- the two web surfaces ---
@@ -231,6 +231,21 @@ const EXPECTED_RANKS = {
231
231
  'GET /security/adr': 'metic+archon',
232
232
  };
233
233
 
234
+ // The authz-core route pins, referenced by BOTH the `governance` and the
235
+ // `government` module keys below while goal 1000068's rename is in flight
236
+ // (ADR 0174, task 1003003). One object, two keys — never two literals.
237
+ const GOVERNMENT_PINS = {
238
+ 'GET /governance/roles': 'perm:governance.manage',
239
+ 'GET /governance/permissions': 'perm:governance.manage',
240
+ 'GET /governance/assignments': 'perm:governance.manage',
241
+ 'POST /governance/roles': 'perm:governance.manage',
242
+ 'PUT /governance/roles/:roleKey/permissions/:permissionKey': 'perm:governance.manage',
243
+ 'DELETE /governance/roles/:roleKey/permissions/:permissionKey': 'perm:governance.manage',
244
+ 'POST /governance/roles/:roleKey/reset': 'perm:governance.manage',
245
+ 'POST /governance/assignments': 'perm:governance.manage',
246
+ 'DELETE /governance/assignments/:builderId/:roleKey': 'perm:governance.manage',
247
+ };
248
+
234
249
  // Module-scoped privileged-rank pins: a privileged route that lives in a FEATURE
235
250
  // MODULE (modules/<key>/routes/…), pinned like EXPECTED_RANKS but verified ONLY
236
251
  // when that module is in scope (its routes were discovered in this scan). So an
@@ -400,24 +415,28 @@ const MODULE_EXPECTED_RANKS = {
400
415
  'POST /security/reports/:id/fix': 'perm:security.report.adjudicate',
401
416
  'POST /security/reports/:id/link-fix': 'perm:security.report.adjudicate',
402
417
  },
403
- // The governance tab's server half (BV1.R110, ADR 0151) — the routes that EDIT
404
- // the role/permission graph itself. Every route, the three reads included, is
405
- // pinned to the `governance.manage` ATOM rather than a rank: on this surface
406
- // the atom IS the authority (it is the catalog's meta-escalation key), and a
407
- // downgrade here is the model's worst case — the routes that write authority
408
- // drifting below the wall that guards authority. Reads are pinned too because
409
- // the full role/grant/assignment map is the authority model's blueprint.
410
- governance: {
411
- 'GET /governance/roles': 'perm:governance.manage',
412
- 'GET /governance/permissions': 'perm:governance.manage',
413
- 'GET /governance/assignments': 'perm:governance.manage',
414
- 'POST /governance/roles': 'perm:governance.manage',
415
- 'PUT /governance/roles/:roleKey/permissions/:permissionKey': 'perm:governance.manage',
416
- 'DELETE /governance/roles/:roleKey/permissions/:permissionKey': 'perm:governance.manage',
417
- 'POST /governance/roles/:roleKey/reset': 'perm:governance.manage',
418
- 'POST /governance/assignments': 'perm:governance.manage',
419
- 'DELETE /governance/assignments/:builderId/:roleKey': 'perm:governance.manage',
420
- },
418
+ // The government tab's server half (BV1.R110, ADR 0151; renamed by ADR 0174) —
419
+ // the routes that EDIT the rank/permission graph itself. Every route, the three
420
+ // reads included, is pinned to the `governance.manage` ATOM rather than a rank:
421
+ // on this surface the atom IS the authority (it is the catalog's meta-escalation
422
+ // key), and a downgrade here is the model's worst case — the routes that write
423
+ // authority drifting below the wall that guards authority. Reads are pinned too
424
+ // because the full rank/grant/assignment map is the authority model's blueprint.
425
+ //
426
+ // The ROUTE PATHS and the `governance.manage` key are renamed by R05 (task
427
+ // 1003006), not here: R02 only makes the pins reachable under both module keys.
428
+ // Renaming the paths before the routes move would pin routes that do not exist
429
+ // and red the build for the whole window.
430
+ governance: GOVERNMENT_PINS,
431
+ // The same pins under the post-ADR-0174 module name (goal 1000068, task
432
+ // 1003003). Pins are applied only when the module directory is IN SCOPE — at
433
+ // least one route file was discovered under modules/<key>/ — so this entry is
434
+ // inert until R04 (task 1003005) moves the folder, and becomes load-bearing
435
+ // the moment it does, with no second edit needed. Both keys reference the SAME
436
+ // object rather than a copy: two literals here would be the "second list that
437
+ // drifts" failure mode this file exists to prevent, on the surface where a
438
+ // silent drift is worst.
439
+ government: GOVERNMENT_PINS,
421
440
  };
422
441
 
423
442
  // The rank a route's RANK middleware implies, or null when it carries none.
package/src/module-api.js CHANGED
@@ -791,8 +791,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
791
791
  // landed since 1.19.180 with no explicit bump. run 31972686846. (task 1002620)
792
792
  // 1.19.182 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
793
793
  // landed since 1.19.181 with no explicit bump. run 31972846686. (task 1002620)
794
+ // 1.19.183 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
795
+ // landed since 1.19.182 with no explicit bump. run 31973728179. (task 1002620)
794
796
  // ---------------------------------------------------------------------------
795
- const CORE_VERSION = '1.19.182'; // CI auto-patch carrier (ADR 0161); see changelog above
797
+ const CORE_VERSION = '1.19.183'; // CI auto-patch carrier (ADR 0161); see changelog above
796
798
 
797
799
  // A namespaced logger so a module's log lines are attributable + consistent.
798
800
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -83,14 +83,70 @@ const EXPECTED_GLOBS_BEFORE_R101 = [
83
83
  '.claude/settings.json',
84
84
  ];
85
85
 
86
+ // Globs added to the registry SINCE R101, each with the change that added it.
87
+ // Kept separate from the verbatim pre-R101 array above so that array stays what
88
+ // it claims to be — the literal pre-change constant. Overwriting it to make a
89
+ // later addition pass would destroy the only evidence that R101 moved WHERE the
90
+ // truth lives without changing WHAT is protected.
91
+ //
92
+ // Each entry is { after, glob, why }: `after` is the glob it is inserted
93
+ // directly below, so the expected list is reconstructed in order rather than
94
+ // re-pasted (a re-paste is how the two lists drift apart).
95
+ const ADDED_SINCE_R101 = [
96
+ {
97
+ after: 'modules/governance/',
98
+ glob: 'modules/government/',
99
+ why: 'goal 1000068 / task 1003003 (ADR 0174) — the authz core is renamed '
100
+ + 'governance→government. The new glob is registered BEFORE the folder '
101
+ + 'moves because `protected` DERIVES from this registry: without it the '
102
+ + 'new module key computes protected:false and both the Archon gate on '
103
+ + 'goal creation and the pre-push block on these files would silently lapse.',
104
+ },
105
+ ];
106
+
107
+ // The list the registry must produce TODAY: the pre-R101 set with each
108
+ // documented addition spliced in at its declared position.
109
+ const EXPECTED_GLOBS = (() => {
110
+ const out = [...EXPECTED_GLOBS_BEFORE_R101];
111
+ for (const a of ADDED_SINCE_R101) {
112
+ const at = out.indexOf(a.after);
113
+ assert.notEqual(at, -1, `ADDED_SINCE_R101 anchors on '${a.after}', which is not in the list`);
114
+ out.splice(at + 1, 0, a.glob);
115
+ }
116
+ return out;
117
+ })();
118
+
86
119
  // ---------- behavior identity: the same globs, at the same floor ----------
87
120
 
88
- test('the registry reproduces the pre-R101 PROTECTED_GLOBS exactly, in order', () => {
89
- assert.deepEqual(registry.PROTECTED_GLOBS, EXPECTED_GLOBS_BEFORE_R101);
90
- assert.deepEqual(ppc.PROTECTED_GLOBS, EXPECTED_GLOBS_BEFORE_R101,
121
+ test('nothing protected before R101 has been unprotected since', () => {
122
+ // The load-bearing half. Additions are ordinary policy; a REMOVAL silently
123
+ // unprotects a trust surface, so it is asserted separately and must never be
124
+ // satisfied by editing the pre-R101 array.
125
+ for (const glob of EXPECTED_GLOBS_BEFORE_R101) {
126
+ assert.ok(
127
+ registry.PROTECTED_GLOBS.includes(glob),
128
+ `'${glob}' was protected before R101 and is no longer in the registry — `
129
+ + 'a protected surface cannot be dropped without an ADR saying why.',
130
+ );
131
+ }
132
+ });
133
+
134
+ test('the registry reproduces the expected glob list exactly, in order', () => {
135
+ assert.deepEqual(registry.PROTECTED_GLOBS, EXPECTED_GLOBS);
136
+ assert.deepEqual(ppc.PROTECTED_GLOBS, EXPECTED_GLOBS,
91
137
  'the kernel matcher must expose the same derived list the registry declares');
92
138
  });
93
139
 
140
+ test('every glob added since R101 carries a documented reason', () => {
141
+ for (const a of ADDED_SINCE_R101) {
142
+ assert.ok(a.why && a.why.length > 40,
143
+ `${a.glob} must record WHY it became protected — an undocumented addition `
144
+ + 'is indistinguishable from a typo.');
145
+ assert.ok(registry.PROTECTED_GLOBS.includes(a.glob),
146
+ `${a.glob} is declared as added but is not in the registry`);
147
+ }
148
+ });
149
+
94
150
  test('every surface floors at metic — the ADR 0043 floor, unchanged by the move', () => {
95
151
  for (const s of registry.SURFACES) {
96
152
  assert.equal(s.floor, 'metic', `${s.glob} must keep the Metic floor`);
@@ -128,7 +184,7 @@ test('the registry loads synchronously from the repo with no DB and no server',
128
184
  "const p=require('./src/bongos/permission-path-check');" +
129
185
  "process.stdout.write(String(p.PROTECTED_GLOBS.length)+':'+String(p.floorFor('migrations/001.sql')));",
130
186
  ], { cwd: ROOT, encoding: 'utf8', env: { ...process.env, DATABASE_URL: '', PGHOST: '' } });
131
- assert.equal(out, `${EXPECTED_GLOBS_BEFORE_R101.length}:metic`);
187
+ assert.equal(out, `${EXPECTED_GLOBS.length}:metic`);
132
188
  });
133
189
 
134
190
  test('the registry data file carries no DB/network dependency', () => {