@bongos/core 1.19.636 → 1.19.637
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 +12 -12
- package/docs/module-api-changelog.md +2 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/main-audit.js +41 -6
- package/src/module-api.js +1 -1
- package/tests/government_protected_surfaces.mjs +25 -3
- package/tests/main_audit.mjs +95 -0
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.637",
|
|
6
|
+
"core_contract": "1.19.637",
|
|
7
|
+
"source_commit": "1c08a67a41a3bf7de85545460f6803cf6c68982d",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-10T04:22:04.368Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 468,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 2592,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "09c8365d205c14a4ae13cab5ab9eb561213f4e38cc9126033a3942e5dda81e3f",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/backlog-review/SKILL.md",
|
|
@@ -2777,7 +2777,7 @@
|
|
|
2777
2777
|
{
|
|
2778
2778
|
"path": "docs/module-api-changelog.md",
|
|
2779
2779
|
"mode": "0000644",
|
|
2780
|
-
"sha256": "
|
|
2780
|
+
"sha256": "3e80809a3e33883a21335d5380c6bf9358d98f09ac1ccf6322c864bbbaa06892"
|
|
2781
2781
|
},
|
|
2782
2782
|
{
|
|
2783
2783
|
"path": "docs/modules-contract.md",
|
|
@@ -7707,12 +7707,12 @@
|
|
|
7707
7707
|
{
|
|
7708
7708
|
"path": "package-lock.json",
|
|
7709
7709
|
"mode": "0000644",
|
|
7710
|
-
"sha256": "
|
|
7710
|
+
"sha256": "262eabcdc5a5a052871db03a5a334721de892e4d927f4c069787ad763d675686"
|
|
7711
7711
|
},
|
|
7712
7712
|
{
|
|
7713
7713
|
"path": "package.json",
|
|
7714
7714
|
"mode": "0000644",
|
|
7715
|
-
"sha256": "
|
|
7715
|
+
"sha256": "e62905214d126629233cda9c9bbb2d57e3b45771899b66139237607269e190fb"
|
|
7716
7716
|
},
|
|
7717
7717
|
{
|
|
7718
7718
|
"path": "public-docs/index.html",
|
|
@@ -8372,7 +8372,7 @@
|
|
|
8372
8372
|
{
|
|
8373
8373
|
"path": "scripts/gds/main-audit.js",
|
|
8374
8374
|
"mode": "0000644",
|
|
8375
|
-
"sha256": "
|
|
8375
|
+
"sha256": "35047f05c6059aee0cb64b13ef1495e4db1f3885b5b9c8cac5c60283069a059d"
|
|
8376
8376
|
},
|
|
8377
8377
|
{
|
|
8378
8378
|
"path": "scripts/gds/me.js",
|
|
@@ -9457,7 +9457,7 @@
|
|
|
9457
9457
|
{
|
|
9458
9458
|
"path": "src/module-api.js",
|
|
9459
9459
|
"mode": "0000644",
|
|
9460
|
-
"sha256": "
|
|
9460
|
+
"sha256": "b15a7de69ca6e8cd7c57b50dab455d6ec44a40336895c78738ad0f8ec8a25a10"
|
|
9461
9461
|
},
|
|
9462
9462
|
{
|
|
9463
9463
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10857,7 +10857,7 @@
|
|
|
10857
10857
|
{
|
|
10858
10858
|
"path": "tests/government_protected_surfaces.mjs",
|
|
10859
10859
|
"mode": "0000644",
|
|
10860
|
-
"sha256": "
|
|
10860
|
+
"sha256": "cd56facc3522f17cd83b067ee1ae9dcb3e4e03dac13157013c44d7ba23508af2"
|
|
10861
10861
|
},
|
|
10862
10862
|
{
|
|
10863
10863
|
"path": "tests/government_rank_sync.mjs",
|
|
@@ -11442,7 +11442,7 @@
|
|
|
11442
11442
|
{
|
|
11443
11443
|
"path": "tests/main_audit.mjs",
|
|
11444
11444
|
"mode": "0000644",
|
|
11445
|
-
"sha256": "
|
|
11445
|
+
"sha256": "eff2ce96889306f4898686c3648d302f54fff5f137ee41ddf543866fdf2f807d"
|
|
11446
11446
|
},
|
|
11447
11447
|
{
|
|
11448
11448
|
"path": "tests/maintenance_goal.mjs",
|
|
@@ -1721,5 +1721,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
1721
1721
|
landed since 1.19.634 with no explicit bump. run 34429906252. (task 1002620)
|
|
1722
1722
|
1.19.636 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1723
1723
|
landed since 1.19.635 with no explicit bump. run 34434517065. (task 1002620)
|
|
1724
|
+
1.19.637 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1725
|
+
landed since 1.19.636 with no explicit bump. run 34436870653. (task 1002620)
|
|
1724
1726
|
---------------------------------------------------------------------------
|
|
1725
1727
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.637",
|
|
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.637",
|
|
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.637",
|
|
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",
|
|
@@ -55,7 +55,14 @@ const { cliClient, API_BASE } = require('./cli-lib');
|
|
|
55
55
|
// not a GDS github_login, and every builder shares one commit email — so the
|
|
56
56
|
// author NAME is the only distinguishing signal, and an unresolved name is
|
|
57
57
|
// 'needs a human glance', not 'definitely a violation'.
|
|
58
|
-
|
|
58
|
+
//
|
|
59
|
+
// `registry` is the protected-surface matcher, defaulting to the real one. It
|
|
60
|
+
// is a parameter for the same reason `rankByIdentity` is: this analyzer is pure
|
|
61
|
+
// and its callers supply its inputs. Tests inject a MIXED-FLOOR fixture through
|
|
62
|
+
// it — the real registry floors every surface at 'metic' today, so without the
|
|
63
|
+
// seam the per-hit floor comparison below is untestable and would silently rot
|
|
64
|
+
// back into a global-minimum test. The CLI never passes it.
|
|
65
|
+
function analyzeCommits(commits, rankByIdentity, { strict = false, registry = ppc } = {}) {
|
|
59
66
|
const findings = [];
|
|
60
67
|
for (const c of commits || []) {
|
|
61
68
|
// #863-followup (finding #5): we no longer blanket-skip merges. For a
|
|
@@ -67,28 +74,46 @@ function analyzeCommits(commits, rankByIdentity, { strict = false } = {}) {
|
|
|
67
74
|
// changes are still attributed to their feature commits (no double-count);
|
|
68
75
|
// but a merge that smuggles a protected change is now caught and attributed
|
|
69
76
|
// to the MERGE author.
|
|
70
|
-
const hits =
|
|
77
|
+
const hits = registry.matchProtected(c.files || []);
|
|
71
78
|
if (hits.length === 0) continue;
|
|
72
79
|
|
|
73
80
|
const rank = resolveRank(c, rankByIdentity);
|
|
74
81
|
const fileList = hits.map((h) => h.file).join(', ');
|
|
75
82
|
if (rank == null) {
|
|
83
|
+
const need = strictestFloorLabel(hits, registry);
|
|
76
84
|
findings.push({
|
|
77
85
|
severity: strict ? 'blocker' : 'review',
|
|
78
86
|
sha: c.sha,
|
|
79
87
|
author: c.authorName,
|
|
80
88
|
rank: null,
|
|
81
89
|
files: hits.map((h) => h.file),
|
|
82
|
-
summary: `commit ${short(c.sha)} by '${c.authorName}' touched permission-sensitive path(s) [${fileList}] but the author could not be resolved to a GDS rank. Verify it is
|
|
90
|
+
summary: `commit ${short(c.sha)} by '${c.authorName}' touched permission-sensitive path(s) [${fileList}] but the author could not be resolved to a GDS rank. Verify it is ${need}+ work.`,
|
|
83
91
|
});
|
|
84
|
-
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Each hit is judged against ITS OWN registry floor — not against the
|
|
96
|
+
// registry's global minimum. `isBelowFloor` tests the lowest floor any
|
|
97
|
+
// surface declares, which is identical only while every surface floors at
|
|
98
|
+
// the same rank (true today). The moment governance RAISES one surface's
|
|
99
|
+
// floor, a global-minimum test silently downgrades that raise back to the
|
|
100
|
+
// minimum here — in the one layer that catches a raw `git push origin main`
|
|
101
|
+
// (task 1003191; the cooperative layers already compare per-hit via
|
|
102
|
+
// checkPermissionPaths). Unknown ranks stay non-blocking, as before: an
|
|
103
|
+
// unresolvable rank is the `rank == null` case above.
|
|
104
|
+
const tier = registry.tierOf(rank);
|
|
105
|
+
const below = tier === null ? [] : hits.filter((h) => tier < registry.RANK_TIER[h.floor]);
|
|
106
|
+
if (below.length > 0) {
|
|
107
|
+
const need = strictestFloorLabel(below, registry);
|
|
108
|
+
const belowList = below.map((h) => `${h.file} (floor ${h.floor})`).join(', ');
|
|
85
109
|
findings.push({
|
|
86
110
|
severity: 'blocker',
|
|
87
111
|
sha: c.sha,
|
|
88
112
|
author: c.authorName,
|
|
89
113
|
rank,
|
|
90
|
-
files:
|
|
91
|
-
|
|
114
|
+
files: below.map((h) => h.file),
|
|
115
|
+
floors: below.map((h) => h.floor),
|
|
116
|
+
summary: `commit ${short(c.sha)} by '${c.authorName}' (rank '${rank}') modified permission-sensitive path(s) [${belowList}] whose registry floor it does not clear — this is the SEC #863 violation class. It must be reverted and re-landed by a ${need}+ builder if genuinely needed.`,
|
|
92
117
|
});
|
|
93
118
|
}
|
|
94
119
|
}
|
|
@@ -115,6 +140,16 @@ function short(sha) {
|
|
|
115
140
|
return String(sha || '').slice(0, 9);
|
|
116
141
|
}
|
|
117
142
|
|
|
143
|
+
// The highest rank floor demanded by a set of protected hits, title-cased for
|
|
144
|
+
// prose ('Metic', 'Archon'). What a reader has to clear to own the whole commit
|
|
145
|
+
// — so a finding names the floor that actually governs it rather than a
|
|
146
|
+
// hardcoded 'Metic+' that a governance floor raise would make a lie.
|
|
147
|
+
function strictestFloorLabel(hits, registry) {
|
|
148
|
+
const floors = hits.map((h) => h.floor);
|
|
149
|
+
const top = floors.reduce((a, b) => (registry.RANK_TIER[b] > registry.RANK_TIER[a] ? b : a), floors[0]);
|
|
150
|
+
return top ? top.charAt(0).toUpperCase() + top.slice(1) : 'Metic';
|
|
151
|
+
}
|
|
152
|
+
|
|
118
153
|
// ---------- git + API glue (CLI) ----------
|
|
119
154
|
|
|
120
155
|
function git(args) {
|
package/src/module-api.js
CHANGED
|
@@ -55,7 +55,7 @@ const { buildInfo } = require('./build-info');
|
|
|
55
55
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
56
56
|
// the entry to that file. Look for a version's history there, not here.
|
|
57
57
|
// ---------------------------------------------------------------------------
|
|
58
|
-
const CORE_VERSION = '1.19.
|
|
58
|
+
const CORE_VERSION = '1.19.637'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
59
59
|
|
|
60
60
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
61
61
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -172,14 +172,36 @@ test('every glob added since R101 carries a documented reason', () => {
|
|
|
172
172
|
}
|
|
173
173
|
});
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
// Metic is a FLOOR, not a fixed value (task 1003191). Pinning every surface to
|
|
176
|
+
// exactly 'metic' made the registry's own contract untestable and, worse,
|
|
177
|
+
// illegal: governance owns this data and raising one surface to 'archon' is a
|
|
178
|
+
// policy edit the enforcers are supposed to honour. What must never happen is a
|
|
179
|
+
// surface dropping BELOW Metic — that is ADR 0043 being weakened by a data edit.
|
|
180
|
+
// So: no surface under Metic, and the derived minimum stays exactly Metic.
|
|
181
|
+
test('no surface floors below Metic — the ADR 0043 floor (a raise above it is legal policy)', () => {
|
|
176
182
|
for (const s of registry.SURFACES) {
|
|
177
|
-
assert.
|
|
183
|
+
assert.ok(ppc.RANK_TIER[s.floor] >= ppc.RANK_TIER.metic,
|
|
184
|
+
`${s.glob} floors at '${s.floor}', below the Metic floor ADR 0043 sets. Governance may RAISE a floor; it may never lower one under Metic.`);
|
|
178
185
|
}
|
|
179
|
-
assert.equal(registry.FLOOR, 'metic');
|
|
186
|
+
assert.equal(registry.FLOOR, 'metic', 'the lowest declared floor is the Metic floor itself');
|
|
180
187
|
assert.equal(ppc.MIN_TIER, ppc.RANK_TIER.metic, 'the kernel floor must DERIVE to metic');
|
|
181
188
|
});
|
|
182
189
|
|
|
190
|
+
test('a floor raise flows through to the enforcers, not just the registry', () => {
|
|
191
|
+
// The registry promises a re-mapped floor reaches the substrate. Each layer
|
|
192
|
+
// must read the hit's OWN floor: the cooperative ones through
|
|
193
|
+
// checkPermissionPaths, the authoritative post-push audit through its per-hit
|
|
194
|
+
// comparison (task 1003191 — it used to test the global minimum and silently
|
|
195
|
+
// downgraded every raise).
|
|
196
|
+
const src = fs.readFileSync(path.join(ROOT, 'scripts', 'gds', 'main-audit.js'), 'utf8');
|
|
197
|
+
assert.ok(!/\bppc\.isBelowFloor\s*\(/.test(src),
|
|
198
|
+
'main-audit.js must not decide floors with isBelowFloor — that tests the registry '
|
|
199
|
+
+ 'GLOBAL MINIMUM, so a governance floor raise is silently downgraded in the one '
|
|
200
|
+
+ 'layer that catches a raw `git push origin main` (task 1003191).');
|
|
201
|
+
assert.ok(/RANK_TIER\[h\.floor\]/.test(src),
|
|
202
|
+
'main-audit.js must compare each hit against its own registry floor');
|
|
203
|
+
});
|
|
204
|
+
|
|
183
205
|
// ---------- the system-permission mapping flows from the registry ----------
|
|
184
206
|
|
|
185
207
|
test('every entry maps to a permission the catalog defines as system:true', () => {
|
package/tests/main_audit.mjs
CHANGED
|
@@ -134,6 +134,101 @@ t('#863-followup (finding #6): a sub-Metic author NAME still resolves and BLOCKS
|
|
|
134
134
|
assert.equal(r.findings[0].rank, 'thetes');
|
|
135
135
|
});
|
|
136
136
|
|
|
137
|
+
// -- per-hit registry floors (task 1003191) --------------------------------
|
|
138
|
+
//
|
|
139
|
+
// The authoritative layer used to decide floors with ppc.isBelowFloor(rank),
|
|
140
|
+
// which tests the registry's GLOBAL MINIMUM floor. Every live surface floors at
|
|
141
|
+
// 'metic', so that was indistinguishable from a per-hit comparison — until
|
|
142
|
+
// governance RAISES one surface, at which point layer 3 silently downgraded the
|
|
143
|
+
// raise back to the minimum while the pre-push hook and the grader (both on
|
|
144
|
+
// checkPermissionPaths, which compares per-hit) still blocked it. Layer 3 is the
|
|
145
|
+
// only one that catches a raw `git push origin main`, so the authoritative net
|
|
146
|
+
// was the loosest of the three.
|
|
147
|
+
//
|
|
148
|
+
// A uniform-floor fixture cannot tell the two implementations apart. This is the
|
|
149
|
+
// shape that can: one surface raised above the minimum, one left at it.
|
|
150
|
+
const ppc = require('../src/bongos/permission-path-check.js');
|
|
151
|
+
|
|
152
|
+
function mixedFloorRegistry() {
|
|
153
|
+
const SURFACES = [
|
|
154
|
+
{ glob: 'infra/', floor: 'archon' }, // RAISED above the global minimum
|
|
155
|
+
{ glob: 'src/bongos/db.js', floor: 'metic' }, // still at the minimum
|
|
156
|
+
];
|
|
157
|
+
return {
|
|
158
|
+
RANK_TIER: ppc.RANK_TIER,
|
|
159
|
+
tierOf: (rank) => ppc.RANK_TIER[rank] ?? null,
|
|
160
|
+
matchProtected: (files) => (files || [])
|
|
161
|
+
.map((f) => {
|
|
162
|
+
const s = SURFACES.find((x) => (x.glob.endsWith('/') ? f.startsWith(x.glob) : f === x.glob));
|
|
163
|
+
return s ? { file: f, glob: s.glob, floor: s.floor, permission: 'path.protected.modify' } : null;
|
|
164
|
+
})
|
|
165
|
+
.filter(Boolean),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
t('a RAISED surface floor is enforced: Metic touching an archon-floored path → BLOCKER', () => {
|
|
170
|
+
const r = analyzeCommits([{
|
|
171
|
+
sha: 'r01', subject: 'touch the substrate', authorName: 'SomeMetic', authorEmail: 'm@x',
|
|
172
|
+
isMerge: false, files: ['infra/deploy.sh'],
|
|
173
|
+
}], RANKS, { registry: mixedFloorRegistry() });
|
|
174
|
+
assert.equal(r.hardFail, true, 'a governance floor raise must reach the authoritative layer');
|
|
175
|
+
assert.equal(r.findings.length, 1);
|
|
176
|
+
assert.deepEqual(r.findings[0].floors, ['archon']);
|
|
177
|
+
assert.match(r.findings[0].summary, /Archon\+ builder/);
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
t('the finding reports only the paths the author actually fails to clear', () => {
|
|
181
|
+
// db.js floors at the minimum this Metic DOES clear; infra/ does not. A
|
|
182
|
+
// per-hit comparison names the second and stays silent about the first.
|
|
183
|
+
const r = analyzeCommits([{
|
|
184
|
+
sha: 'r02', subject: 'mixed', authorName: 'SomeMetic', authorEmail: 'm@x',
|
|
185
|
+
isMerge: false, files: ['src/bongos/db.js', 'infra/deploy.sh'],
|
|
186
|
+
}], RANKS, { registry: mixedFloorRegistry() });
|
|
187
|
+
assert.equal(r.hardFail, true);
|
|
188
|
+
assert.deepEqual(r.findings[0].files, ['infra/deploy.sh']);
|
|
189
|
+
assert.equal(r.findings[0].summary.includes('src/bongos/db.js'), false,
|
|
190
|
+
'a path the author clears must not be reported as a violation');
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
t('a raised floor does not over-block: Archon touching the same path → no finding', () => {
|
|
194
|
+
const r = analyzeCommits([{
|
|
195
|
+
sha: 'r03', subject: 'x', authorName: 'somearchon', authorEmail: 'l@x',
|
|
196
|
+
isMerge: false, files: ['infra/deploy.sh'],
|
|
197
|
+
}], RANKS, { registry: mixedFloorRegistry() });
|
|
198
|
+
assert.equal(r.hardFail, false);
|
|
199
|
+
assert.equal(r.findings.length, 0);
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
t('a Metic still clears a surface left at the minimum floor', () => {
|
|
203
|
+
const r = analyzeCommits([{
|
|
204
|
+
sha: 'r04', subject: 'x', authorName: 'SomeMetic', authorEmail: 'm@x',
|
|
205
|
+
isMerge: false, files: ['src/bongos/db.js'],
|
|
206
|
+
}], RANKS, { registry: mixedFloorRegistry() });
|
|
207
|
+
assert.equal(r.hardFail, false);
|
|
208
|
+
assert.equal(r.findings.length, 0);
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
t('an unresolved author is told the floor that actually governs, not a hardcoded Metic', () => {
|
|
212
|
+
const r = analyzeCommits([{
|
|
213
|
+
sha: 'r05', subject: 'x', authorName: 'Nobody Known', authorEmail: 'n@x',
|
|
214
|
+
isMerge: false, files: ['infra/deploy.sh'],
|
|
215
|
+
}], RANKS, { registry: mixedFloorRegistry() });
|
|
216
|
+
assert.equal(r.findings.length, 1);
|
|
217
|
+
assert.equal(r.findings[0].severity, 'review');
|
|
218
|
+
assert.match(r.findings[0].summary, /Archon\+ work/);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
t('the default registry is the real one — no injection needed in production', () => {
|
|
222
|
+
// The seam must not change what the CLI does: infra/ floors at metic today,
|
|
223
|
+
// so a Metic touching it is legal on the live registry.
|
|
224
|
+
const r = analyzeCommits([{
|
|
225
|
+
sha: 'r06', subject: 'x', authorName: 'SomeMetic', authorEmail: 'm@x',
|
|
226
|
+
isMerge: false, files: ['infra/deploy.sh'],
|
|
227
|
+
}], RANKS);
|
|
228
|
+
assert.equal(r.hardFail, false);
|
|
229
|
+
assert.equal(ppc.floorFor('infra/deploy.sh'), 'metic');
|
|
230
|
+
});
|
|
231
|
+
|
|
137
232
|
// -- the default range window (task 1002566) -------------------------------
|
|
138
233
|
//
|
|
139
234
|
// Everything above tests the pure ANALYZER. Nothing tested what FEEDS it, which
|