@bongos/core 1.19.776 → 1.19.777
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 +21 -11
- package/docs/module-api-changelog.md +2 -0
- package/modules/provisioning/migrations/provisioning_017_domain_lookup_index.sql +20 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/module-api.js +1 -1
- package/tests/provisioning_domain_lookup_index.mjs +85 -0
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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.777",
|
|
6
|
+
"core_contract": "1.19.777",
|
|
7
|
+
"source_commit": "8c4c3db04491300feb300426c07f7d4bce19f981",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-16T18:
|
|
9
|
+
"built_at": "2026-09-16T18:55:13.712Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 486,
|
|
13
13
|
"agent_docs_stubbed": 25,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2153,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2664,
|
|
20
|
+
"tree_sha256": "48b4056d95f14a44152bbeafa4b8208f71b3bbb6890cb8fff14b4b5a70f27b10",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -2527,7 +2527,7 @@
|
|
|
2527
2527
|
{
|
|
2528
2528
|
"path": "docs/module-api-changelog.md",
|
|
2529
2529
|
"mode": "0000644",
|
|
2530
|
-
"sha256": "
|
|
2530
|
+
"sha256": "48accd0cc072b560c546805d257d6ac9695ec17a3702aa7434c17b6eb632f819"
|
|
2531
2531
|
},
|
|
2532
2532
|
{
|
|
2533
2533
|
"path": "docs/modules-contract.md",
|
|
@@ -6309,6 +6309,11 @@
|
|
|
6309
6309
|
"mode": "0000644",
|
|
6310
6310
|
"sha256": "aba202502cffe31a031facd7b8e902315b81729d42028d857fa913754f2f0a7b"
|
|
6311
6311
|
},
|
|
6312
|
+
{
|
|
6313
|
+
"path": "modules/provisioning/migrations/provisioning_017_domain_lookup_index.sql",
|
|
6314
|
+
"mode": "0000644",
|
|
6315
|
+
"sha256": "69fa8f9cdc3c9ec272c318226558254267ae63ef2ffa68ab93a89a3ab5d782a2"
|
|
6316
|
+
},
|
|
6312
6317
|
{
|
|
6313
6318
|
"path": "modules/provisioning/module.json",
|
|
6314
6319
|
"mode": "0000644",
|
|
@@ -7627,12 +7632,12 @@
|
|
|
7627
7632
|
{
|
|
7628
7633
|
"path": "package-lock.json",
|
|
7629
7634
|
"mode": "0000644",
|
|
7630
|
-
"sha256": "
|
|
7635
|
+
"sha256": "620248e6545e156fd98d84b9dc29bdad59a77be39ba3e761a90d62d385255f4d"
|
|
7631
7636
|
},
|
|
7632
7637
|
{
|
|
7633
7638
|
"path": "package.json",
|
|
7634
7639
|
"mode": "0000644",
|
|
7635
|
-
"sha256": "
|
|
7640
|
+
"sha256": "d4ebe23ce76cdf1091ce8ab656a5199df19fb171768a947ff7cad259f9262dfd"
|
|
7636
7641
|
},
|
|
7637
7642
|
{
|
|
7638
7643
|
"path": "public-docs/index.html",
|
|
@@ -9492,7 +9497,7 @@
|
|
|
9492
9497
|
{
|
|
9493
9498
|
"path": "src/module-api.js",
|
|
9494
9499
|
"mode": "0000644",
|
|
9495
|
-
"sha256": "
|
|
9500
|
+
"sha256": "3791abffec940edb90c976525b388d122d16ff5613c1ee1a487d6e9f1ad1a1e0"
|
|
9496
9501
|
},
|
|
9497
9502
|
{
|
|
9498
9503
|
"path": "src/module-loader/catalog.js",
|
|
@@ -12229,6 +12234,11 @@
|
|
|
12229
12234
|
"mode": "0000644",
|
|
12230
12235
|
"sha256": "62ea8ffc2c21c351289dc7f96cab38fcd5824afba1fed0df7a545cd5df9e396c"
|
|
12231
12236
|
},
|
|
12237
|
+
{
|
|
12238
|
+
"path": "tests/provisioning_domain_lookup_index.mjs",
|
|
12239
|
+
"mode": "0000644",
|
|
12240
|
+
"sha256": "77110372442881ea3beaa59f25d08128e0dd2b92c49a78779567454ec8298d38"
|
|
12241
|
+
},
|
|
12232
12242
|
{
|
|
12233
12243
|
"path": "tests/provisioning_domain_unique.mjs",
|
|
12234
12244
|
"mode": "0000644",
|
|
@@ -2026,5 +2026,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2026
2026
|
landed since 1.19.774 with no explicit bump. run 35133750943. (task 1002620)
|
|
2027
2027
|
1.19.776 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2028
2028
|
landed since 1.19.775 with no explicit bump. run 35135604764. (task 1002620)
|
|
2029
|
+
1.19.777 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2030
|
+
landed since 1.19.776 with no explicit bump. run 35137334438. (task 1002620)
|
|
2029
2031
|
---------------------------------------------------------------------------
|
|
2030
2032
|
```
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- provisioning_017_domain_lookup_index.sql — an index every lower(domain) read can
|
|
2
|
+
-- use (task 1003541; grader minor on PR 451, task 1003347).
|
|
3
|
+
--
|
|
4
|
+
-- WHY. Every address read in provisioning.js matches `lower(domain)`, and the only
|
|
5
|
+
-- index on that expression is provisioning_015's UNIQUE one, which is PARTIAL on
|
|
6
|
+
-- status <> 'torn_down' (ADR 0181 D2 keeps a torn-down address for the revive
|
|
7
|
+
-- path). A query that does not also exclude torn-down rows cannot use a partial
|
|
8
|
+
-- index, so planetChoicesForHosts — the provisioning.projectPlanets seam behind
|
|
9
|
+
-- every public /projects/featured read — scanned the whole table. It keeps
|
|
10
|
+
-- torn-down rows on purpose (an offline project still shows its owner's planet),
|
|
11
|
+
-- so the fix is an index, not a narrower query.
|
|
12
|
+
--
|
|
13
|
+
-- Non-unique and non-partial: uniqueness stays provisioning_015's job. Additive,
|
|
14
|
+
-- no row changes. Applied only when the provisioning module is enabled. Safe to re-run.
|
|
15
|
+
|
|
16
|
+
CREATE INDEX IF NOT EXISTS ix_provisioning_instances_lower_domain
|
|
17
|
+
ON provisioning_instances (lower(domain));
|
|
18
|
+
|
|
19
|
+
INSERT INTO schema_migrations (version) VALUES ('provisioning_017_domain_lookup_index')
|
|
20
|
+
ON CONFLICT (version) DO NOTHING;
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.777",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.777",
|
|
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.
|
|
3
|
+
"version": "1.19.777",
|
|
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.
|
|
74
|
+
const CORE_VERSION = '1.19.777'; // 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');
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
// tests/provisioning_domain_lookup_index.mjs
|
|
2
|
+
//
|
|
3
|
+
// The index behind the planet seam's address read (task 1003541).
|
|
4
|
+
//
|
|
5
|
+
// planetChoicesForHosts — the provisioning.projectPlanets port every public
|
|
6
|
+
// /projects/featured read calls — matches lower(domain) and deliberately keeps
|
|
7
|
+
// torn-down rows, because the catalog still lists an offline project and its
|
|
8
|
+
// owner's planet should still draw. provisioning_015's lower(domain) index is
|
|
9
|
+
// PARTIAL on status <> 'torn_down', which such a query cannot use, so the read
|
|
10
|
+
// scanned the whole table. provisioning_017 adds the index it can use.
|
|
11
|
+
//
|
|
12
|
+
// These tests hold the pair together: the migration's expression and the seam's
|
|
13
|
+
// predicate must stay the same expression, and the seam must not "fix" the scan by
|
|
14
|
+
// quietly dropping torn-down rows.
|
|
15
|
+
//
|
|
16
|
+
// DB-free: the seam runs against a fake `db` that records its SQL. Postgres is not
|
|
17
|
+
// asked to EXPLAIN; there is no DB lane in CI (task 1003381).
|
|
18
|
+
//
|
|
19
|
+
// Run: node tests/provisioning_domain_lookup_index.mjs
|
|
20
|
+
|
|
21
|
+
import { strict as assert } from 'node:assert';
|
|
22
|
+
import { createRequire } from 'node:module';
|
|
23
|
+
import fs from 'node:fs';
|
|
24
|
+
|
|
25
|
+
const require = createRequire(import.meta.url);
|
|
26
|
+
const provisioning = require('../modules/provisioning/provisioning.js');
|
|
27
|
+
|
|
28
|
+
let passed = 0, failed = 0;
|
|
29
|
+
function t(name, fn) {
|
|
30
|
+
try { fn(); passed++; console.log(` PASS ${name}`); }
|
|
31
|
+
catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
|
|
32
|
+
}
|
|
33
|
+
async function ta(name, fn) {
|
|
34
|
+
try { await fn(); passed++; console.log(` PASS ${name}`); }
|
|
35
|
+
catch (e) { failed++; console.log(` FAIL ${name}\n ${e.message}`); }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const SQL = fs.readFileSync(new URL('../modules/provisioning/migrations/provisioning_017_domain_lookup_index.sql', import.meta.url), 'utf8');
|
|
39
|
+
const CREATE = (SQL.match(/CREATE[\s\S]*?;/) || [''])[0];
|
|
40
|
+
|
|
41
|
+
console.log('the migration — provisioning_017_domain_lookup_index.sql:');
|
|
42
|
+
|
|
43
|
+
t('indexes lower(domain), the expression every address read matches', () => {
|
|
44
|
+
assert.match(CREATE, /CREATE INDEX IF NOT EXISTS ix_provisioning_instances_lower_domain\s+ON provisioning_instances \(lower\(domain\)\)/);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
t('is neither UNIQUE nor PARTIAL — uniqueness stays provisioning_015\'s, and a partial index is what the seam could not use', () => {
|
|
48
|
+
assert.doesNotMatch(CREATE, /UNIQUE/);
|
|
49
|
+
assert.doesNotMatch(CREATE, /WHERE/);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
t('self-registers and is safe to re-run', () => {
|
|
53
|
+
assert.match(SQL, /INSERT INTO schema_migrations \(version\) VALUES \('provisioning_017_domain_lookup_index'\)\s+ON CONFLICT \(version\) DO NOTHING/);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
console.log('\nthe seam — planetChoicesForHosts:');
|
|
57
|
+
|
|
58
|
+
function recordingDb(rows = []) {
|
|
59
|
+
const calls = [];
|
|
60
|
+
return { calls, query: async (sql, params) => { calls.push({ sql, params }); return { rows }; } };
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
await ta('matches on the same lower(domain) expression the index is built on, with the hosts lowercased', async () => {
|
|
64
|
+
const db = recordingDb();
|
|
65
|
+
await provisioning.planetChoicesForHosts(db, ['Mercury.Example.com', 'mercury.example.com', '']);
|
|
66
|
+
assert.equal(db.calls.length, 1);
|
|
67
|
+
assert.match(db.calls[0].sql, /lower\(domain\) = ANY\(\$1\)/);
|
|
68
|
+
assert.deepEqual(db.calls[0].params, [['mercury.example.com']]);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
await ta('keeps torn-down rows — an offline project still draws its owner\'s planet', async () => {
|
|
72
|
+
const db = recordingDb([{ host: 'lantern.example.com', status: 'torn_down', settings: { planet_template: 'blob-tint' }, updated_at: '2026-09-16' }]);
|
|
73
|
+
const out = await provisioning.planetChoicesForHosts(db, ['lantern.example.com']);
|
|
74
|
+
assert.doesNotMatch(db.calls[0].sql, /status/, 'no status filter — that would change what the map draws, not just how fast');
|
|
75
|
+
assert.equal(out['lantern.example.com'].planet_template, 'blob-tint');
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
await ta('no hosts asks nothing', async () => {
|
|
79
|
+
const db = recordingDb();
|
|
80
|
+
assert.deepEqual(await provisioning.planetChoicesForHosts(db, []), {});
|
|
81
|
+
assert.equal(db.calls.length, 0);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log(`\nprovisioning_domain_lookup_index: ${passed} passed, ${failed} failed`);
|
|
85
|
+
process.exit(failed ? 1 : 0);
|