@bongos/core 1.19.367 → 1.19.368
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 +10 -10
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/redteam-patrol.js +48 -8
- package/src/module-api.js +3 -1
- package/tests/redteam_patrol.mjs +70 -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.368",
|
|
6
|
+
"core_contract": "1.19.368",
|
|
7
|
+
"source_commit": "17b78f620a5cdc6f01af878404e8b11ebd9b2f77",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-25T21:
|
|
9
|
+
"built_at": "2026-08-25T21:47:56.330Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 332,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1895,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "f3b82bb092f3f91eea0a51d84cc52e1b31042d4e9ae32a5a54972a00e9816c39",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -4892,12 +4892,12 @@
|
|
|
4892
4892
|
{
|
|
4893
4893
|
"path": "package-lock.json",
|
|
4894
4894
|
"mode": "0000644",
|
|
4895
|
-
"sha256": "
|
|
4895
|
+
"sha256": "a58b49638d9cbd5aa528a08b7435d6be48d636cb2574e7ed9b84b11850b296dd"
|
|
4896
4896
|
},
|
|
4897
4897
|
{
|
|
4898
4898
|
"path": "package.json",
|
|
4899
4899
|
"mode": "0000644",
|
|
4900
|
-
"sha256": "
|
|
4900
|
+
"sha256": "225e8f6b5b696a25599e723f18cfb3d8da8382a8be2a85be2429b090445ce178"
|
|
4901
4901
|
},
|
|
4902
4902
|
{
|
|
4903
4903
|
"path": "public-docs/index.html",
|
|
@@ -5972,7 +5972,7 @@
|
|
|
5972
5972
|
{
|
|
5973
5973
|
"path": "scripts/gds/redteam-patrol.js",
|
|
5974
5974
|
"mode": "0000644",
|
|
5975
|
-
"sha256": "
|
|
5975
|
+
"sha256": "34e2a56646ad7b8f72c63ee3f8c6319ce523c3ee390d89740bf44d27190d2005"
|
|
5976
5976
|
},
|
|
5977
5977
|
{
|
|
5978
5978
|
"path": "scripts/gds/regen-instance-docs.js",
|
|
@@ -6777,7 +6777,7 @@
|
|
|
6777
6777
|
{
|
|
6778
6778
|
"path": "src/module-api.js",
|
|
6779
6779
|
"mode": "0000644",
|
|
6780
|
-
"sha256": "
|
|
6780
|
+
"sha256": "c66c224c5bf1755a79ce4bcb6da90bfb72079ae5195b0b8758be067602329ab7"
|
|
6781
6781
|
},
|
|
6782
6782
|
{
|
|
6783
6783
|
"path": "src/module-loader/catalog.js",
|
|
@@ -8862,7 +8862,7 @@
|
|
|
8862
8862
|
{
|
|
8863
8863
|
"path": "tests/redteam_patrol.mjs",
|
|
8864
8864
|
"mode": "0000644",
|
|
8865
|
-
"sha256": "
|
|
8865
|
+
"sha256": "6dac9970bfdc8e5fd3940dc956b94963bc8ecdc345820de831078af614cf875f"
|
|
8866
8866
|
},
|
|
8867
8867
|
{
|
|
8868
8868
|
"path": "tests/regrade_eligibility.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.368",
|
|
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.368",
|
|
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.368",
|
|
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",
|
|
@@ -134,6 +134,43 @@ function lockedVersion(lock, name) {
|
|
|
134
134
|
return entry && entry.version;
|
|
135
135
|
}
|
|
136
136
|
|
|
137
|
+
// Pure: what to say about ONE `overrides` entry. Extracted so the rule is a table
|
|
138
|
+
// a test can enumerate — the networked half (npm view) stays outside.
|
|
139
|
+
//
|
|
140
|
+
// THE BUG THIS REPLACES (task 1003283, report 1000025). The old rule compared the
|
|
141
|
+
// pinned MAJOR against `dist-tags.latest` and filed a medium whenever latest was
|
|
142
|
+
// higher. That flags every override which deliberately holds a major line — which
|
|
143
|
+
// is the normal reason an override exists at all. It fired on `undici ^6.28.0`
|
|
144
|
+
// "while latest is 8.10.0", when 6.28.0 is the newest 6.x, `discord.js` (the only
|
|
145
|
+
// consumer) requires the 6.x line, and `npm audit` finds nothing. Acting on it
|
|
146
|
+
// would have BROKEN the dependent; ignoring it weekly is the alert-fatigue failure
|
|
147
|
+
// ADR 0188 §2.4 exists to prevent — here inside the patrol itself.
|
|
148
|
+
//
|
|
149
|
+
// The real signal is narrower: a pin whose LOCKED version has fallen behind what
|
|
150
|
+
// its own range already allows. That is rot nobody chose. Trailing the latest
|
|
151
|
+
// major is reported as a NOTE instead, because only a human can say whether a
|
|
152
|
+
// dependent still constrains the line.
|
|
153
|
+
//
|
|
154
|
+
// `satisfying` is every published version matching `range`, ASCENDING (npm's own
|
|
155
|
+
// order), so the newest in-range version is simply the last element — no semver
|
|
156
|
+
// comparator needed, and no dependency added to do it.
|
|
157
|
+
function overrideVerdict({ name, range, locked, satisfying = [], latest = null } = {}) {
|
|
158
|
+
const newestInRange = satisfying.length ? satisfying[satisfying.length - 1] : null;
|
|
159
|
+
if (newestInRange && locked && newestInRange !== locked && satisfying.includes(locked)) {
|
|
160
|
+
return {
|
|
161
|
+
finding: { severity: 'medium', item: `stale override: ${name} is locked at ${locked} but its own pin "${range}" already allows ${newestInRange} — refresh the lockfile` },
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const pinnedMajor = parseInt(String(range).replace(/^[^0-9]*/, ''), 10);
|
|
165
|
+
const latestMajor = parseInt(String(latest), 10);
|
|
166
|
+
if (Number.isFinite(pinnedMajor) && Number.isFinite(latestMajor) && latestMajor > pinnedMajor) {
|
|
167
|
+
return {
|
|
168
|
+
note: `override ${name} "${range}" trails the latest major (${latest}) — expected when a dependent requires that line; verify before lifting, do NOT bump blind`,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return {};
|
|
172
|
+
}
|
|
173
|
+
|
|
137
174
|
function dependencyReview() {
|
|
138
175
|
const findings = [];
|
|
139
176
|
const notes = [];
|
|
@@ -175,16 +212,19 @@ function dependencyReview() {
|
|
|
175
212
|
}
|
|
176
213
|
}
|
|
177
214
|
|
|
178
|
-
// 2c — override staleness (the undici lesson: a pin nobody watches rots)
|
|
215
|
+
// 2c — override staleness (the undici lesson: a pin nobody watches rots) —
|
|
216
|
+
// measured INSIDE the pinned range, see overrideVerdict above.
|
|
179
217
|
for (const [name, range] of Object.entries(pkg.overrides || {})) {
|
|
180
218
|
if (typeof range !== 'string') continue;
|
|
181
219
|
const latest = npmViewJson(`${name} dist-tags.latest`);
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
}
|
|
220
|
+
// Every published version matching the range, ascending. npm returns a bare
|
|
221
|
+
// string when exactly one matches, so normalise to an array.
|
|
222
|
+
const matched = npmViewJson(`"${name}@${range}" version`);
|
|
223
|
+
const satisfying = matched == null ? [] : (Array.isArray(matched) ? matched : [matched]);
|
|
224
|
+
if (!latest && !satisfying.length) { notes.push(`npm view failed for override ${name} — staleness check skipped`); continue; }
|
|
225
|
+
const v = overrideVerdict({ name, range, locked: lockedVersion(lock, name), satisfying, latest });
|
|
226
|
+
if (v.finding) findings.push(v.finding);
|
|
227
|
+
if (v.note) notes.push(v.note);
|
|
188
228
|
}
|
|
189
229
|
return { findings, notes };
|
|
190
230
|
}
|
|
@@ -393,5 +433,5 @@ if (require.main === module) {
|
|
|
393
433
|
module.exports = {
|
|
394
434
|
parseGitleaksReport, unpinnedUses, ageDays, mapSeverity, maxSeverity,
|
|
395
435
|
buildClassReport, lockedVersion, COOLDOWN_DAYS, YOUNG_PKG_DAYS,
|
|
396
|
-
stepSummary, filingBlocker, disposition,
|
|
436
|
+
stepSummary, filingBlocker, disposition, overrideVerdict,
|
|
397
437
|
};
|
package/src/module-api.js
CHANGED
|
@@ -1164,8 +1164,10 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
1164
1164
|
// landed since 1.19.365 with no explicit bump. run 32895705036. (task 1002620)
|
|
1165
1165
|
// 1.19.367 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1166
1166
|
// landed since 1.19.366 with no explicit bump. run 32902059088. (task 1002620)
|
|
1167
|
+
// 1.19.368 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1168
|
+
// landed since 1.19.367 with no explicit bump. run 32902864988. (task 1002620)
|
|
1167
1169
|
// ---------------------------------------------------------------------------
|
|
1168
|
-
const CORE_VERSION = '1.19.
|
|
1170
|
+
const CORE_VERSION = '1.19.368'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
1169
1171
|
|
|
1170
1172
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
1171
1173
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
package/tests/redteam_patrol.mjs
CHANGED
|
@@ -128,3 +128,73 @@ test('filingBlocker reports a sessionless runner instead of exiting with re-auth
|
|
|
128
128
|
assert.doesNotMatch(r.stdout + r.stderr, /builder-reauth/,
|
|
129
129
|
'the sessionless path must not print interactive re-auth guidance into a cron log');
|
|
130
130
|
});
|
|
131
|
+
|
|
132
|
+
// ---------------------------------------------------------------------------
|
|
133
|
+
// overrideVerdict (task 1003283, report 1000025). The first scheduled patrol run
|
|
134
|
+
// filed a medium saying `undici` was "pinned ^6.28.0 while latest is 8.10.0".
|
|
135
|
+
// It was wrong: 6.28.0 IS the newest 6.x, discord.js (the only consumer) requires
|
|
136
|
+
// the 6.x line, and npm audit finds nothing — acting on it would have broken the
|
|
137
|
+
// dependent, and ignoring it weekly is the alert-fatigue failure the patrol is
|
|
138
|
+
// supposed to avoid. These pin the narrower rule that replaced it.
|
|
139
|
+
// ---------------------------------------------------------------------------
|
|
140
|
+
|
|
141
|
+
test('a pin holding a major line on purpose is a NOTE, never a finding', () => {
|
|
142
|
+
// THE regression. An override exists precisely to hold a line; "latest is a
|
|
143
|
+
// higher major" is the expected steady state, not a defect.
|
|
144
|
+
const v = p.overrideVerdict({
|
|
145
|
+
name: 'undici', range: '^6.28.0', locked: '6.28.0',
|
|
146
|
+
satisfying: ['6.24.1', '6.27.0', '6.28.0'], latest: '8.10.0',
|
|
147
|
+
});
|
|
148
|
+
assert.equal(v.finding, undefined, 'a deliberate major pin must not file weekly forever');
|
|
149
|
+
assert.match(v.note, /trails the latest major/);
|
|
150
|
+
assert.match(v.note, /do NOT bump blind/);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
test('a lock that trails what the pin already allows IS a finding — rot nobody chose', () => {
|
|
154
|
+
const v = p.overrideVerdict({
|
|
155
|
+
name: 'undici', range: '^6.28.0', locked: '6.27.0',
|
|
156
|
+
satisfying: ['6.27.0', '6.28.0'], latest: '8.10.0',
|
|
157
|
+
});
|
|
158
|
+
assert.equal(v.finding.severity, 'medium');
|
|
159
|
+
assert.match(v.finding.item, /locked at 6\.27\.0 but its own pin .* already allows 6\.28\.0/);
|
|
160
|
+
assert.equal(v.note, undefined, 'the actionable finding replaces the note, not doubles it');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
test('a current pin with no newer major says nothing at all', () => {
|
|
164
|
+
const v = p.overrideVerdict({
|
|
165
|
+
name: 'x', range: '^3.1.0', locked: '3.4.0', satisfying: ['3.1.0', '3.4.0'], latest: '3.4.0',
|
|
166
|
+
});
|
|
167
|
+
assert.deepEqual(v, {});
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
test('no npm data produces silence, not a guess', () => {
|
|
171
|
+
// A registry failure must not read as "the pin is fine" OR invent a finding —
|
|
172
|
+
// the caller adds an explicit skipped-check note instead.
|
|
173
|
+
assert.deepEqual(p.overrideVerdict({ name: 'x', range: '^3.0.0', locked: '3.0.0', satisfying: [], latest: null }), {});
|
|
174
|
+
assert.deepEqual(p.overrideVerdict(), {});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('a locked version OUTSIDE the declared range is not reported as a stale lock', () => {
|
|
178
|
+
// If the lock does not satisfy the range at all, the mismatch is a different
|
|
179
|
+
// (worse) problem than "refresh the lockfile", and this rule must not mislabel
|
|
180
|
+
// it — the `satisfying.includes(locked)` guard is what keeps that honest.
|
|
181
|
+
const v = p.overrideVerdict({
|
|
182
|
+
name: 'x', range: '^6.0.0', locked: '5.9.9', satisfying: ['6.0.0', '6.1.0'], latest: '6.1.0',
|
|
183
|
+
});
|
|
184
|
+
assert.equal(v.finding, undefined);
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test('LIVE: the repo\'s own overrides produce no medium finding today', () => {
|
|
188
|
+
// The end state report 1000025 should have had. Uses the committed package.json
|
|
189
|
+
// + lockfile, with the registry answers stubbed to what they really are, so the
|
|
190
|
+
// assertion is hermetic but not fictional.
|
|
191
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(ROOT, 'package.json'), 'utf8'));
|
|
192
|
+
const lock = JSON.parse(fs.readFileSync(path.join(ROOT, 'package-lock.json'), 'utf8'));
|
|
193
|
+
const ranges = Object.entries(pkg.overrides || {}).filter(([, r]) => typeof r === 'string');
|
|
194
|
+
assert.ok(ranges.length > 0, 'this test is pointless if the repo declares no overrides');
|
|
195
|
+
for (const [name, range] of ranges) {
|
|
196
|
+
const locked = p.lockedVersion(lock, name);
|
|
197
|
+
const v = p.overrideVerdict({ name, range, locked, satisfying: [locked], latest: '99.0.0' });
|
|
198
|
+
assert.equal(v.finding, undefined, `${name} should not file a medium: ${JSON.stringify(v)}`);
|
|
199
|
+
}
|
|
200
|
+
});
|