@bongos/core 1.19.215 → 1.19.217
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 +11 -11
- package/.claude/skills/grader-health/SKILL.md +11 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/preflight.js +61 -4
- package/src/module-api.js +5 -1
- package/tests/preflight_checks.mjs +74 -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.217",
|
|
6
|
+
"core_contract": "1.19.217",
|
|
7
|
+
"source_commit": "2a474dc7f283910befbca2879f13d342c4d5f0b4",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-18T00:
|
|
9
|
+
"built_at": "2026-08-18T00:33:32.467Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 310,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1633,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "a3212b990024b1a28961deb9e9d93d52eeca950d4be79f84b3bddd2fe928583f",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -167,7 +167,7 @@
|
|
|
167
167
|
{
|
|
168
168
|
"path": ".claude/skills/grader-health/SKILL.md",
|
|
169
169
|
"mode": "0000644",
|
|
170
|
-
"sha256": "
|
|
170
|
+
"sha256": "3268e1138e02245ddf16d11b072133168cf0f59ca0ea4656631babba5df7158c"
|
|
171
171
|
},
|
|
172
172
|
{
|
|
173
173
|
"path": ".claude/skills/idea-triage/SKILL.md",
|
|
@@ -4282,12 +4282,12 @@
|
|
|
4282
4282
|
{
|
|
4283
4283
|
"path": "package-lock.json",
|
|
4284
4284
|
"mode": "0000644",
|
|
4285
|
-
"sha256": "
|
|
4285
|
+
"sha256": "09501ec03bde658dfcbc651c0603d0c45f5d38914aafb73ff685ccec7c76d69e"
|
|
4286
4286
|
},
|
|
4287
4287
|
{
|
|
4288
4288
|
"path": "package.json",
|
|
4289
4289
|
"mode": "0000644",
|
|
4290
|
-
"sha256": "
|
|
4290
|
+
"sha256": "c6882c7a5bf88c3cdd811dd9b957aeffe46b5ffbdc9c42e45a49c5e5caff1edf"
|
|
4291
4291
|
},
|
|
4292
4292
|
{
|
|
4293
4293
|
"path": "public-docs/index.html",
|
|
@@ -5197,7 +5197,7 @@
|
|
|
5197
5197
|
{
|
|
5198
5198
|
"path": "scripts/gds/preflight.js",
|
|
5199
5199
|
"mode": "0000644",
|
|
5200
|
-
"sha256": "
|
|
5200
|
+
"sha256": "bd57bb676f0ed6c426129a912727c4ecd363a1197373588fe24f4d48727a75dc"
|
|
5201
5201
|
},
|
|
5202
5202
|
{
|
|
5203
5203
|
"path": "scripts/gds/provision.js",
|
|
@@ -5902,7 +5902,7 @@
|
|
|
5902
5902
|
{
|
|
5903
5903
|
"path": "src/module-api.js",
|
|
5904
5904
|
"mode": "0000644",
|
|
5905
|
-
"sha256": "
|
|
5905
|
+
"sha256": "6123bf63d65e4e5327c05a413117015e2198293f2a1a2191f10cb1ecbb397fbf"
|
|
5906
5906
|
},
|
|
5907
5907
|
{
|
|
5908
5908
|
"path": "src/module-loader/catalog.js",
|
|
@@ -7497,7 +7497,7 @@
|
|
|
7497
7497
|
{
|
|
7498
7498
|
"path": "tests/preflight_checks.mjs",
|
|
7499
7499
|
"mode": "0000644",
|
|
7500
|
-
"sha256": "
|
|
7500
|
+
"sha256": "9f16091a8feeaef9e4350104dbc9671fab6f2b53f99fd82f798c77800e780b61"
|
|
7501
7501
|
},
|
|
7502
7502
|
{
|
|
7503
7503
|
"path": "tests/preview_server.mjs",
|
|
@@ -31,7 +31,16 @@ Baselines: the 14-agent evaluation window measured a **90.6%** pass rate, alread
|
|
|
31
31
|
|
|
32
32
|
### 3 — Cost anomalies
|
|
33
33
|
|
|
34
|
-
Benchmark: mean panel cost **$2.14** per grade, and ~90% of it is **fixed** re-exploration cost, independent of diff size. Read grader spend
|
|
34
|
+
Benchmark: mean panel cost **$2.14** per grade, and ~90% of it is **fixed** re-exploration cost, independent of diff size. Read grader spend and divide by the grade count from axis 2's window:
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
node scripts/gds/api.js GET "/api/gds/public/cost-summary?source=grader&days=30" --quiet \
|
|
38
|
+
| node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>{const j=JSON.parse(s);
|
|
39
|
+
if(j.applied_filters?.source!=='grader'){console.error('FILTER DROPPED — do not divide');process.exit(1)}
|
|
40
|
+
console.log('grader 30d:', j.filtered_total_usd)})"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Read `filtered_total_usd`, never `total_usd`.** The filters drill into the breakdown; they deliberately do *not* rescope the headline, so `total_usd` stays instance-wide (the treasury chart depends on that) and is off by more than an order of magnitude here. `by_category` / `by_builder` / `by_source` *are* filtered — under `?source=grader`, `by_builder` attributes each panel to the builder whose ship triggered it, which is why human logins appear. The `applied_filters` guard above makes a silently-dropped filter fail loudly instead of yielding a wrong mean.
|
|
35
44
|
|
|
36
45
|
- Mean drifting well above the benchmark → panel re-rolls/retries or timeout-and-retry loops (not "big diffs" — the fixed-cost share means diff size barely moves the mean).
|
|
37
46
|
- Near-zero spend with grades still recording → the trivial path or grade reuse dominating; spot-check that gating lenses are actually running.
|
|
@@ -56,6 +65,6 @@ End with a compact findings list, most severe first: axis, evidence (the numbers
|
|
|
56
65
|
|
|
57
66
|
## Files this skill touches
|
|
58
67
|
|
|
59
|
-
- Reads: `GET /api/gds/public/grades`, `GET /api/gds/grades/by-builder` (Archon), `GET /api/gds/public/cost-summary?source=grader
|
|
68
|
+
- Reads: `GET /api/gds/public/grades`, `GET /api/gds/grades/by-builder` (Archon), `GET /api/gds/public/cost-summary?source=grader` (the `filtered_total_usd` key), `GET /api/gds/tasks/:id?include=grade`, `modules/grading/grader.js`, `modules/grading/grader-rubric.json`.
|
|
60
69
|
- Runs (read-only): `node scripts/gds/doctor.js`; with `--probe` only: `node scripts/gds/grade-smoke.js`.
|
|
61
70
|
- Writes: 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.217",
|
|
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.217",
|
|
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.217",
|
|
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/scripts/gds/preflight.js
CHANGED
|
@@ -8,8 +8,9 @@
|
|
|
8
8
|
// on a bare machine it died with `node: command not found`.
|
|
9
9
|
// 2. deps installed — a missing node_modules is why a ship later blew up with
|
|
10
10
|
// `Cannot find module 'pg'`.
|
|
11
|
-
// 3. `claude`
|
|
12
|
-
// failed grading with SUBAGENT_SPAWN_FAILED
|
|
11
|
+
// 3. `claude` usable — the grader spawns it per worker. Not launchable ⇒ every
|
|
12
|
+
// ship failed grading with SUBAGENT_SPAWN_FAILED; launchable
|
|
13
|
+
// but LOGGED OUT ⇒ SUBAGENT_NONZERO_EXIT (task 1003080).
|
|
13
14
|
// Each finding carries a copy-paste fix.
|
|
14
15
|
//
|
|
15
16
|
// Before this, those checks lived only inside `bongos doctor` (doctor.js) and were
|
|
@@ -31,6 +32,10 @@ const { spawnSync } = require('node:child_process');
|
|
|
31
32
|
const REPO_ROOT = nodePath.resolve(__dirname, '..', '..');
|
|
32
33
|
const MIN_NODE_MAJOR = 22;
|
|
33
34
|
|
|
35
|
+
// Env that authenticates the CLI with no interactive login — a headless box or a
|
|
36
|
+
// CI runner. ci-grade.js reads the same two to decide whether it can grade at all.
|
|
37
|
+
const HEADLESS_AUTH_ENV = ['CLAUDE_CODE_OAUTH_TOKEN', 'ANTHROPIC_API_KEY'];
|
|
38
|
+
|
|
34
39
|
// The node_modules-present check, factored out (task 1002403) so a HOT-PATH
|
|
35
40
|
// caller — /builder-start runs on every session open — can reuse THIS exact
|
|
36
41
|
// finding without paying for the `claude --version` spawn the full
|
|
@@ -49,6 +54,55 @@ function depsFinding({ repoRoot = REPO_ROOT, fs = nodeFs } = {}) {
|
|
|
49
54
|
};
|
|
50
55
|
}
|
|
51
56
|
|
|
57
|
+
// The AUTH half of the `claude CLI` row (task 1003080). Split out to keep
|
|
58
|
+
// preflightChecks readable — the depsFinding precedent. Pure: spawn/env injected.
|
|
59
|
+
//
|
|
60
|
+
// WHY IT EXISTS. `claude --version` exits 0 while the CLI is LOGGED OUT, so the
|
|
61
|
+
// launchable probe alone reported "the grader can spawn its workers" on a box
|
|
62
|
+
// where every worker died on spawn. The grader runs one `claude -p` per panel
|
|
63
|
+
// worker; logged out, each exits 1 in ~5s, so all four record
|
|
64
|
+
// SUBAGENT_NONZERO_EXIT, the panel reports `unavailable`, and the builder gets a
|
|
65
|
+
// 0/10 "grade failed" card with an empty issues[] — while doctor, the one tool
|
|
66
|
+
// they're told to run, printed a green row. (Observed on task 1002459: two
|
|
67
|
+
// consecutive outage rounds, cost_usd null on every worker, while the rest of the
|
|
68
|
+
// fleet graded 21/21 the same day.)
|
|
69
|
+
//
|
|
70
|
+
// `claude auth status --json` answers `{ loggedIn: bool }` from local credentials
|
|
71
|
+
// — no token spend, no model call. An unverifiable answer (an older CLI with no
|
|
72
|
+
// `auth` subcommand, or any unparseable output) deliberately stays OK with the
|
|
73
|
+
// caveat named: a working older box must never be turned red by a probe it can't
|
|
74
|
+
// answer.
|
|
75
|
+
function claudeAuthFinding({ bin, via, ver, env, spawn, platform }) {
|
|
76
|
+
const envVar = HEADLESS_AUTH_ENV.find((k) => env[k]);
|
|
77
|
+
if (envVar) {
|
|
78
|
+
return { level: 'ok', title: 'claude CLI', detail: `launches${via}: ${ver}; authenticated via ${envVar} — the grader can spawn its workers.` };
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let a;
|
|
82
|
+
try {
|
|
83
|
+
a = spawn(bin, ['auth', 'status', '--json'], { encoding: 'utf8', shell: platform === 'win32', windowsHide: true, timeout: 15000 });
|
|
84
|
+
} catch (err) { a = { error: err }; }
|
|
85
|
+
|
|
86
|
+
let loggedIn = null; // null ⇒ the CLI didn't answer in a shape we understand
|
|
87
|
+
try {
|
|
88
|
+
const parsed = JSON.parse(String((a && a.stdout) || '').trim());
|
|
89
|
+
if (typeof parsed.loggedIn === 'boolean') loggedIn = parsed.loggedIn;
|
|
90
|
+
} catch (_) { /* older CLI without `auth status`, or non-JSON output */ }
|
|
91
|
+
|
|
92
|
+
if (loggedIn === false) {
|
|
93
|
+
return {
|
|
94
|
+
level: 'fail',
|
|
95
|
+
title: 'claude CLI',
|
|
96
|
+
detail: `launches${via} (${ver}) but is not logged in — the grader spawns one \`claude -p\` per panel worker and each exits 1 immediately, so every ship fails grading with SUBAGENT_NONZERO_EXIT and a 0/10 card carrying no findings.`,
|
|
97
|
+
fix: `Run \`${bin} auth login\` (or \`${bin}\`, then /login). On a headless box, set ${HEADLESS_AUTH_ENV.join(' or ')} instead.`,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (loggedIn === true) {
|
|
101
|
+
return { level: 'ok', title: 'claude CLI', detail: `launches${via}: ${ver}, logged in — the grader can spawn its workers.` };
|
|
102
|
+
}
|
|
103
|
+
return { level: 'ok', title: 'claude CLI', detail: `launches${via}: ${ver} — the grader can spawn its workers (login state not verified: this CLI has no \`auth status\`).` };
|
|
104
|
+
}
|
|
105
|
+
|
|
52
106
|
// preflightChecks(deps) → [{ level:'ok'|'warn'|'fail', title, detail, fix? }]
|
|
53
107
|
// No printing, no process.exit — callers (setup, doctor, the test) format it.
|
|
54
108
|
function preflightChecks({
|
|
@@ -87,7 +141,10 @@ function preflightChecks({
|
|
|
87
141
|
} catch (err) { r = { error: err }; }
|
|
88
142
|
if (r && !r.error && r.status === 0) {
|
|
89
143
|
const ver = String(r.stdout || '').trim().split('\n')[0] || 'present';
|
|
90
|
-
|
|
144
|
+
// task 1003080: launchable is only HALF this leg — `--version` exits 0 while
|
|
145
|
+
// the CLI is logged out, so this row used to go green at the exact moment
|
|
146
|
+
// the thing it checks is broken. claudeAuthFinding proves auth too.
|
|
147
|
+
out.push(claudeAuthFinding({ bin, via, ver, env, spawn, platform }));
|
|
91
148
|
} else {
|
|
92
149
|
const why = r && r.error ? (r.error.code || r.error.message) : `exited ${r ? r.status : '?'}`;
|
|
93
150
|
out.push({
|
|
@@ -116,7 +173,7 @@ function formatPreflight(results, { color = false, heading = false } = {}) {
|
|
|
116
173
|
return lines.join('\n');
|
|
117
174
|
}
|
|
118
175
|
|
|
119
|
-
module.exports = { preflightChecks, depsFinding, formatPreflight, REPO_ROOT, MIN_NODE_MAJOR };
|
|
176
|
+
module.exports = { preflightChecks, depsFinding, claudeAuthFinding, formatPreflight, REPO_ROOT, MIN_NODE_MAJOR, HEADLESS_AUTH_ENV };
|
|
120
177
|
|
|
121
178
|
// Standalone: `node scripts/gds/preflight.js` — exit 1 if any hard fail.
|
|
122
179
|
if (require.main === module) {
|
package/src/module-api.js
CHANGED
|
@@ -857,8 +857,12 @@ const { validateOrRespond, LIMITS, parseId, asyncHandler, corsPublicGet, parsePa
|
|
|
857
857
|
// landed since 1.19.213 with no explicit bump. run 32081917908. (task 1002620)
|
|
858
858
|
// 1.19.215 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
859
859
|
// landed since 1.19.214 with no explicit bump. run 32084187695. (task 1002620)
|
|
860
|
+
// 1.19.216 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
861
|
+
// landed since 1.19.215 with no explicit bump. run 32084584347. (task 1002620)
|
|
862
|
+
// 1.19.217 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
863
|
+
// landed since 1.19.216 with no explicit bump. run 32084927511. (task 1002620)
|
|
860
864
|
// ---------------------------------------------------------------------------
|
|
861
|
-
const CORE_VERSION = '1.19.
|
|
865
|
+
const CORE_VERSION = '1.19.217'; // CI auto-patch carrier (ADR 0161); see changelog above
|
|
862
866
|
|
|
863
867
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
864
868
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
|
@@ -70,3 +70,77 @@ test('formatPreflight renders glyphs + fixes and stays plain (no ANSI) by defaul
|
|
|
70
70
|
assert.match(s, /→ .*npm ci/);
|
|
71
71
|
assert.doesNotMatch(s, /\x1b\[/); // color:false ⇒ no ANSI escapes
|
|
72
72
|
});
|
|
73
|
+
|
|
74
|
+
// --------------------------------------------------------------------------
|
|
75
|
+
// claude CLI AUTHENTICATION (task 1003080)
|
|
76
|
+
// --------------------------------------------------------------------------
|
|
77
|
+
// `--version` exits 0 while the CLI is logged out, so the launchable probe
|
|
78
|
+
// alone false-greened the exact failure it exists to catch: every grader worker
|
|
79
|
+
// exits 1 on spawn (SUBAGENT_NONZERO_EXIT) and the builder gets a 0/10 card with
|
|
80
|
+
// no findings. These cover the four auth shapes.
|
|
81
|
+
|
|
82
|
+
// A spawn stub that answers `--version` and `auth status --json` differently.
|
|
83
|
+
// authJson === null ⇒ the CLI has no `auth` subcommand (older build): non-JSON
|
|
84
|
+
// on stdout, non-zero exit.
|
|
85
|
+
const spawnWithAuth = (authJson) => (_bin, args) => {
|
|
86
|
+
if (args && args[0] === 'auth') {
|
|
87
|
+
return authJson === null
|
|
88
|
+
? { status: 1, stdout: '', stderr: "error: unknown command 'auth'\n" }
|
|
89
|
+
: { status: 0, stdout: `${JSON.stringify(authJson)}\n` };
|
|
90
|
+
}
|
|
91
|
+
return { status: 0, stdout: '2.1.234 (Claude Code)\n' };
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
test('claude launches but is LOGGED OUT → fail naming SUBAGENT_NONZERO_EXIT + the login fix', () => {
|
|
95
|
+
const r = preflightChecks({
|
|
96
|
+
nodeVersion: 'v22.0.0', fs: fsWith(true), env: {},
|
|
97
|
+
spawn: spawnWithAuth({ loggedIn: false }),
|
|
98
|
+
});
|
|
99
|
+
const claude = find(r, 'claude CLI');
|
|
100
|
+
assert.equal(claude.level, 'fail');
|
|
101
|
+
assert.match(claude.detail, /not logged in/i);
|
|
102
|
+
assert.match(claude.detail, /SUBAGENT_NONZERO_EXIT/);
|
|
103
|
+
assert.match(claude.fix, /auth login/);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('claude logged in → ok', () => {
|
|
107
|
+
const r = preflightChecks({
|
|
108
|
+
nodeVersion: 'v22.0.0', fs: fsWith(true), env: {},
|
|
109
|
+
spawn: spawnWithAuth({ loggedIn: true, authMethod: 'claude.ai' }),
|
|
110
|
+
});
|
|
111
|
+
const claude = find(r, 'claude CLI');
|
|
112
|
+
assert.equal(claude.level, 'ok');
|
|
113
|
+
assert.match(claude.detail, /2\.1\.234/);
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
test('a headless auth token in env → ok, and the auth probe is never spawned', () => {
|
|
117
|
+
const seen = [];
|
|
118
|
+
const spy = (_bin, args) => { seen.push((args || []).join(' ')); return { status: 0, stdout: '2.1.234\n' }; };
|
|
119
|
+
const r = preflightChecks({
|
|
120
|
+
nodeVersion: 'v22.0.0', fs: fsWith(true), spawn: spy,
|
|
121
|
+
env: { CLAUDE_CODE_OAUTH_TOKEN: 'sk-ant-oat-xxx' },
|
|
122
|
+
});
|
|
123
|
+
const claude = find(r, 'claude CLI');
|
|
124
|
+
assert.equal(claude.level, 'ok');
|
|
125
|
+
assert.match(claude.detail, /CLAUDE_CODE_OAUTH_TOKEN/);
|
|
126
|
+
assert.deepEqual(seen, ['--version']);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('an older CLI without `auth status` stays ok, but says auth was not verified', () => {
|
|
130
|
+
const r = preflightChecks({
|
|
131
|
+
nodeVersion: 'v22.0.0', fs: fsWith(true), env: {},
|
|
132
|
+
spawn: spawnWithAuth(null),
|
|
133
|
+
});
|
|
134
|
+
const claude = find(r, 'claude CLI');
|
|
135
|
+
assert.equal(claude.level, 'ok');
|
|
136
|
+
assert.match(claude.detail, /not verif/i);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
test('a thrown auth spawn is treated as unverifiable, never crashes', () => {
|
|
140
|
+
const spawnThrows = (_bin, args) => {
|
|
141
|
+
if (args && args[0] === 'auth') throw new Error('boom');
|
|
142
|
+
return { status: 0, stdout: '2.1.234\n' };
|
|
143
|
+
};
|
|
144
|
+
const r = preflightChecks({ nodeVersion: 'v22.0.0', fs: fsWith(true), env: {}, spawn: spawnThrows });
|
|
145
|
+
assert.equal(find(r, 'claude CLI').level, 'ok');
|
|
146
|
+
});
|