@bongos/core 1.19.219 → 1.19.220

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.219",
6
- "core_contract": "1.19.219",
7
- "source_commit": "c74ac31eedb3ec3676f8517b51302df625298931",
5
+ "core_version": "1.19.220",
6
+ "core_contract": "1.19.220",
7
+ "source_commit": "c0428ccbca81e3243f981295653e2996e9cda202",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-08-18T03:06:20.562Z",
9
+ "built_at": "2026-08-18T03:14:10.378Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 311,
13
13
  "agent_docs_stubbed": 21,
14
- "functional_verbatim": 1302,
14
+ "functional_verbatim": 1303,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 1634,
20
- "tree_sha256": "4da1158ccf79b2a7a5253dad319cc74192493be9bda2e6a8874df8c60f581cc5",
19
+ "file_count": 1635,
20
+ "tree_sha256": "aac7f97a1131f16c75b768382681a70085520bf75be38b35124497b3d734e097",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/blocker-review/SKILL.md",
@@ -2964,6 +2964,11 @@
2964
2964
  "mode": "0000644",
2965
2965
  "sha256": "75913af702d6529c9a5cf2e2c42d9c329eea92ae99274fb71f2524520de4cfbf"
2966
2966
  },
2967
+ {
2968
+ "path": "modules/government/migrations/government_005_seeded_rank_descriptions.sql",
2969
+ "mode": "0000644",
2970
+ "sha256": "dc570f8871b578a8af965ffbc91fc4e195f2e7fce7d7886166f0025ac2b47bce"
2971
+ },
2967
2972
  {
2968
2973
  "path": "modules/government/module.json",
2969
2974
  "mode": "0000644",
@@ -4287,12 +4292,12 @@
4287
4292
  {
4288
4293
  "path": "package-lock.json",
4289
4294
  "mode": "0000644",
4290
- "sha256": "ac23681c5493a57f1faca551e4896e4a7a4e2dabb6246bf2a84c39ae6e571257"
4295
+ "sha256": "352bfdf3484cd27c33da65632970d50a1b99e164008d45b2689cb365fee16720"
4291
4296
  },
4292
4297
  {
4293
4298
  "path": "package.json",
4294
4299
  "mode": "0000644",
4295
- "sha256": "7122e5cca352a5abc317d25267eba6c0bab955febf2179bf362a896be424d0bc"
4300
+ "sha256": "719aa0ff0ff7323f96ad1257c3505c5929943f64d3e00f9cdb6f4fce78dc150e"
4296
4301
  },
4297
4302
  {
4298
4303
  "path": "public-docs/index.html",
@@ -5907,7 +5912,7 @@
5907
5912
  {
5908
5913
  "path": "src/module-api.js",
5909
5914
  "mode": "0000644",
5910
- "sha256": "d509a7e4f16027ccef999e8aadf1a2cef5368bce5cd0c3bda3b7eb61cbceaa5f"
5915
+ "sha256": "6f39901735ba86e7abd2b5770b36146104ac47dec250131ac24eeca6754ef5f2"
5911
5916
  },
5912
5917
  {
5913
5918
  "path": "src/module-loader/catalog.js",
@@ -6907,7 +6912,7 @@
6907
6912
  {
6908
6913
  "path": "tests/government_seed.mjs",
6909
6914
  "mode": "0000644",
6910
- "sha256": "e7f980f02abfb057d725beaf5730fdd71f4e8249af2180bf4a355632481330d6"
6915
+ "sha256": "8240fef8ed5b7e9a4c16e17e8dd5ffa522a99e320d41229f58f2214e00bcf160"
6911
6916
  },
6912
6917
  {
6913
6918
  "path": "tests/government_session_scope.mjs",
@@ -0,0 +1,78 @@
1
+ -- government_005_seeded_rank_descriptions.sql — the last "role" on the government
2
+ -- side: the four seeded ranks still DESCRIBE themselves as rank-roles
3
+ -- (task 1003083 / goal 1000068, criterion govt-ranks-not-roles). Decision of
4
+ -- record: ADR 0174.
5
+ --
6
+ -- ── WHAT WAS MISSED, AND WHY ────────────────────────────────────────────────
7
+ -- The rename cleaned the CONFIG TEMPLATE but never the LIVE ROWS.
8
+ -- config/government.neutral.json already reads "Seeded rank — …" for all four,
9
+ -- so the repo looks correct and a fresh instance boots with the right words in
10
+ -- its template. But `GET /api/bongos/government/ranks` reads the DB, and on the
11
+ -- live database every seeded row still carries the text governance_002 wrote:
12
+ --
13
+ -- archon : 'Seeded rank-role — top authority. Adds the admin + system (non-grantable) powers.'
14
+ -- metic : 'Seeded rank-role — the trusted working rank. Adds review/triage/authoring.'
15
+ -- thetes : 'Seeded rank-role — graduated newcomer. Adds the general claim queue.'
16
+ -- xenos : 'Seeded rank-role — the sandboxed entry rank. Own-work + public read.'
17
+ --
18
+ -- government_001 renamed the TABLES and government_002 renamed the permission
19
+ -- KEYS; neither touched this column. The hall's Government tab renders these
20
+ -- strings, so the surface goal 1000068 renamed has been displaying the reserved
21
+ -- word to the Owner ever since.
22
+ --
23
+ -- ── WHY THE FITNESS WALL DID NOT CATCH IT ───────────────────────────────────
24
+ -- Check 19 (checkVocabularyWall, scripts/gds/fitness.js) scans FILES on the
25
+ -- government surface, and only .js/.json/.html/.css at that. It cannot see DB
26
+ -- row text. That is the rule working as designed, not a hole in it — which is
27
+ -- precisely why this needed a migration rather than a lint fix.
28
+ --
29
+ -- ── WHY THIS CORRECTS FORWARD INSTEAD OF EDITING governance_002 ─────────────
30
+ -- governance_002 is applied and run-once (schema_migrations is stem-keyed), so
31
+ -- editing its text would change history without changing any database. It also
32
+ -- stays deliberately spelled the old way: it is the factual record of what was
33
+ -- once true, which is exactly the carve-out ADR 0174 grants the historical
34
+ -- migrations. government_002 (the permission-key rename) is the worked example
35
+ -- this copies. On a FRESH install the two converge — governance_002 seeds the
36
+ -- old text, this rewrites it — so both paths end identically.
37
+ --
38
+ -- ── THE GUARD IS LOAD-BEARING ───────────────────────────────────────────────
39
+ -- The WHERE clause matches the OLD SEEDED TEXT EXACTLY rather than blanket-
40
+ -- updating by rank_key. A host may have relabelled a seeded rank through
41
+ -- config (config/government.json may relabel a seeded rank — it may never
42
+ -- re-grant one), and overwriting a deliberate customisation with our template
43
+ -- would be a silent regression dressed as a typo fix. Matching the exact string
44
+ -- governance_002 wrote touches only rows nobody has edited. It also makes this
45
+ -- migration idempotent: re-running it matches nothing.
46
+ --
47
+ -- NAMING ONLY. No grant, floor, or authority change; is_system and seeded_rank
48
+ -- are untouched; no row is inserted or deleted. Safe to run against a database
49
+ -- where some or all four have already been corrected by hand.
50
+ --
51
+ -- ROLLBACK — reverse the mapping (lossless; restores the governance_002 text):
52
+ -- UPDATE government_ranks SET description = replace(description, 'Seeded rank —', 'Seeded rank-role —')
53
+ -- WHERE is_system AND rank_key IN ('xenos','thetes','metic','archon')
54
+ -- AND description LIKE 'Seeded rank —%';
55
+
56
+ BEGIN;
57
+
58
+ UPDATE government_ranks AS g
59
+ SET description = v.new_description
60
+ FROM (VALUES
61
+ ('xenos',
62
+ 'Seeded rank-role — the sandboxed entry rank. Own-work + public read.',
63
+ 'Seeded rank — the sandboxed entry rank. Own-work + public read.'),
64
+ ('thetes',
65
+ 'Seeded rank-role — graduated newcomer. Adds the general claim queue.',
66
+ 'Seeded rank — graduated newcomer. Adds the general claim queue.'),
67
+ ('metic',
68
+ 'Seeded rank-role — the trusted working rank. Adds review/triage/authoring.',
69
+ 'Seeded rank — the trusted working rank. Adds review/triage/authoring.'),
70
+ ('archon',
71
+ 'Seeded rank-role — top authority. Adds the admin + system (non-grantable) powers.',
72
+ 'Seeded rank — top authority. Adds the admin + system (non-grantable) powers.')
73
+ ) AS v(rank_key, old_description, new_description)
74
+ WHERE g.rank_key = v.rank_key
75
+ AND g.is_system
76
+ AND g.description = v.old_description;
77
+
78
+ COMMIT;
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.219",
3
+ "version": "1.19.220",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.219",
9
+ "version": "1.19.220",
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.219",
3
+ "version": "1.19.220",
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",
package/src/module-api.js CHANGED
@@ -865,8 +865,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
865
865
  // landed since 1.19.217 with no explicit bump. run 32086598601. (task 1002620)
866
866
  // 1.19.219 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
867
867
  // landed since 1.19.218 with no explicit bump. run 32094215476. (task 1002620)
868
+ // 1.19.220 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
869
+ // landed since 1.19.219 with no explicit bump. run 32094701831. (task 1002620)
868
870
  // ---------------------------------------------------------------------------
869
- const CORE_VERSION = '1.19.219'; // CI auto-patch carrier (ADR 0161); see changelog above
871
+ const CORE_VERSION = '1.19.220'; // CI auto-patch carrier (ADR 0161); see changelog above
870
872
 
871
873
  // A namespaced logger so a module's log lines are attributable + consistent.
872
874
  // Usage: const log = api.logger('dev-box'); log.info('mounted');
@@ -37,6 +37,7 @@ const NON_GRANT_MIGRATIONS = new Set([
37
37
  'government_001_rename_from_governance.sql', // ADR 0174 table rename (task 1003004)
38
38
  'government_002_rename_permission_keys.sql', // ADR 0174 key rename (task 1003006)
39
39
  'government_003_board_tables.sql', // ADR 0175 Board Room schema (task 1003016)
40
+ 'government_005_seeded_rank_descriptions.sql', // ADR 0174 seeded-description text fix (task 1003083)
40
41
  ]);
41
42
 
42
43
  // Permission keys RENAMED after the grant migrations that first granted them.
@@ -142,6 +143,35 @@ test('later grant migrations are idempotent + transactional', () => {
142
143
  }
143
144
  });
144
145
 
146
+ // The bug this guards (task 1003083): goal 1000068 renamed the government, and
147
+ // config/government.neutral.json was updated to say "Seeded rank — …". The LIVE
148
+ // government_ranks rows were not, so `GET /government/ranks` — and the hall tab
149
+ // that renders it — kept serving governance_002's "Seeded rank-role — …" long
150
+ // after the rename shipped. Two lists of the same strings, only one maintained:
151
+ // exactly the drift this file exists to prevent, in the one column nobody had
152
+ // pointed a test at. The vocabulary fitness wall cannot see it either — Check 19
153
+ // scans .js/.json/.html/.css files, never DB row text or .sql.
154
+ test('the description correction lands EXACTLY the config template text (no second list that drifts)', () => {
155
+ const correction = fs.readFileSync(path.join(MIG_DIR, 'government_005_seeded_rank_descriptions.sql'), 'utf8');
156
+ const neutral = JSON.parse(fs.readFileSync(path.join(ROOT, 'config', 'government.neutral.json'), 'utf8'));
157
+
158
+ // Each VALUES row is ('<rank_key>', '<old_description>', '<new_description>').
159
+ const rows = [...stripComments(correction).matchAll(/\(\s*'([a-z]+)'\s*,\s*'([^']+)'\s*,\s*'([^']+)'\s*\)/g)]
160
+ .map(([, rankKey, , newDescription]) => [rankKey, newDescription]);
161
+
162
+ assert.equal(rows.length, RANK_ORDER.length,
163
+ 'the correction must cover every seeded rank, not a subset');
164
+
165
+ for (const [rankKey, newDescription] of rows) {
166
+ const template = neutral.ranks[rankKey];
167
+ assert.ok(template, `${rankKey}: not a rank in config/government.neutral.json`);
168
+ assert.equal(newDescription, template.description,
169
+ `${rankKey}: the migration writes text the config template does not carry — the two lists have drifted again`);
170
+ assert.ok(!/\brole/i.test(newDescription),
171
+ `${rankKey}: "role" is reserved for the crafts (ADR 0174) — a rank describes itself as a rank`);
172
+ }
173
+ });
174
+
145
175
  test('migration objects are all governance_-namespaced (ADR 0083 §5)', () => {
146
176
  for (const sql of [tablesSql, seedSql]) {
147
177
  for (const m of sql.matchAll(/CREATE (?:TABLE|INDEX)(?: IF NOT EXISTS)? (\w+)/g)) {