config-audit/tests/knowledge/knowledge-staleness.test.mjs
Kjell Tore Guttormsen 8376dab83f fix(tokens): refresh stale "Opus 4.7" framing to model-neutral + Opus 4.8 anchor
Fase 4 token-opt, Item 1 of gap-review NEXT STEP #2. The prompt-cache pattern corpus + TOK scanner were frozen at an "Opus 4.7" framing after CC shipped Opus 4.8 (default, 2.1.154) and Fable 5 (2.1.170). Model-era facts re-verified against the official changelog cache before editing.

The patterns are properties of prompt-caching, not of any model, so mechanic text is now model-neutral with a single "current default: Opus 4.8" anchor — preventing a re-freeze at the next model bump.

- rename knowledge/opus-4.7-patterns.md -> prompt-cache-patterns.md (git mv, history preserved); 6 reference sites updated
- TOK scanner: line-318 finding text (human-facing) made model-neutral; header + cache-prefix-scanner + CLI comments refreshed
- configuration-best-practices.md body + footnote 4.7 -> 4.8
- human-facing docs: commands/{tokens,help,manifest}.md, project CLAUDE.md, README, docs/scanner-internals.md
- gap-matrix row marked DONE; future Items 2/3 retargeted to new filename

Failing-test-first (Iron Law): +2 knowledge staleness guards (era-anchor + no-refreeze) +1 scanner assertion (no stale model anchor in finding text). Suite 853 -> 856 green; zero snapshot drift; self-audit A(97) PASS. CHANGELOG / v5 plan / ratified gap-plan keep historical opus-4.7-patterns refs (correct record of past state).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ter3E2JSi1Khgmuf2kady8
2026-06-18 15:27:36 +02:00

112 lines
5.9 KiB
JavaScript

// Knowledge-base staleness guard.
//
// The gap-review (CC 2.1.114->181) found config-audit's knowledge corpus frozen
// at ~v2.1.111, so it described an Opus-4.7 world after CC had shipped Opus 4.8
// and Fable 5. These assertions encode facts re-verified against the official
// Claude Code changelog (~/.claude/cache/changelog.md) on 2026-06-18 so the
// corpus cannot silently re-freeze. Each fact carries its verified version.
//
// Verified facts (official changelog, CC 2.1.181):
// Opus 4.8 default + high effort + /effort xhigh ... 2.1.154
// lean system prompt now default (except Haiku/Sonnet/4.7-) 2.1.154
// Claude Fable 5 (Mythos-class) .................... 2.1.170
// /simplify renamed to /code-review ............... 2.1.147
// /config key=value in-session settings ........... 2.1.181
// MessageDisplay hook event ....................... 2.1.152
// post-session lifecycle hook ..................... 2.1.169
// Stop/SubagentStop return additionalContext ...... 2.1.163 (NOT 2.1.165)
import { test } from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
const read = (rel) =>
readFileSync(fileURLToPath(new URL(`../../knowledge/${rel}`, import.meta.url)), 'utf8');
test('feature-evolution.md records the Opus 4.8 era (not frozen at v2.1.111)', () => {
const md = read('feature-evolution.md');
assert.match(md, /Opus 4\.8/, 'must record Opus 4.8 as the new default');
assert.match(md, /Fable 5/, 'must record Claude Fable 5');
assert.match(md, /2\.1\.170/, 'Fable 5 verified at v2.1.170');
assert.match(md, /2\.1\.154/, 'Opus 4.8 / xhigh / lean prompt verified at v2.1.154');
assert.match(md, /xhigh/, 'must record the /effort xhigh tier');
});
test('feature-evolution.md records the /simplify -> /code-review rename', () => {
const md = read('feature-evolution.md');
assert.match(md, /\/code-review/, 'bundled skill renamed to /code-review (2.1.147)');
});
test('feature-evolution.md records /config key=value', () => {
const md = read('feature-evolution.md');
assert.match(md, /\/config/, '/config key=value in-session settings (2.1.181)');
});
test('hook-events-reference.md header reflects 28 events, not 26', () => {
const md = read('hook-events-reference.md');
assert.match(md, /28 hook events/, 'count must be 28 after MessageDisplay + post-session');
assert.doesNotMatch(md, /26 hook events/, 'stale "26 hook events" must be gone');
});
test('hook-events-reference.md lists MessageDisplay and post-session events', () => {
const md = read('hook-events-reference.md');
assert.match(md, /MessageDisplay/, 'MessageDisplay hook event (2.1.152)');
assert.match(md, /post-session/, 'post-session lifecycle hook (2.1.169)');
});
test('hook-events-reference.md documents Stop/SubagentStop additionalContext at 2.1.163', () => {
const md = read('hook-events-reference.md');
// The feature shipped in 2.1.163 (NOT 2.1.165 — that release was bug fixes only).
assert.match(md, /SubagentStop[\s\S]*additionalContext|additionalContext[\s\S]*SubagentStop/,
'Stop/SubagentStop additionalContext output field must be documented');
assert.match(md, /2\.1\.163/, 'additionalContext for Stop/SubagentStop verified at v2.1.163');
});
test('claude-code-capabilities.md bundled skills use /code-review, not stale /simplify', () => {
const md = read('claude-code-capabilities.md');
assert.match(md, /\/code-review/, 'bundled-skill list must list /code-review');
assert.doesNotMatch(md, /\/simplify/, '/simplify was renamed to /code-review (2.1.147)');
});
test('claude-code-capabilities.md documents /config key=value', () => {
const md = read('claude-code-capabilities.md');
assert.match(md, /\/config/, '/config key=value in-session settings (2.1.181)');
});
// MCP `trust` is NOT a real .mcp.json field (verified 2026-06-18 against
// code.claude.com/docs/en/mcp + /settings). Approval is dialog/settings-based.
// These guards stop the corpus from re-fabricating the field.
test('claude-code-capabilities.md does not resurrect the invented MCP `trust` field', () => {
const md = read('claude-code-capabilities.md');
assert.doesNotMatch(md, /"trust":\s*"workspace/,
'the fabricated `trust` field must not return to the .mcp.json schema example');
assert.match(md, /enableAllProjectMcpServers|enabledMcpjsonServers/,
'must document the real MCP approval mechanism');
});
test('configuration-best-practices.md recommends real MCP approval, not a `trust` field', () => {
const md = read('configuration-best-practices.md');
assert.match(md, /enabledMcpjsonServers|enableAllProjectMcpServers/,
'must point to the real settings-based approval mechanism');
assert.doesNotMatch(md, /Set trust levels explicitly/,
'the invented "set trust levels" advice must be gone');
});
// Token-efficiency corpus era-anchor (Fase 4 token-opt). The prompt-cache pattern
// catalogue was frozen at an "Opus 4.7" framing after CC shipped Opus 4.8 (default,
// 2.1.154) and Fable 5 (2.1.170). The mechanics are properties of prompt-caching,
// not of a model, so the corpus anchors the current default (Opus 4.8) once and
// keeps the pattern text model-neutral — preventing a re-freeze at the next bump.
test('prompt-cache pattern catalogue is anchored to Opus 4.8, not frozen at Opus 4.7', () => {
const md = read('prompt-cache-patterns.md');
assert.match(md, /Opus 4\.8/, 'must name the current default model (Opus 4.8), not a stale 4.7 anchor');
assert.doesNotMatch(md, /Opus 4\.7/, 'all stale Opus-4.7 era-stamping must be gone from the pattern catalogue');
});
test('configuration-best-practices.md CLAUDE.md cost framing names Opus 4.8, not stale 4.7', () => {
const md = read('configuration-best-practices.md');
assert.match(md, /Opus 4\.8/, 'the cache-vs-length cost-lever framing must name the current default model');
assert.doesNotMatch(md, /On Opus 4\.7|Opus 4\.7 uses prompt-cache/,
'the present-tense Opus-4.7 cost framing (body + footnote) must be refreshed to 4.8');
});