SKL-002 (skill-listing budget) and CML char-budget now calibrate to a
resolved context window instead of always anchoring at 200k:
- resolveContextWindow(): --context-window <n> calibrates; 'auto' keeps the
conservative 200k anchor but marks advisory (model→window probing deferred
to B8b); no flag → 200k anchor, byte-identical to pre-B8 default.
- scaleForWindow(): linear off the 200k anchor (identity at the anchor).
- SKL + CML each keep an untouched default branch (window===200k && !advisory)
for byte-stability and a calibrated branch; advisory downgrades the budget
finding from a breach (low/medium) to info.
- Flag wired through scan-orchestrator + posture; runAllScanners resolves once
and threads { contextWindow } to scanners (others ignore the 3rd arg).
- CPS intentionally excluded: it has no window-anchored budget (fixed
150-line volatility heuristic), so there is nothing to calibrate.
15 new tests; e2e CLI verified (1M suppresses SKL-002, auto → info, default
unchanged); full suite 1279 green; snapshots byte-stable.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
2.9 KiB
JavaScript
76 lines
2.9 KiB
JavaScript
import { describe, it } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import {
|
|
CONTEXT_WINDOW_ANCHOR,
|
|
LARGE_CONTEXT_WINDOW,
|
|
resolveContextWindow,
|
|
scaleForWindow,
|
|
} from '../../scanners/lib/context-window.mjs';
|
|
|
|
// B8 — context-window calibration. resolveContextWindow turns the raw
|
|
// --context-window CLI value into { window, advisory } that SKL/CML calibrate
|
|
// their budgets with. The DEFAULT (no flag) must be byte-identical to the
|
|
// pre-B8 behavior: the conservative 200k anchor at full severity (advisory=false).
|
|
|
|
describe('resolveContextWindow — default (no flag) is the conservative anchor', () => {
|
|
it('undefined resolves to the 200k anchor, not advisory (byte-stable default)', () => {
|
|
const r = resolveContextWindow(undefined);
|
|
assert.equal(r.window, CONTEXT_WINDOW_ANCHOR);
|
|
assert.equal(r.advisory, false);
|
|
assert.equal(r.source, 'default');
|
|
});
|
|
|
|
it('null resolves to the conservative default', () => {
|
|
const r = resolveContextWindow(null);
|
|
assert.equal(r.window, CONTEXT_WINDOW_ANCHOR);
|
|
assert.equal(r.advisory, false);
|
|
});
|
|
});
|
|
|
|
describe('resolveContextWindow — explicit window', () => {
|
|
it('a numeric string calibrates to that window, not advisory', () => {
|
|
const r = resolveContextWindow('1000000');
|
|
assert.equal(r.window, 1_000_000);
|
|
assert.equal(r.advisory, false);
|
|
assert.equal(r.source, 'explicit');
|
|
});
|
|
|
|
it('a plain number is accepted', () => {
|
|
const r = resolveContextWindow(1_000_000);
|
|
assert.equal(r.window, 1_000_000);
|
|
assert.equal(r.advisory, false);
|
|
});
|
|
});
|
|
|
|
describe('resolveContextWindow — auto / unknown downgrades to advisory', () => {
|
|
it('"auto" keeps the conservative anchor but flags advisory (no model probe yet)', () => {
|
|
const r = resolveContextWindow('auto');
|
|
assert.equal(r.window, CONTEXT_WINDOW_ANCHOR, 'window stays the conservative anchor');
|
|
assert.equal(r.advisory, true, 'unknown window -> advisory, not a budget breach');
|
|
assert.equal(r.source, 'auto-unresolved');
|
|
});
|
|
|
|
it('"AUTO" is case-insensitive', () => {
|
|
assert.equal(resolveContextWindow('AUTO').advisory, true);
|
|
});
|
|
|
|
it('an invalid value falls back to the conservative default (not advisory)', () => {
|
|
for (const bad of ['banana', '0', '-5', '']) {
|
|
const r = resolveContextWindow(bad);
|
|
assert.equal(r.window, CONTEXT_WINDOW_ANCHOR, `"${bad}" -> anchor`);
|
|
assert.equal(r.advisory, false, `"${bad}" -> not advisory`);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('scaleForWindow — linear scaling off the 200k anchor', () => {
|
|
it('is the identity at the 200k anchor (byte-stable default)', () => {
|
|
assert.equal(scaleForWindow(4000, CONTEXT_WINDOW_ANCHOR), 4000);
|
|
assert.equal(scaleForWindow(40_000, CONTEXT_WINDOW_ANCHOR), 40_000);
|
|
});
|
|
|
|
it('scales 5x at the 1M window', () => {
|
|
assert.equal(scaleForWindow(4000, LARGE_CONTEXT_WINDOW), 20_000);
|
|
assert.equal(scaleForWindow(40_000, LARGE_CONTEXT_WINDOW), 200_000);
|
|
});
|
|
});
|