@bongos/core 1.19.769 → 1.19.770

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.769",
6
- "core_contract": "1.19.769",
7
- "source_commit": "5552e7252b67cc3192446a9c48ca2cd4faf10368",
5
+ "core_version": "1.19.770",
6
+ "core_contract": "1.19.770",
7
+ "source_commit": "6860da8b241f99c69f179a82908b848215eaf46d",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-16T14:54:06.807Z",
9
+ "built_at": "2026-09-16T15:11:28.421Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 483,
13
13
  "agent_docs_stubbed": 25,
14
- "functional_verbatim": 2125,
14
+ "functional_verbatim": 2126,
15
15
  "rules": 3,
16
16
  "gate_literals": 3,
17
17
  "gate": "passed"
18
18
  },
19
- "file_count": 2633,
20
- "tree_sha256": "8c9135931a565436af92fb7fc38953f0bf6b9ca8c6b608b91e9751c88dd62fe0",
19
+ "file_count": 2634,
20
+ "tree_sha256": "d7c0492f1f78fb62ba8de96723bfc2b4caffb4083a4e98d39c23fab5de7c6270",
21
21
  "files": [
22
22
  {
23
23
  "path": ".claude/skills/ask-for-help/SKILL.md",
@@ -2512,7 +2512,7 @@
2512
2512
  {
2513
2513
  "path": "docs/module-api-changelog.md",
2514
2514
  "mode": "0000644",
2515
- "sha256": "ffaeae011cd55895b3c16a2ee903e0593aa42a22cfceb3307c5228452c737948"
2515
+ "sha256": "6c9191a42934b1fc862c9075812ead3451eacd71278bdcfb652c01b02ed7e083"
2516
2516
  },
2517
2517
  {
2518
2518
  "path": "docs/modules-contract.md",
@@ -7577,12 +7577,12 @@
7577
7577
  {
7578
7578
  "path": "package-lock.json",
7579
7579
  "mode": "0000644",
7580
- "sha256": "17b6a246e7e14d3949244aff29ed7e63dc5bc5d65a7aeff2a463f8283fa5b4cc"
7580
+ "sha256": "43473b034badae11d9d613079d8ea502102bd9349a5b601c89ec4d094f0d21bf"
7581
7581
  },
7582
7582
  {
7583
7583
  "path": "package.json",
7584
7584
  "mode": "0000644",
7585
- "sha256": "df0b9ff8dceb4cafd08db0a28bcbe92b1cbee04fefe4f811574257af0929901c"
7585
+ "sha256": "ca671dc476d503ca56328e84fa7f0e3712b60657cfbfd84f1790be4bc93a5b1f"
7586
7586
  },
7587
7587
  {
7588
7588
  "path": "public-docs/index.html",
@@ -9407,7 +9407,7 @@
9407
9407
  {
9408
9408
  "path": "src/module-api.js",
9409
9409
  "mode": "0000644",
9410
- "sha256": "3237d6ea069eae19ed9baf41a528984e21010defcfc5a0d96d34fd8eeca2fb4a"
9410
+ "sha256": "a4707be144d7581356575936d364de82a6b1dabd5310dc6df70de1954282deb4"
9411
9411
  },
9412
9412
  {
9413
9413
  "path": "src/module-loader/catalog.js",
@@ -11167,12 +11167,12 @@
11167
11167
  {
11168
11168
  "path": "tests/help_requests.mjs",
11169
11169
  "mode": "0000644",
11170
- "sha256": "8a4b380ebe8ad5667f20f4f0c21f8870262340e6d0f2aabca36d0737fdc81d1e"
11170
+ "sha256": "e1e1075e2f8ba4b52acba29804e5fd62443b823cfd15d4c50f0a93fcea0d13bd"
11171
11171
  },
11172
11172
  {
11173
11173
  "path": "tests/helpers.mjs",
11174
11174
  "mode": "0000644",
11175
- "sha256": "2c5ffa3ed447fdbbbc1b44e553f493bf05ab2848b154836defe3fe40e1909592"
11175
+ "sha256": "2527e761e86d289bfaf1f0c5bc416762b02c0784f0307fd0f445da656d8db549"
11176
11176
  },
11177
11177
  {
11178
11178
  "path": "tests/hierarchy-config.mjs",
@@ -12784,6 +12784,11 @@
12784
12784
  "mode": "0000644",
12785
12785
  "sha256": "905b7b9147fa35f74c2c5f4118175ebf96fa36107379207a7a2c59afc5a2967d"
12786
12786
  },
12787
+ {
12788
+ "path": "tests/sql_column_lines.mjs",
12789
+ "mode": "0000644",
12790
+ "sha256": "c68bf3aa9cd886de435293f0a536df8153fcc99187c48097de12c5482b1ee430"
12791
+ },
12787
12792
  {
12788
12793
  "path": "tests/sso_checkin_identity_spoof.mjs",
12789
12794
  "mode": "0000644",
@@ -12907,7 +12912,7 @@
12907
12912
  {
12908
12913
  "path": "tests/task_recommendations.mjs",
12909
12914
  "mode": "0000644",
12910
- "sha256": "cfce8e24b5844b1720399cc467e89ca457d74dfbf0783ef2a733d433f0443bd8"
12915
+ "sha256": "1c5d35d58371cbde290a3e71e023febeebf350b54031d458c2ebe58f25962aa4"
12911
12916
  },
12912
12917
  {
12913
12918
  "path": "tests/task_visual_route_gate.mjs",
@@ -2012,5 +2012,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
2012
2012
  landed since 1.19.767 with no explicit bump. run 35110800163. (task 1002620)
2013
2013
  1.19.769 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2014
2014
  landed since 1.19.768 with no explicit bump. run 35111616379. (task 1002620)
2015
+ 1.19.770 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
2016
+ landed since 1.19.769 with no explicit bump. run 35113578542. (task 1002620)
2015
2017
  ---------------------------------------------------------------------------
2016
2018
  ```
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.769",
3
+ "version": "1.19.770",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.769",
9
+ "version": "1.19.770",
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.769",
3
+ "version": "1.19.770",
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
@@ -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.769'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.770'; // 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');
@@ -10,6 +10,7 @@ import { test } from 'node:test';
10
10
  import { createRequire } from 'node:module';
11
11
  import fs from 'node:fs';
12
12
  import path from 'node:path';
13
+ import { sqlColumnLines } from './helpers.mjs';
13
14
  import { fileURLToPath } from 'node:url';
14
15
 
15
16
  const require = createRequire(import.meta.url);
@@ -127,10 +128,7 @@ test('sub-speciality is deliberately NOT modelled yet', () => {
127
128
  // "speciality" anywhere outside a `--` comment and flagged the migration's own
128
129
  // COMMENT ON TABLE, which says it is deliberately not modelled. Same
129
130
  // over-broad-source-assertion reflex as learning 1000196.
130
- const body = sql.slice(sql.indexOf('CREATE TABLE'), sql.indexOf(');'));
131
- const columns = body.split('\n')
132
- .map((l) => l.replace(/--.*$/, '').trim())
133
- .filter((l) => l && !/^(CONSTRAINT|CHECK|\))/.test(l));
131
+ const columns = sqlColumnLines(sql);
134
132
  assert.ok(!columns.some((l) => /special/i.test(l)), `no speciality column: ${columns.filter((l) => /special/i.test(l))}`);
135
133
  });
136
134
 
package/tests/helpers.mjs CHANGED
@@ -385,3 +385,39 @@ export function parseInto(host, html) {
385
385
  return null;
386
386
  });
387
387
  }
388
+
389
+ // The COLUMN LINES of a CREATE TABLE, with SQL line comments removed (task 1003759).
390
+ //
391
+ // Two tests assert "this table has no such column" and must read the COLUMN LIST,
392
+ // not the file: a migration routinely EXPLAINS in a comment that some column is
393
+ // deliberately not modelled, and matching that prose as a violation of the rule it
394
+ // states is the over-broad-source-assertion reflex of learning 1000196.
395
+ //
396
+ // Both had the same strip, and the same bug: `l.replace(/--.*$/, '')`. In JS `.`
397
+ // does not match `\r`, and `$` without the `m` flag matches ONLY end-of-string —
398
+ // so on a CRLF checkout (every Windows clone) the trailing `\r` sits between `.*`
399
+ // and `$`, the match fails, and the comment is NOT stripped. The comment line then
400
+ // reaches the column scan and trips the very assertion it was written to explain.
401
+ //
402
+ // tests/task_recommendations.mjs failed exactly that way on Windows and nowhere
403
+ // else, so CI never saw it and it sat in the local failure baseline being read as
404
+ // environmental noise. tests/help_requests.mjs carried the identical strip and
405
+ // passed only by luck — no comment inside its CREATE TABLE body happened to
406
+ // contain its scanned word.
407
+ //
408
+ // Dropping the `$` is the whole fix: `.*` still stops at the `\r`, the match now
409
+ // succeeds, and the existing `.trim()` removes what is left.
410
+ export function sqlColumnLines(sql) {
411
+ const text = String(sql || '');
412
+ const start = text.indexOf('CREATE TABLE');
413
+ if (start === -1) return [];
414
+ // End on `\n);` rather than the first `);` — a bare `);` can appear inside a
415
+ // comment or an earlier statement, which would cut the body short.
416
+ const endAt = text.indexOf('\n);', start);
417
+ const body = text.slice(start, endAt === -1 ? undefined : endAt);
418
+ return body.split('\n')
419
+ .map((l) => l.replace(/--.*/, '').trim())
420
+ // CREATE TABLE is dropped too: the slice starts at the header line, so a table
421
+ // whose NAME contained a scanned word would otherwise read as a column.
422
+ .filter((l) => l && !/^(CREATE TABLE|CONSTRAINT|CHECK|\))/.test(l));
423
+ }
@@ -0,0 +1,87 @@
1
+ // tests/sql_column_lines.mjs — the CRLF-safe SQL column extractor (task 1003759).
2
+ //
3
+ // THE BUG IT REPLACES. Two tests assert "this table has no such column", and both
4
+ // read the COLUMN LIST rather than the file, because a migration routinely EXPLAINS
5
+ // in a comment that some column is deliberately not modelled — matching that prose
6
+ // as a violation of the rule it states is the over-broad-source-assertion reflex of
7
+ // learning 1000196.
8
+ //
9
+ // Both stripped comments with `l.replace(/--.*$/, '')`, and that is wrong on a CRLF
10
+ // checkout. In JS `.` does not match `\r`, and `$` without the `m` flag matches ONLY
11
+ // end-of-string, so the trailing `\r` sits between `.*` and `$`, the match fails,
12
+ // and the comment survives into the column scan.
13
+ //
14
+ // tests/task_recommendations.mjs failed exactly that way — on Windows only, so CI
15
+ // never saw it and it sat in the local failure baseline being read as environmental
16
+ // noise for weeks. tests/help_requests.mjs had the identical strip and passed purely
17
+ // by luck: no comment inside its CREATE TABLE body happened to contain its scanned
18
+ // word. A guard that works by accident is the thing this file exists to stop.
19
+ //
20
+ // Run: node --test tests/sql_column_lines.mjs
21
+
22
+ import { test } from 'node:test';
23
+ import assert from 'node:assert/strict';
24
+ import { sqlColumnLines } from './helpers.mjs';
25
+
26
+ // The shape that broke: a comment INSIDE the table body naming the very word a
27
+ // caller scans for. Written with explicit \r\n — the whole point is the line ending.
28
+ const CRLF = [
29
+ 'CREATE TABLE lifecycle_task_recommendations (',
30
+ ' id BIGSERIAL PRIMARY KEY,',
31
+ " -- There is NO 'accepted'. Accepting a recommendation is CLAIMING THE TASK,",
32
+ ' -- so "accepted" would be a second, weaker record of holding work.',
33
+ ' status TEXT NOT NULL DEFAULT \'open\',',
34
+ ' CONSTRAINT one_open_pair UNIQUE (from_builder_id, to_builder_id)',
35
+ ');',
36
+ ].join('\r\n');
37
+
38
+ const LF = CRLF.replace(/\r\n/g, '\n');
39
+
40
+ test('CRLF: a comment naming the scanned word is stripped, not returned as a column', () => {
41
+ const cols = sqlColumnLines(CRLF);
42
+ assert.ok(!cols.some((l) => /accepted/i.test(l)),
43
+ `comments must not reach the column list, got: ${JSON.stringify(cols)}`);
44
+ });
45
+
46
+ test('CRLF and LF produce identical column lists — the platform must not matter', () => {
47
+ assert.deepEqual(sqlColumnLines(CRLF), sqlColumnLines(LF));
48
+ });
49
+
50
+ test('the real columns survive on both line endings', () => {
51
+ for (const [label, sql] of [['CRLF', CRLF], ['LF', LF]]) {
52
+ const cols = sqlColumnLines(sql);
53
+ assert.ok(cols.some((l) => l.startsWith('id ')), `${label}: id column kept`);
54
+ assert.ok(cols.some((l) => l.startsWith('status ')), `${label}: status column kept`);
55
+ }
56
+ });
57
+
58
+ test('CONSTRAINT / CHECK lines and the closing paren are filtered out', () => {
59
+ const cols = sqlColumnLines(CRLF);
60
+ assert.ok(!cols.some((l) => /^CONSTRAINT/.test(l)), 'constraints are not columns');
61
+ assert.ok(!cols.some((l) => /^\)/.test(l)), 'the closing paren is not a column');
62
+ });
63
+
64
+ test('a trailing comment on a real column line is stripped, the column kept', () => {
65
+ const sql = 'CREATE TABLE t (\r\n id BIGINT, -- accepted is not modelled here\r\n);';
66
+ const cols = sqlColumnLines(sql);
67
+ assert.deepEqual(cols, ['id BIGINT,']);
68
+ });
69
+
70
+ test('the body ends at the closing \\n); — a bare ); inside a comment does not cut it short', () => {
71
+ // `indexOf(');')` would stop at the comment and hide every column after it.
72
+ const sql = [
73
+ 'CREATE TABLE t (',
74
+ ' -- see fn(a); for why',
75
+ ' keeper TEXT,',
76
+ ');',
77
+ ].join('\r\n');
78
+ assert.ok(sqlColumnLines(sql).some((l) => l.startsWith('keeper')),
79
+ 'a column after a comment containing "};" must still be seen');
80
+ });
81
+
82
+ test('no CREATE TABLE, empty, and non-string inputs are safe', () => {
83
+ assert.deepEqual(sqlColumnLines('ALTER TABLE t ADD COLUMN x INT;'), []);
84
+ assert.deepEqual(sqlColumnLines(''), []);
85
+ assert.deepEqual(sqlColumnLines(null), []);
86
+ assert.deepEqual(sqlColumnLines(undefined), []);
87
+ });
@@ -18,6 +18,7 @@ import { test } from 'node:test';
18
18
  import { createRequire } from 'node:module';
19
19
  import fs from 'node:fs';
20
20
  import path from 'node:path';
21
+ import { sqlColumnLines } from './helpers.mjs';
21
22
  import { fileURLToPath } from 'node:url';
22
23
 
23
24
  const require = createRequire(import.meta.url);
@@ -79,10 +80,7 @@ test('the schema has NO accepted status — accepting is claiming, which lives e
79
80
  });
80
81
 
81
82
  test('the schema carries no transfer column', () => {
82
- const body = SQL.slice(SQL.indexOf('CREATE TABLE'), SQL.indexOf('\n);'));
83
- const columns = body.split('\n')
84
- .map((l) => l.replace(/--.*$/, '').trim())
85
- .filter((l) => l && !/^(CONSTRAINT|CHECK|\))/.test(l));
83
+ const columns = sqlColumnLines(SQL);
86
84
  const suspect = columns.filter((l) => /transferred|claimed_by|assigned_to|accepted/i.test(l));
87
85
  assert.deepEqual(suspect, [], `no transfer-shaped column: ${suspect}`);
88
86
  });