test(docs): the alias targets on live surfaces must match the docs today (red)

Verified 2026-10-02 against code.claude.com/docs/en/model-config and
/sub-agents: opus -> Opus 5.5 and sonnet -> Sonnet 5.5 (both default
effort medium), fable -> Fable 5.1 (default high), and a subagent
without effort: inherits the session level. Seven tracked files still
say Opus 4.8 / Sonnet 4.6 / Fable 5. History keeps its names; a
known-positive control proves the query can find them there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-02 21:42:13 +02:00
commit f555c281ea
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q

View file

@ -1954,3 +1954,69 @@ test('trekexecute Phase 7 says NO_CRITERIA out loud instead of failing silently'
'the report must carry the line the unreadable section starts on',
);
});
// Model-alias facts, verified 2026-10-02 against code.claude.com/docs/en/model-config
// (Anthropic API) and code.claude.com/docs/en/sub-agents: `opus` -> Opus 5.5 and
// `sonnet` -> Sonnet 5.5, both default effort `medium`; `fable` -> Fable 5.1, default
// `high`; a subagent without `effort:` inherits the session level. Live surfaces state
// what is true now; historical records keep what was true when written and are never
// rewritten. When an alias moves again, re-verify against the docs and fix the SOURCE.
const ALIAS_LIVE_SURFACES = [
'CLAUDE.md', 'README.md', 'docs/profiles.md', 'docs/operations.md',
...listMd('commands').map((f) => `commands/${f}`),
...listMd('agents').map((f) => `agents/${f}`),
];
const RETIRED_ALIAS_TARGETS = [
{ term: 'Opus 4.8', re: /Opus 4\.8/g },
{ term: 'Sonnet 4.6', re: /Sonnet 4\.6/g },
{ term: 'Fable 5', re: /Fable 5(?!\.\d)/g },
];
// History inside a live surface: an entry must hit EXACTLY its count (a stale one fails).
const ALIAS_HISTORY_EXEMPT = [
{ path: 'docs/operations.md', term: 'Sonnet 4.6', count: 1, reason: 'Path C measurement, closed 2026-05-05 on CC v2.1.128' },
];
const ALIAS_HISTORICAL = ['CHANGELOG.md', 'docs/cc-upgrade-2.1.181-decision-matrix.md'];
function aliasHits(rel, re) { return (read(rel).match(re) || []).length; }
test('model aliases: no live surface names a retired alias target as current', () => {
const offenders = [];
for (const rel of ALIAS_LIVE_SURFACES) {
for (const { term, re } of RETIRED_ALIAS_TARGETS) {
const n = aliasHits(rel, re);
const ex = ALIAS_HISTORY_EXEMPT.find((e) => e.path === rel && e.term === term);
const allowed = ex ? ex.count : 0;
if (n !== allowed) offenders.push(`${rel}: ${term} x${n} (allowed ${allowed})`);
}
}
assert.deepEqual(offenders, [], `retired alias targets on live surfaces: ${offenders.join(' · ')}`);
});
test('model aliases: known-positive control — the same query still finds every retired term in history', () => {
// Verifiseringsloven ansikt 4: the empty result above is a measurement only if the
// query CAN find. Every retired term must still hit in a historical record or an
// exact-count exemption.
const silent = RETIRED_ALIAS_TARGETS.filter(({ term, re }) =>
!ALIAS_HISTORICAL.some((rel) => aliasHits(rel, re) > 0)
&& !ALIAS_HISTORY_EXEMPT.some((e) => e.term === term)).map(({ term }) => term);
assert.deepEqual(silent, [], `no known-positive left for: ${silent.join(', ')}`);
});
test('model aliases: profiles.md states the current targets, defaults and session inheritance', () => {
const t = read('docs/profiles.md');
const axes = (t.split('\n## Model & effort axes\n')[1] || '').split('\n## ')[0];
assert.ok(axes.length > 0, 'docs/profiles.md must still carry the Model & effort axes section');
assert.match(axes, /Opus 5\.5[^\n]*\n?[^\n]*`medium`/, 'opus -> Opus 5.5, default effort `medium`');
assert.match(axes, /Sonnet 5\.5/, 'sonnet -> Sonnet 5.5');
assert.match(axes, /Fable 5\.1[\s\S]{0,120}`high`/, 'fable -> Fable 5.1, default effort `high`');
assert.match(axes, /inherits? the session/i, 'a subagent without `effort:` inherits the session level');
assert.ok(!/inherit the model default/.test(axes), 'unset `effort:` inherits the session, not the model default');
assert.ok(!/overrides effort entirely/.test(axes),
'`MAX_THINKING_TOKENS=0` has no effect on Opus 5.5, Sonnet 5.5 or the Fable models');
assert.match(axes, /maxEffortLevel/, 'effort is capped by `maxEffortLevel` / an organization cap, not by `availableModels`');
for (const f of ['CLAUDE.md', 'README.md']) {
for (const target of ['Opus 5.5', 'Sonnet 5.5', 'Fable 5.1']) {
assert.ok(read(f).includes(target), `${f} must name the current alias target ${target}`);
}
}
});