config-audit/commands/knowledge-refresh.md
Kjell Tore Guttormsen 0f9c091a14 feat(knowledge): knowledge-refresh — living register, deterministic stale core + web poll (v5.7 Chunk 3)
The 'living' half of the v5.7 living knowledge base. Same hybrid split as the
optimization lens (Chunk 2b): a deterministic, byte-stable, unit-tested core +
a web/judgment command shell.

- scanners/lib/knowledge-refresh.mjs: pure assessFreshness(register,
  {referenceDate, staleAfterDays=90}) — age-based fresh/stale classification of
  source.verified; referenceDate injected (never reads the clock) → fully
  deterministic. 15 tests.
- scanners/knowledge-refresh-cli.mjs: -cli (NOT an orchestrated scanner →
  scanner count stays 15, suite byte-stable). Read-only — never writes the
  register, never hits the network. --reference-date/--stale-after/--dry-run,
  exit 0/1/3. 8 tests.
- commands/knowledge-refresh.md (opus): CLI stale-report → re-verify each stale
  entry by re-reading its source.url → poll CC changelog + Anthropic blog →
  apply ONLY human-approved writes, then re-validate the register. No unverified
  claim is ever auto-written (Verifiseringsplikt). Web-driven → not byte-stable.

No new agent, no new orchestrated scanner. Docs/badges: commands 19→20,
tests 1068→1091 (20 lib + 32 scanner test files). self-audit A/A, readmeCheck passed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 19:22:57 +02:00

6.4 KiB

name description argument-hint allowed-tools model
config-audit:knowledge-refresh Keep the best-practices register fresh — flag stale entries, poll sources for new/changed practices, with human-approved writes only [--stale-after N] [--no-candidates] Read, Write, Edit, Bash, WebSearch, WebFetch opus

Config-Audit: Knowledge Refresh

The "living" part of the living knowledge base. The optimization lens (/config-audit optimize) is only as good as the best-practices register it reads — and Claude Code moves fast. This command keeps knowledge/best-practices.json current in two ways:

  • Stale check (deterministic): every CONFIRMED entry carries a source.verified date. An entry older than the threshold (default 90 days) is flagged for re-verification — its source may have changed since.
  • Candidate poll (web): scan the CC changelog + the Anthropic "Steering Claude Code" docs/blog for new best-practices the register doesn't yet hold, or changed guidance that contradicts an existing entry.

The Iron rule (Verifiseringsplikt): nothing is ever auto-written. Every change — a bumped verified date, an updated claim, a brand-new entry — is presented to the user and applied only on explicit approval, and only after the live source has actually been re-read. No unverified claim enters the register.

Implementation

Step 1: Parse arguments

From $ARGUMENTS:

  • --stale-after N → override the staleness threshold (integer days; default 90).
  • --no-candidates → run the deterministic stale check only; skip the web poll.

Tell the user what's happening:

## Knowledge Refresh

Checking the best-practices register for stale entries (sources that may need
re-verification) and polling for new Claude Code practices...

Step 2: Run the stale-check CLI

TODAY=$(date +%F)
STALE_AFTER=""
if echo "$ARGUMENTS" | grep -qE -- '--stale-after'; then
  STALE_AFTER="--stale-after $(echo "$ARGUMENTS" | sed -nE 's/.*--stale-after[ =]+([0-9]+).*/\1/p')"
fi
node ${CLAUDE_PLUGIN_ROOT}/scanners/knowledge-refresh-cli.mjs \
  --reference-date "$TODAY" $STALE_AFTER \
  --output-file ~/.claude/config-audit/sessions/knowledge-refresh.json 2>/dev/null; echo $?

Exit code 0 = all fresh, 1 = some stale (advisory, normal), 3 = real error → "The refresh check couldn't run — the register file may be missing or invalid."

Step 3: Read the payload + present stale entries

Read ~/.claude/config-audit/sessions/knowledge-refresh.json with the Read tool. It has counts {total, stale, fresh}, a stale[] array (each: id, verified, ageDays, url, claim), referenceDate, and staleAfterDays.

Present the stale entries as a markdown table (per the UX rules — never show the raw JSON):

Entry Claim (short) Verified Age (days) Source

If counts.stale === 0, say so plainly: "✓ All N register entries were re-verified within the last {staleAfterDays} days." Then continue to the candidate poll (unless --no-candidates).

Step 4: Candidate + source-change poll (web — skip if --no-candidates)

Tell the user this takes a moment ("Polling the changelog + Anthropic docs, ~20-40s...").

  1. Re-verify each stale entry. WebFetch the entry's source.url and check whether the claim it backs is still accurate. Three outcomes:
    • Still holds → propose bumping source.verified to today (no claim change).
    • Changed → propose an updated claim/recommendation quoting the new source text.
    • Cannot verify (page gone, paywalled, contradicts) → propose nothing; flag it "needs manual review" (Verifiseringsplikt: never bump a date you couldn't confirm).
  2. Look for new practices. WebSearch the CC changelog and the "Steering Claude Code" blog/docs for steering/config guidance not already represented by an entry's lensCheck. For each genuine new practice, draft a candidate entry (next free BP-<TOPIC>-NNN id, confidence: "confirmed" only if a primary source confirms it — otherwise mark inferred and do not present it as user-facing).

Step 5: Present everything for approval — write nothing yet

Group the proposals and ask the user to approve per item:

  • Re-verify (date bump): "{id} — source re-read, claim still holds → bump verified to {today}?"
  • Update (claim drift): show the old vs. new claim + the quoted source line.
  • New candidate: show the drafted entry (id, claim, mechanism, recommendation, source).
  • Needs manual review: list, with why it couldn't be auto-verified. (No write offered.)

Be explicit: "I will not change any file until you approve specific items."

Step 6: Apply approved writes (only the approved ones)

For each approved item:

  1. Edit knowledge/best-practices.json — bump source.verified, update the claim/ recommendation, or append the new entry. Keep the file's 2-space JSON formatting.
  2. If a knowledge/*.md mirror states the same fact, update it too so the human-readable mirror doesn't drift from the register.
  3. Validate before declaring done — re-run the register schema check and confirm zero errors:
    node --test ${CLAUDE_PLUGIN_ROOT}/tests/lib/best-practices-register.test.mjs 2>&1 | tail -5
    
    If validation fails, revert that edit and report it — never leave the register invalid.

Report exactly what changed (ids + fields), and what was deferred to manual review.

Step 7: Next steps

  • /config-audit optimize — the lens now reads the refreshed register; re-run it to pick up any new or changed mechanism-fit rules.
  • Re-run /config-audit knowledge-refresh --no-candidates anytime for a quick staleness scan without the web poll.
  • Commit the register change (knowledge/best-practices.json + any .md mirror) with a chore(knowledge): message so the provenance bump is in git history.

Notes

  • Deterministic core, web-driven shell. The stale classification is byte-stable and unit-tested (tests/lib/knowledge-refresh.test.mjs, tests/scanners/knowledge-refresh-cli.test.mjs); the candidate poll + writes are web/judgment-driven and deliberately not byte-stable (mirrors /config-audit optimize).
  • Read-only CLI. knowledge-refresh-cli.mjs never writes the register; all writes happen here, in the command, after approval.
  • The -cli suffix keeps it out of the scan-orchestrator, so the scanner count and the snapshot suite are unaffected.