@bongos/core 1.19.1033 → 1.19.1035
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 +204 -99
- package/.claude/skills/builder-start/SKILL.md +1 -1
- package/.claude/skills/grade-recover/SKILL.md +2 -1
- package/.claude/skills/grader-health/SKILL.md +4 -0
- package/.claude/skills/merge-mode/SKILL.md +1 -1
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +6 -0
- package/clients/bongos-client/index.cjs +6 -0
- package/clients/bongos-client/index.d.ts +8 -0
- package/clients/bongos-client/index.mjs +6 -0
- package/docs/adr/0089-modular-multi-model-adversarial-grader.md +15 -0
- package/docs/adr/README.md +1 -1
- package/docs/api/openapi.json +120 -4
- package/docs/api-reference.md +9 -2
- package/docs/architecture.md +3 -2
- package/docs/canonical-permissions.md +2 -2
- package/docs/copy-inventory.md +34 -30
- package/docs/copy-registry.json +69 -33
- package/docs/module-api-changelog.md +5 -1
- package/docs/recipes/local-dev.md +45 -3
- package/docs/recipes/packaging-the-core.md +1 -1
- package/modules/autonomy/cadence.js +52 -0
- package/modules/autonomy/db.js +19 -0
- package/modules/autonomy/routes/autonomy.js +28 -0
- package/modules/government/catalog.js +2 -2
- package/modules/government/protected-surfaces.json +1 -0
- package/modules/grading/grade-engine.js +267 -0
- package/modules/grading/grader-subagent.js +4 -3
- package/modules/grading/grader-workers/index.js +67 -11
- package/modules/grading/grader-workers/worker-verdict.js +32 -2
- package/modules/grading/grader.js +109 -88
- package/modules/hall-ui/public/deploy.js +35 -0
- package/modules/hall-ui/public/project-settings.css +7 -0
- package/modules/lifecycle/routes/tasks.js +19 -4
- package/modules/lifecycle/ship-assurance.js +17 -1
- package/modules/provisioning/control-plane-guard.js +14 -13
- package/modules/provisioning/core-upgrade.js +30 -17
- package/modules/provisioning/public-refusal.js +44 -0
- package/modules/provisioning/routes/disconnect.js +2 -1
- package/modules/provisioning/routes/env-manifest.js +5 -4
- package/modules/provisioning/routes/provisioning.js +16 -15
- package/modules/provisioning/routes/repo-private.js +2 -1
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +80 -0
- package/scripts/gds/autobongos-run.js +10 -2
- package/scripts/gds/backfill-cost.js +20 -9
- package/scripts/gds/claim.js +2 -2
- package/scripts/gds/credential-presence.js +281 -0
- package/scripts/gds/deploy-main-audit-gate.sh +11 -4
- package/scripts/gds/dev-lib.js +212 -5
- package/scripts/gds/dev.js +102 -50
- package/scripts/gds/doctor.js +3 -2
- package/scripts/gds/grade-correlation-audit.js +280 -0
- package/scripts/gds/grade-replay.js +237 -0
- package/scripts/gds/hooks/pre-push.js +7 -3
- package/scripts/gds/main-audit.js +19 -10
- package/scripts/gds/memory-map.js +3 -1
- package/scripts/gds/onboarding-config.js +3 -2
- package/scripts/gds/plain-cards.js +4 -0
- package/scripts/gds/preflight.js +12 -4
- package/scripts/gds/provision-core-upgrade.js +155 -4
- package/scripts/gds/provision-repo-auth.js +15 -0
- package/scripts/gds/provision.js +1 -1
- package/scripts/gds/publish-credential-check.js +3 -0
- package/scripts/gds/push-main.js +14 -3
- package/scripts/gds/push-path-brief.js +3 -2
- package/scripts/gds/run-routine.js +18 -5
- package/scripts/gds/run-unit-tests.js +14 -3
- package/scripts/gds/session-cost.js +12 -3
- package/scripts/gds/ship-deploy-target.js +11 -6
- package/scripts/gds/ship-grade-steps.js +33 -0
- package/scripts/gds/ship-land.js +157 -11
- package/scripts/gds/ship-merge.js +3 -2
- package/scripts/gds/ship-preflight-steps.js +30 -8
- package/scripts/gds/ship.js +1 -1
- package/scripts/gds/upgrade.js +3 -3
- package/scripts/hall-preview/README.md +20 -3
- package/scripts/hall-preview/live-identity.js +1 -1
- package/scripts/hall-preview/refresh-fixtures.js +71 -11
- package/scripts/hall-preview/scrub-identity.js +296 -0
- package/src/bongos/core-update.js +23 -1
- package/src/bongos/routes/core-update.js +27 -2
- package/src/bongos/routes/security.js +3 -3
- package/src/build-info.js +4 -2
- package/src/module-api.js +1 -1
- package/tests/adr_0089_scope.mjs +70 -0
- package/tests/autobongos_cadence.mjs +74 -0
- package/tests/consumer_layout_boot.mjs +363 -31
- package/tests/core_upgrade_door.mjs +40 -6
- package/tests/core_upgrade_runner.mjs +240 -4
- package/tests/credential_presence.mjs +153 -0
- package/tests/deploy_audit_gate.mjs +5 -2
- package/tests/deploy_page_projects.mjs +63 -2
- package/tests/dev_lib.mjs +2 -1
- package/tests/dev_windows.mjs +324 -0
- package/tests/env_knobs_neutral_prefix.mjs +203 -0
- package/tests/fixtures/grade-replay/recorded-panel-grades.json +27 -0
- package/tests/government_protected_surfaces.mjs +10 -0
- package/tests/grade_correlation_audit.mjs +159 -0
- package/tests/grade_engine.mjs +249 -0
- package/tests/grade_engine_replay.mjs +99 -0
- package/tests/grader_prompt_window_bound.mjs +132 -0
- package/tests/grader_unbacked_score.mjs +194 -0
- package/tests/hall_preview_scrub.mjs +214 -0
- package/tests/integration_parked_ratchet.mjs +24 -1
- package/tests/provisioning_public_refusal.mjs +195 -0
- package/tests/publish_status_branch.mjs +128 -0
- package/tests/routine_observability_api.mjs +195 -0
- package/tests/ship_assurance.mjs +86 -3
- package/tests/ship_land_red_pr.mjs +236 -0
- package/tests/ship_preflight.mjs +67 -1
- package/tests/start_env_guard.mjs +16 -0
- package/tests/upgrade.mjs +20 -1
package/src/build-info.js
CHANGED
|
@@ -8,13 +8,15 @@
|
|
|
8
8
|
// deployedCommit === mergeCommit before flipping a task to shipped.
|
|
9
9
|
//
|
|
10
10
|
// Resolution order (resolveCommit is pure + exported for the test):
|
|
11
|
-
// 1. env
|
|
11
|
+
// 1. env <PREFIX>_GIT_SHA (BONGOS_GIT_SHA on a vanilla instance; the legacy
|
|
12
|
+
// OTB_GIT_SHA is still read) — set by ~/deploy.sh at restart if/when it chooses to;
|
|
12
13
|
// authoritative + cheap, and survives a checkout with no usable .git.
|
|
13
14
|
// 2. `git rev-parse HEAD` in the checkout — accurate after deploy.sh's
|
|
14
15
|
// `git reset --hard origin/main`.
|
|
15
16
|
// 3. null — unknown (callers must degrade gracefully, never hard-fail).
|
|
16
17
|
|
|
17
18
|
const { execSync } = require('node:child_process');
|
|
19
|
+
const { resolveEnv } = require('./instance-config');
|
|
18
20
|
|
|
19
21
|
const SHA_RE = /^[0-9a-f]{7,40}$/i;
|
|
20
22
|
|
|
@@ -62,7 +64,7 @@ let _cache = null;
|
|
|
62
64
|
// restarts the service), so caching is correct and keeps /version allocation-free.
|
|
63
65
|
function buildInfo() {
|
|
64
66
|
if (_cache) return _cache;
|
|
65
|
-
const fromEnv = resolveCommit({ envSha:
|
|
67
|
+
const fromEnv = resolveCommit({ envSha: resolveEnv('GIT_SHA') });
|
|
66
68
|
const commit = fromEnv || resolveCommit({ gitSha: readGitSha() });
|
|
67
69
|
_cache = {
|
|
68
70
|
commit,
|
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.1035'; // 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,70 @@
|
|
|
1
|
+
// tests/adr_0089_scope.mjs — ADR 0089 §8 names what the grading engine does NOT own,
|
|
2
|
+
// and this file keeps that list true (task 1002844).
|
|
3
|
+
//
|
|
4
|
+
// WHY. Four surfaces spend model tokens on the repository or guard the pipeline,
|
|
5
|
+
// so a reader planning the engine can take them for graders: the BFG session
|
|
6
|
+
// evaluator, gate-review, main-audit and the Architect audit. §8 records, for each,
|
|
7
|
+
// exactly what it shares with the grader. A prose boundary rots the moment one of
|
|
8
|
+
// them quietly starts calling grading code, so the coupling the ADR states is
|
|
9
|
+
// asserted from the source: the Architect uses exactly the three plumbing helpers
|
|
10
|
+
// §8 names, and the other three import no grading module at all.
|
|
11
|
+
//
|
|
12
|
+
// Run: node tests/adr_0089_scope.mjs
|
|
13
|
+
|
|
14
|
+
import { strict as assert } from 'node:assert';
|
|
15
|
+
import fs from 'node:fs';
|
|
16
|
+
|
|
17
|
+
let passed = 0;
|
|
18
|
+
let failed = 0;
|
|
19
|
+
function test(name, fn) {
|
|
20
|
+
try { fn(); passed++; console.log(` ok ${name}`); }
|
|
21
|
+
catch (err) { failed++; console.log(` FAIL ${name}`); console.log(` ${err.message}`); }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const read = (rel) => fs.readFileSync(new URL(`../${rel}`, import.meta.url), 'utf8');
|
|
25
|
+
const adr = read('docs/adr/0089-modular-multi-model-adversarial-grader.md');
|
|
26
|
+
const section = adr.slice(adr.indexOf('### 8. Scope: what the engine does NOT own'), adr.indexOf('## Consequences'));
|
|
27
|
+
|
|
28
|
+
const SURFACES = [
|
|
29
|
+
'scripts/gds/session-eval.js',
|
|
30
|
+
'scripts/gds/gate-review.js',
|
|
31
|
+
'scripts/gds/main-audit.js',
|
|
32
|
+
'scripts/gds/architect-audit.js',
|
|
33
|
+
];
|
|
34
|
+
|
|
35
|
+
test('ADR 0089 carries the §8 scope section, before Consequences', () => {
|
|
36
|
+
assert.ok(adr.includes('### 8. Scope: what the engine does NOT own'), 'the section heading');
|
|
37
|
+
assert.ok(section.length > 200, 'the section sits between §7 and Consequences');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
test('§8 names each of the four surfaces by path, and each path exists', () => {
|
|
41
|
+
for (const p of SURFACES) {
|
|
42
|
+
assert.ok(section.includes(p), `§8 names ${p}`);
|
|
43
|
+
assert.ok(fs.existsSync(new URL(`../${p}`, import.meta.url)), `${p} exists`);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('the Architect uses exactly the three grader helpers §8 names — nothing from the grade path', () => {
|
|
48
|
+
// Code only: a comment that mentions grader.<thing> is not a call.
|
|
49
|
+
const src = read('scripts/gds/architect-audit.js').replace(/\/\*[\s\S]*?\*\//g, '').replace(/^\s*\/\/.*$/gm, '');
|
|
50
|
+
const used = [...new Set([...src.matchAll(/\bgrader\.([A-Za-z_]\w*)/g)].map((m) => m[1]))].sort();
|
|
51
|
+
assert.deepEqual(used, ['extractAssistantResult', 'extractJson', 'runSubagentCached'],
|
|
52
|
+
'a new grader.* call from the Architect means §8 is out of date');
|
|
53
|
+
for (const name of used) assert.ok(section.includes(name), `§8 names ${name}`);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('session-eval, gate-review and main-audit import no grading module', () => {
|
|
57
|
+
for (const p of SURFACES.filter((s) => !s.endsWith('architect-audit.js'))) {
|
|
58
|
+
assert.doesNotMatch(read(p), /require\([^)]*modules\/grading/, `${p} must not require grading code`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('main-audit and gate-review share only the rank-permission checker §8 names', () => {
|
|
63
|
+
for (const p of ['scripts/gds/main-audit.js', 'scripts/gds/gate-review.js']) {
|
|
64
|
+
assert.match(read(p), /permission-path-check/, `${p} reads the checker`);
|
|
65
|
+
}
|
|
66
|
+
assert.ok(section.includes('src/bongos/permission-path-check.js'), '§8 names the shared checker');
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
console.log(`\n${passed} passed, ${failed} failed`);
|
|
70
|
+
process.exit(failed === 0 ? 0 : 1);
|
|
@@ -600,3 +600,77 @@ test('the suite never reads the real heartbeat file', () => {
|
|
|
600
600
|
// writing right now.
|
|
601
601
|
assert.match(runner.heartbeatPath(), /ab-cadence-/, 'the suite must point at a throwaway path, not the real one');
|
|
602
602
|
});
|
|
603
|
+
|
|
604
|
+
// --- a worker that never RAN is breakage, not quiet (task 1004179) ----------
|
|
605
|
+
//
|
|
606
|
+
// Found by the 1003907 proof run. With the Windows argv bug in play every worker
|
|
607
|
+
// exited in ~2s with "worker output was not JSON". Each run filed a blocker,
|
|
608
|
+
// parked a task, and was classed `quiet` — which neither trips nor forgives the
|
|
609
|
+
// failure count. consecutive_failures stayed 0, mode stayed `full`, and the
|
|
610
|
+
// runner would have worked through the whole allowlisted goal one task every
|
|
611
|
+
// five minutes, parking every one, while the hall showed it alive and allowed to
|
|
612
|
+
// work. A human stopped it after one task.
|
|
613
|
+
|
|
614
|
+
// The exact row the runner logged on the night this was found.
|
|
615
|
+
const brokenWorkerRow = {
|
|
616
|
+
event: 'worked',
|
|
617
|
+
task_id: '1004047',
|
|
618
|
+
outcome: 'worker_failed',
|
|
619
|
+
reason: 'worker output was not JSON',
|
|
620
|
+
duration_s: 2,
|
|
621
|
+
cost_usd: null,
|
|
622
|
+
verified: false,
|
|
623
|
+
ledger_shape: 'still_held',
|
|
624
|
+
claim_released: true,
|
|
625
|
+
task_parked: true,
|
|
626
|
+
};
|
|
627
|
+
|
|
628
|
+
test('the real broken-worker row is a FAILURE, not quiet', () => {
|
|
629
|
+
const c = cadence.classifyEvent(brokenWorkerRow);
|
|
630
|
+
assert.notEqual(c.class, 'quiet', 'this is the exact misclassification the task exists to fix');
|
|
631
|
+
assert.ok(cadence.COUNTS_AS_FAILURE.has(c.class), 'and it must advance the failure count');
|
|
632
|
+
assert.match(c.detail, /never ran/);
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
test('three broken workers drop the runner out of full speed', () => {
|
|
636
|
+
let state = cadence.START;
|
|
637
|
+
for (let i = 0; i < 3; i++) {
|
|
638
|
+
state = cadence.nextCadence(state, cadence.classifyEvent(brokenWorkerRow));
|
|
639
|
+
}
|
|
640
|
+
assert.equal(state.mode, 'probing',
|
|
641
|
+
'the whole point: a runner that cannot spawn must stop chewing the queue');
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
test('a worker that RAN and hit a real obstacle is still quiet', () => {
|
|
645
|
+
// 1003564: 31 minutes, real cost, stopped at a grader refusal. The machine is
|
|
646
|
+
// fine and the next task is the right move — escalating this would "fix" a
|
|
647
|
+
// working runner into a broken one.
|
|
648
|
+
const c = cadence.classifyEvent({
|
|
649
|
+
event: 'worked', outcome: 'needs_human', reason: 'the grader refused the ship',
|
|
650
|
+
duration_s: 1888, cost_usd: 13.74, verified: false, ledger_shape: 'ungraded',
|
|
651
|
+
});
|
|
652
|
+
assert.equal(c.class, 'quiet');
|
|
653
|
+
});
|
|
654
|
+
|
|
655
|
+
test('a worker that burned real time and then failed is NOT "never ran"', () => {
|
|
656
|
+
// A 90-minute timeout is breakage of a different kind, and this predicate must
|
|
657
|
+
// not swallow it by calling it a failed launch.
|
|
658
|
+
assert.equal(cadence.workerNeverRan({ outcome: 'worker_failed', duration_s: 5400, cost_usd: 9.1 }), false);
|
|
659
|
+
});
|
|
660
|
+
|
|
661
|
+
test('a spawn error is "never ran" whatever the numbers say', () => {
|
|
662
|
+
assert.equal(cadence.workerNeverRan({ outcome: 'worker_failed', spawn_error: 'ENOENT' }), true);
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
test('a fast worker that still cost something is not called a failed launch', () => {
|
|
666
|
+
assert.equal(cadence.workerNeverRan({ outcome: 'worker_failed', duration_s: 4, cost_usd: 0.4 }), false,
|
|
667
|
+
'it ran; both conditions are required');
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test('unworkable_queue is still never escalated', () => {
|
|
671
|
+
// The sibling distinction: a queue where every task halts is a HEALTHY machine
|
|
672
|
+
// with nothing to do. This fix must not blur the two.
|
|
673
|
+
const c = cadence.classifyEvent({ event: 'nothing_claimable', skipped: [{ id: '1', title: 't', reasons: ['x'] }] });
|
|
674
|
+
assert.equal(c.class, 'unworkable_queue');
|
|
675
|
+
assert.equal(cadence.COUNTS_AS_FAILURE.has('unworkable_queue'), false);
|
|
676
|
+
});
|