@bongos/core 1.19.128 → 1.19.130
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.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.130",
|
|
6
|
+
"core_contract": "1.19.130",
|
|
7
|
+
"source_commit": "9cfc165fbc5b116976ad07e249f0ed45287f3bcf",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-
|
|
9
|
+
"built_at": "2026-08-15T03:15:08.211Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 303,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1570,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "9c3f424caabdd8755729a2c59370b4ea6c2c0e14f591297b3769f3f18ae3da41",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -4172,12 +4172,12 @@
|
|
|
4172
4172
|
{
|
|
4173
4173
|
"path": "package-lock.json",
|
|
4174
4174
|
"mode": "0000644",
|
|
4175
|
-
"sha256": "
|
|
4175
|
+
"sha256": "d530560bb0e2b69c73bba650529a2d45f3bb4c09728c54e012987f4340681c93"
|
|
4176
4176
|
},
|
|
4177
4177
|
{
|
|
4178
4178
|
"path": "package.json",
|
|
4179
4179
|
"mode": "0000644",
|
|
4180
|
-
"sha256": "
|
|
4180
|
+
"sha256": "1c4c6038789240a0e60015e8501ad5aa572b1c630d0754ee65147acb5a10bb5b"
|
|
4181
4181
|
},
|
|
4182
4182
|
{
|
|
4183
4183
|
"path": "public-docs/index.html",
|
|
@@ -4992,7 +4992,7 @@
|
|
|
4992
4992
|
{
|
|
4993
4993
|
"path": "scripts/gds/mirror-lineage-check.js",
|
|
4994
4994
|
"mode": "0000644",
|
|
4995
|
-
"sha256": "
|
|
4995
|
+
"sha256": "31296eda794e640ce5f7191d166d08710b35290be67878826a2c7209f0216e54"
|
|
4996
4996
|
},
|
|
4997
4997
|
{
|
|
4998
4998
|
"path": "scripts/gds/mirror-redact.js",
|
|
@@ -5762,7 +5762,7 @@
|
|
|
5762
5762
|
{
|
|
5763
5763
|
"path": "src/module-api.js",
|
|
5764
5764
|
"mode": "0000644",
|
|
5765
|
-
"sha256": "
|
|
5765
|
+
"sha256": "d7733ec4964e2aff924d904ee73784843f81ea72c3e2eeb6f3c7ea816c62ceb6"
|
|
5766
5766
|
},
|
|
5767
5767
|
{
|
|
5768
5768
|
"path": "src/module-loader/catalog.js",
|
|
@@ -7052,12 +7052,12 @@
|
|
|
7052
7052
|
{
|
|
7053
7053
|
"path": "tests/mirror_lineage_fulltree.mjs",
|
|
7054
7054
|
"mode": "0000644",
|
|
7055
|
-
"sha256": "
|
|
7055
|
+
"sha256": "0482cd900a7c45a18ece314deb977eef852060b50d56b814d58ac631bc568426"
|
|
7056
7056
|
},
|
|
7057
7057
|
{
|
|
7058
7058
|
"path": "tests/mirror_lineage_proof.mjs",
|
|
7059
7059
|
"mode": "0000644",
|
|
7060
|
-
"sha256": "
|
|
7060
|
+
"sha256": "74301070c93c5cb5b4f31d32e508336c96ba199064db9fdf810f07f8d431a98d"
|
|
7061
7061
|
},
|
|
7062
7062
|
{
|
|
7063
7063
|
"path": "tests/mirror_redact.mjs",
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.130",
|
|
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.130",
|
|
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.130",
|
|
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",
|
|
@@ -13,10 +13,11 @@
|
|
|
13
13
|
// export does (mirror-redact + secret-scrub, via the SHARED redactBlob) and
|
|
14
14
|
// assert ZERO residual instance literals, public IPs, or secrets survive.
|
|
15
15
|
// Same detector the export gates on — "one detector, two consumers."
|
|
16
|
-
// 2. MIGRATION NUMBERING — the set of core
|
|
17
|
-
// reach the mirror is IDENTICAL to the
|
|
18
|
-
// a file), so the claim-time next-number
|
|
19
|
-
// migration on both sides. A dropped
|
|
16
|
+
// 2. MIGRATION NUMBERING — the set of core migration numbers (bare NNN_*.sql and
|
|
17
|
+
// namespaced core_NNN_*.sql alike) that reach the mirror is IDENTICAL to the
|
|
18
|
+
// private set (redaction never renames a file), so the claim-time next-number
|
|
19
|
+
// allocator computes the SAME next migration on both sides. A dropped or
|
|
20
|
+
// renumbered migration = divergence = fail.
|
|
20
21
|
// 3. ENUM VALUES — for every publishable migration, the CHECK (... IN (...))
|
|
21
22
|
// value-lists are byte-identical before and after redaction. Redaction may
|
|
22
23
|
// touch a domain in a comment; it must NEVER alter a schema enum value.
|
|
@@ -46,6 +47,7 @@ const {
|
|
|
46
47
|
const { isBinary } = require(path.join(REPO_ROOT, 'scripts/public-mirror-export.js'));
|
|
47
48
|
const { scrubSecrets, collectEnvSecrets, SECRET_PATTERNS } = require(path.join(REPO_ROOT, 'modules/security/secret-scrub.js'));
|
|
48
49
|
const { nextFree } = require(path.join(REPO_ROOT, 'scripts/gds/next-number.js'));
|
|
50
|
+
const { migrationNumberOf } = require(path.join(REPO_ROOT, 'scripts/gds/migration-namespace.js'));
|
|
49
51
|
|
|
50
52
|
// Known secret SHAPES as NON-GLOBAL clones. We scan each file with .test(), and a
|
|
51
53
|
// `/g` regex carries lastIndex state across .test() calls — reused in a loop over
|
|
@@ -55,30 +57,41 @@ const { nextFree } = require(path.join(REPO_ROOT, 'scripts/gds/next-number.js'))
|
|
|
55
57
|
// deterministic regardless of file order.
|
|
56
58
|
const KNOWN_SECRET_SHAPES = SECRET_PATTERNS.map((re) => new RegExp(re.source, re.flags.replace('g', '')));
|
|
57
59
|
|
|
58
|
-
// Core migrations are migrations/NNN_slug.sql (3+ digit prefix) DIRECTLY under
|
|
59
|
-
// migrations/. Module migrations live under modules/<key>/migrations/ and instance
|
|
60
|
-
// SEEDS under migrations/instance/ (ADR 0105) — both numbered independently and
|
|
61
|
-
// excluded from the publishable mirror; the claim-time allocator only reads the
|
|
62
|
-
// top-level core dir, so only core numbering can diverge.
|
|
63
|
-
const MIGRATION_BASENAME_RE = /^(\d{3,})_.*\.sql$/;
|
|
64
|
-
|
|
65
60
|
// ---- pure helpers (exported for tests) ------------------------------------
|
|
66
61
|
|
|
62
|
+
// The CORE migration number for a repo-relative path, or null if it is not one.
|
|
63
|
+
//
|
|
64
|
+
// Core migrations sit DIRECTLY under migrations/ as either the legacy bare NNN_slug.sql
|
|
65
|
+
// or the namespaced core_NNN_slug.sql every NEW core migration must use (ADR 0108 §5).
|
|
66
|
+
// The prefix namespaces the FILENAME (so a core stem can't collide with an instance/
|
|
67
|
+
// module one across repos), NOT the number line — core_188 continues the bare 001–187
|
|
68
|
+
// sequence as ONE sequence. Hence the shared migrationNumberOf, the SAME parser the
|
|
69
|
+
// claim-time allocator (next-number.js) counts from: this proof and the allocator can
|
|
70
|
+
// never disagree about which numbers are taken. (Task 1002527 — the bare-regex version
|
|
71
|
+
// was blind to core_188+, leaving BOTH halves equally blind and the gate falsely green.)
|
|
72
|
+
//
|
|
73
|
+
// Module migrations (modules/<key>/migrations/) and instance SEEDS
|
|
74
|
+
// (migrations/instance/, ADR 0105) are numbered independently and excluded from the
|
|
75
|
+
// publishable mirror; the allocator only reads the top-level core dir, so only core
|
|
76
|
+
// numbering can diverge.
|
|
77
|
+
function coreMigrationNumber(repoRelPath) {
|
|
78
|
+
const s = String(repoRelPath);
|
|
79
|
+
if (!s.startsWith('migrations/')) return null; // the migrations dir …
|
|
80
|
+
// … and ONLY its top level. Counting migrations/instance/NNN_*.sql put every instance
|
|
81
|
+
// seed in the PRIVATE set but not the MIRROR set (they are unpublishable, task 2140) —
|
|
82
|
+
// a false private⇄mirror divergence that red-lined the unit gate (task 2152). A path
|
|
83
|
+
// with a further slash is a subdir, never a core migration.
|
|
84
|
+
const rest = s.slice('migrations/'.length);
|
|
85
|
+
if (rest.includes('/')) return null;
|
|
86
|
+
return migrationNumberOf(rest);
|
|
87
|
+
}
|
|
88
|
+
|
|
67
89
|
// The set of CORE migration numbers among a list of repo-relative paths.
|
|
68
90
|
function migrationNumbersFromPaths(paths) {
|
|
69
91
|
const out = new Set();
|
|
70
92
|
for (const p of paths || []) {
|
|
71
|
-
const
|
|
72
|
-
if (
|
|
73
|
-
// … and ONLY its top level. migrations/instance/NNN_*.sql are this instance's host
|
|
74
|
-
// seeds (ADR 0105), excluded from the publishable mirror (task 2140) — counting them
|
|
75
|
-
// here put every instance seed in the PRIVATE set but not the MIRROR set, a false
|
|
76
|
-
// private⇄mirror divergence that red-lined the unit gate (task 2152). A path with a
|
|
77
|
-
// further slash is a subdir, never a core migration.
|
|
78
|
-
const rest = s.slice('migrations/'.length);
|
|
79
|
-
if (rest.includes('/')) continue;
|
|
80
|
-
const m = MIGRATION_BASENAME_RE.exec(rest);
|
|
81
|
-
if (m) out.add(parseInt(m[1], 10));
|
|
93
|
+
const n = coreMigrationNumber(p);
|
|
94
|
+
if (n != null) out.add(n);
|
|
82
95
|
}
|
|
83
96
|
return out;
|
|
84
97
|
}
|
|
@@ -178,10 +191,12 @@ function proveLineage({ publishableFiles, privateMigrationNumbers, ctx }) {
|
|
|
178
191
|
for (const f of publishableFiles) {
|
|
179
192
|
const { redactedText, leaks: fileLeaks } = scanFile(f.buf, ctx);
|
|
180
193
|
for (const l of fileLeaks) leaks.push({ path: f.path, label: l.label, sample: l.sample });
|
|
181
|
-
|
|
194
|
+
// Same predicate as the private half (migrationNumbersFromPaths) — the two sets are
|
|
195
|
+
// only comparable if both are built by the identical parser.
|
|
196
|
+
const migNum = coreMigrationNumber(f.path);
|
|
197
|
+
if (migNum != null) {
|
|
182
198
|
migFiles.push({ path: f.path, original: f.buf.toString('utf8'), redacted: redactedText != null ? redactedText : f.buf.toString('utf8') });
|
|
183
|
-
|
|
184
|
-
mirrorNums.add(parseInt(mm[1], 10));
|
|
199
|
+
mirrorNums.add(migNum);
|
|
185
200
|
}
|
|
186
201
|
}
|
|
187
202
|
|
|
@@ -317,7 +332,7 @@ function main() {
|
|
|
317
332
|
if (require.main === module) main();
|
|
318
333
|
|
|
319
334
|
module.exports = {
|
|
320
|
-
|
|
335
|
+
coreMigrationNumber,
|
|
321
336
|
migrationNumbersFromPaths,
|
|
322
337
|
parseEnumChecks,
|
|
323
338
|
numberingDivergence,
|
package/src/module-api.js
CHANGED
|
@@ -683,8 +683,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
683
683
|
// landed since 1.19.126 with no explicit bump. run 31854730552. (task 1002620)
|
|
684
684
|
// 1.19.128 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
685
685
|
// landed since 1.19.127 with no explicit bump. run 31857842473. (task 1002620)
|
|
686
|
+
// 1.19.129 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
687
|
+
// landed since 1.19.128 with no explicit bump. run 31858158416. (task 1002620)
|
|
688
|
+
// 1.19.130 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
689
|
+
// landed since 1.19.129 with no explicit bump. run 31861289412. (task 1002620)
|
|
686
690
|
// ---------------------------------------------------------------------------
|
|
687
|
-
const CORE_VERSION = '1.19.
|
|
691
|
+
const CORE_VERSION = '1.19.130'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
688
692
|
|
|
689
693
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
690
694
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -12,11 +12,18 @@
|
|
|
12
12
|
// and asserts zero residual leaks + private⇄public migration-numbering/enum stability.
|
|
13
13
|
// Filesystem + git (git ls-files) are the only dependencies — no DB, no network.
|
|
14
14
|
import assert from 'node:assert/strict';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
import path from 'node:path';
|
|
17
|
+
import { fileURLToPath } from 'node:url';
|
|
15
18
|
import { test } from 'node:test';
|
|
16
19
|
import { createRequire } from 'node:module';
|
|
17
20
|
|
|
18
21
|
const require = createRequire(import.meta.url);
|
|
19
22
|
const { runSimulation } = require('../scripts/gds/mirror-lineage-check.js');
|
|
23
|
+
const { migrationNumberOf } = require('../scripts/gds/migration-namespace.js');
|
|
24
|
+
const { nextFree } = require('../scripts/gds/next-number.js');
|
|
25
|
+
|
|
26
|
+
const MIGRATIONS_DIR = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'migrations');
|
|
20
27
|
|
|
21
28
|
test('C9 full-tree simulation: the redacted publishable mirror leaks nothing', () => {
|
|
22
29
|
const report = runSimulation();
|
|
@@ -43,3 +50,24 @@ test('C9 full-tree simulation: the redacted publishable mirror leaks nothing', (
|
|
|
43
50
|
`redaction altered enum value-list(s) in ${report.drift.length} migration(s): ${report.drift.map((d) => d.path).join(', ')}`
|
|
44
51
|
);
|
|
45
52
|
});
|
|
53
|
+
|
|
54
|
+
// The proof is only worth its green tick if it actually SEES every core migration.
|
|
55
|
+
// Before task 1002527 it parsed the bare `NNN_` form only, so every `core_NNN_` file
|
|
56
|
+
// (ADR 0108 §5) was invisible to BOTH halves — equally blind, therefore silently
|
|
57
|
+
// "consistent". This asserts the simulation's coverage against the real tree so the
|
|
58
|
+
// gate can't quietly stop covering new core migrations again.
|
|
59
|
+
test('C9 full-tree simulation covers namespaced core_NNN_ migrations too (task 1002527)', () => {
|
|
60
|
+
const basenames = fs.readdirSync(MIGRATIONS_DIR).filter((n) => migrationNumberOf(n) != null);
|
|
61
|
+
const namespaced = basenames.filter((n) => !/^\d/.test(n));
|
|
62
|
+
assert.ok(namespaced.length > 0, 'expected at least one core_NNN_ migration on disk — update this test if the namespace discipline changed');
|
|
63
|
+
|
|
64
|
+
const report = runSimulation();
|
|
65
|
+
assert.equal(
|
|
66
|
+
report.counts.migrations,
|
|
67
|
+
basenames.length,
|
|
68
|
+
`the proof saw ${report.counts.migrations} core migrations but migrations/ holds ${basenames.length} — a naming form is not being parsed`
|
|
69
|
+
);
|
|
70
|
+
// Bare and namespaced core files share ONE number line, so the proof's next-free must
|
|
71
|
+
// match what next-number.js hands a claim; if they disagree a number gets re-used.
|
|
72
|
+
assert.equal(report.nextPrivate, nextFree(new Set(basenames.map(migrationNumberOf))));
|
|
73
|
+
});
|
|
@@ -8,7 +8,9 @@ import { createRequire } from 'node:module';
|
|
|
8
8
|
const require = createRequire(import.meta.url);
|
|
9
9
|
const {
|
|
10
10
|
migrationNumbersFromPaths, parseEnumChecks, numberingDivergence, enumDrift,
|
|
11
|
+
proveLineage, buildRedactionContext,
|
|
11
12
|
} = require('../scripts/gds/mirror-lineage-check.js');
|
|
13
|
+
const { nextFree } = require('../scripts/gds/next-number.js');
|
|
12
14
|
|
|
13
15
|
test('migrationNumbersFromPaths picks CORE migrations only (not module/ADR numbers)', () => {
|
|
14
16
|
const set = migrationNumbersFromPaths([
|
|
@@ -31,9 +33,61 @@ test('migrationNumbersFromPaths excludes migrations/instance/ seeds (task 2152)'
|
|
|
31
33
|
'migrations/080_core_thing.sql', // bare core → counted
|
|
32
34
|
'migrations/instance/080_gds_v4_planning_seed.sql', // instance seed → NOT core
|
|
33
35
|
'migrations/instance/186_governance_seed.sql', // instance seed → NOT core
|
|
34
|
-
'migrations/core_192_namespaced.sql', //
|
|
36
|
+
'migrations/core_192_namespaced.sql', // namespaced core (ADR 0108 §5) → counted
|
|
35
37
|
]);
|
|
36
|
-
assert.deepEqual([...set].sort((a, b) => a - b), [80]);
|
|
38
|
+
assert.deepEqual([...set].sort((a, b) => a - b), [80, 192]);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// ---- namespaced core migrations (ADR 0108 §5 / task 1002527) ---------------
|
|
42
|
+
// Core migrations above LEGACY_BARE_CORE_MAX are `core_NNN_`-prefixed so their stem
|
|
43
|
+
// can't collide with an instance/module migration across repos. The prefix namespaces
|
|
44
|
+
// the FILENAME, not the NUMBER LINE: core_188 continues the bare 001–187 sequence as
|
|
45
|
+
// ONE sequence (migration-namespace.js pins the cutoff so no bare core file can ever
|
|
46
|
+
// exceed it, and next-number.js unions both forms into a single max+1). The C9 proof
|
|
47
|
+
// must parse both forms or it silently stops covering every new core migration.
|
|
48
|
+
|
|
49
|
+
test('migrationNumbersFromPaths parses namespaced core_NNN_ names as ONE sequence with the bare ones (task 1002527)', () => {
|
|
50
|
+
const set = migrationNumbersFromPaths([
|
|
51
|
+
'migrations/003_pms.sql', // legacy bare core
|
|
52
|
+
'migrations/187_goal_sort_order.sql', // the last bare core number
|
|
53
|
+
'migrations/core_188_goal_visibility.sql',
|
|
54
|
+
'migrations/core_219_grade_attempts_idx.sql',
|
|
55
|
+
'modules/game/migrations/game_001_world.sql', // module migration — still excluded
|
|
56
|
+
]);
|
|
57
|
+
assert.deepEqual([...set].sort((a, b) => a - b), [3, 187, 188, 219]);
|
|
58
|
+
// ONE sequence, so the next free core number continues past the namespaced files —
|
|
59
|
+
// the same number next-number.js hands a claim (188 here would re-use core_188).
|
|
60
|
+
assert.equal(nextFree(set), 220);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
test('proveLineage counts namespaced core_NNN_ migrations in the MIRROR set (task 1002527)', () => {
|
|
64
|
+
const ctx = buildRedactionContext();
|
|
65
|
+
const file = (p, sql) => ({ path: p, buf: Buffer.from(sql, 'utf8') });
|
|
66
|
+
const publishableFiles = [
|
|
67
|
+
file('migrations/003_pms.sql', "CREATE TABLE a (s TEXT CHECK (s IN ('x', 'y')));\n"),
|
|
68
|
+
file('migrations/core_188_goal_visibility.sql', "CREATE TABLE b (s TEXT CHECK (s IN ('p', 'q')));\n"),
|
|
69
|
+
file('src/bongos/db.js', 'module.exports = {};\n'), // not a migration
|
|
70
|
+
];
|
|
71
|
+
const report = proveLineage({ publishableFiles, privateMigrationNumbers: new Set([3, 188]), ctx });
|
|
72
|
+
|
|
73
|
+
// Both halves must agree: the private set (migrationNumbersFromPaths) and the mirror
|
|
74
|
+
// set (proveLineage) parse the SAME names, so a namespaced file is never a false
|
|
75
|
+
// "missing" divergence — the failure mode that would red-line the C9 gate.
|
|
76
|
+
assert.equal(report.counts.migrations, 2);
|
|
77
|
+
assert.deepEqual(report.numbering, { missing: [], extra: [], consistent: true });
|
|
78
|
+
assert.equal(report.nextMirror, 189);
|
|
79
|
+
assert.equal(report.nextPrivate, 189);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('proveLineage still CATCHES a genuinely dropped namespaced core migration (task 1002527)', () => {
|
|
83
|
+
const ctx = buildRedactionContext();
|
|
84
|
+
const publishableFiles = [
|
|
85
|
+
{ path: 'migrations/003_pms.sql', buf: Buffer.from('SELECT 1;\n', 'utf8') },
|
|
86
|
+
];
|
|
87
|
+
// core_188 exists privately but never reached the mirror → a real divergence.
|
|
88
|
+
const report = proveLineage({ publishableFiles, privateMigrationNumbers: new Set([3, 188]), ctx });
|
|
89
|
+
assert.equal(report.numbering.consistent, false);
|
|
90
|
+
assert.deepEqual(report.numbering.missing, [188]);
|
|
37
91
|
});
|
|
38
92
|
|
|
39
93
|
test('parseEnumChecks extracts the quoted value-lists from CHECK (... IN (...))', () => {
|