Check the consensus-layer knowledge base (platform-sdk/docs/consensus-layer) for drift against the code. Runs the deterministic engine, then performs the semantic (prose-vs-code) reading and presents a combined report. Use when asked to check, refresh, or audit the consensus-layer KB.
Installs into .claude/skills of the current project.
Are you the author of Kb Freshness?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/hiero-ledger-kb-freshness)
---
name: kb-freshness
description: Check the consensus-layer knowledge base (platform-sdk/docs/consensus-layer) for drift against the code. Runs the deterministic engine, then performs the semantic (prose-vs-code) reading and presents a combined report. Use when asked to check, refresh, or audit the consensus-layer KB.
---
# KB freshness — orchestrate a run + semantic pass
You are running the consensus-layer KB freshness check. It has two layers:
1. A **deterministic Java engine** that resolves the KB's code anchors against the current checkout
and emits machine-readable findings. It **never** guesses — every assertion carries one-look
evidence.
2. A **semantic pass that you perform** — reading a topic's prose claims against the *current source
the engine located*, never from memory. This catches drift that is true-but-no-longer-accurate
prose, which no deterministic check can safely assert.
Follow these steps exactly. **Do not modify any KB or source files** — this check only reports.
## Step 1 — Run the deterministic engine
Run the bundled script and capture the output directory:
```bash
bash "${CLAUDE_SKILL_DIR}/scripts/run.sh"
```
> **Re-running is destructive — run once, then ask before re-running.** Each run regenerates every
> artifact in the output directory. If a report already exists there and you (or the user) are
> mid-remediation, do **not** re-run to "refresh" it — read the existing artifacts in place. Only
> re-run the engine when the user explicitly asks for a new run. (The runner copies the prior output
> to `<out>.bak.<timestamp>` as a backstop, but still treat a re-run as overwriting the working
> report — including the semantic worklist a remediation session is tracking against.)
It prints the output directory (default `<repo>/build/kb-freshness`). Read these artifacts from it:
- `report.md` — the human drift report (deterministic assertions a curator acts on). Its **Summary**
counts the pending semantic worklist (your Step 2 workload); its **Scan coverage** section states
what was scanned and checked; its **Root causes (rollup)** section groups findings that share one
underlying change.
- `findings.json` — the machine-readable finding set (stable ids; reproducible).
- `quiet-log.md` — unverifiable checks (generated/external symbols) — **not** drift.
- `auto-fix.md` — proposed line-reference and path corrections (applied only by `--fix`).
- `suggestions.md` — non-asserting did-you-mean hints for gone targets, including config-key
migrations (a gone key another record now declares) and ready link rewrites for misdirected doc
links.
- `coverage.md` — documentation gaps (coverage lane): undocumented code and config keys, config
records with no tunables section at all, topics anchoring no source, and cited topic slugs with no
document — **not** drift.
- `worklist.json` — the semantic worklist (below).
Do not re-derive or second-guess the deterministic findings; present them as-is.
## Step 2 — Semantic pass (you perform this)
Read `worklist.json`. Process **only** entries whose `status` is `review` or `unknown` (their
anchored source changed since `last_reviewed`, or freshness is unknown). Skip `fresh` entries.
**Fan out for large worklists.** When more than ~4 entries need processing, or a single entry lists
many changed sources (say, 10+), spawn one subagent per entry instead of reading everything in one
context: each subagent reads only its document and that entry's changed sources, judges the claims
by the rules below, and returns its `contradicted`-with-citation items (file + symbol/line per
claim). Merge the returns into one Advisory section, applying the same only-cited-contradictions
bar to what comes back — a subagent's uncited judgment is dropped exactly like your own. Small
worklists are faster inline; do not fan out for one or two entries.
For each `review` entry:
1. Read the document at `entryPath`.
2. Read the **current** source files listed in `changedPaths` (and any other source the document
anchors). Never rely on memory of what the code does — open the files.
3. For each **load-bearing prose claim** about behavior in the document, judge it three ways:
- `supported` — the current code backs the claim.
- `contradicted` — the current code makes the claim false, **or** names a symbol (method, class,
field, path) that no longer exists; a rename or removal counts even if the behavior survives.
- `can't-determine` — you cannot tell from the source available.
An `unknown` entry has no `changedPaths` to read — its `note` names why (usually
`no anchored sources`). Handle it by the note:
- `no anchored sources` — the document carries no mechanically-checkable code anchor. Some documents
are **expected** to be unanchored — `glossary.md`, `symptoms.md`, and the `README.md` indexes are
definitional or navigational, not code-describing: acknowledge them as `unknown` and move on, do not
hunt for code. For a document that *does* describe specific code but cites none (e.g. a topic, or an
ADR with no source), **locate** the code it describes (search by the class/component names in its
prose), judge its claims against it, and recommend anchoring the doc (add source citations) so future
runs can track freshness. If you cannot identify the code, say so — do not guess.
- `git unavailable` / `no commit dates for anchored sources` — freshness could not be dated; treat the
entry like `review` and read the sources the document anchors.
## Step 3 — Report only contradicted-with-citation
- Keep **only** `contradicted` claims, and **only** those where you can cite the specific current
code (file + symbol/line) that contradicts the specific claim. Drop `supported`,
`can't-determine`, and any `contradicted` you cannot cite.
- Present them in a clearly separated **`## Advisory (semantic)`** section, *after* and *distinct
from* the deterministic report. Never intermix semantic findings with deterministic assertions —
they are advisory, not facts the engine verified.
Each advisory item cites: the entry + claim, and the current code (path + symbol) that contradicts
it. An uncited judgment is dropped, not reported.
## Step 4 — Present the combined result
Show, in order:
1. The deterministic **report.md** (new drift, carried drift, resolved), summarized — lead with the
**Root causes (rollup)** section when present: one underlying code move often explains dozens of
findings, and the curator should read cause-level first.
2. Pointers to `quiet-log.md`, `auto-fix.md`, `coverage.md` for the non-drift lanes.
3. Your **`## Advisory (semantic)`** section (or "none" if nothing survived).
## Step 5 — Recommend next actions
Close with a short, concrete action list derived from this run (skip lines that do not apply):
1. **Apply the certain fixes**: if the summary counts anything under "Fixable now with `--fix`",
suggest re-running the engine with `--fix` (it applies exactly the `auto-fix.md` diffs).
2. **Hand-fix the GONE findings**: point at `suggestions.md` for did-you-mean hints — including
config-key migration hints and ready link rewrites; all of them need a human decision and are
never auto-applied.
3. **Close coverage gaps**: mention `coverage.md` items worth acting on (unanchored topics,
undocumented config keys, config records with no tunables section, topic slugs with no document).
4. **Close the review loop**: for each worklisted document whose semantic pass found every claim
`supported` (or whose contradictions have since been fixed), suggest bumping its `last_reviewed`
via `--mark-reviewed <entry-key>` (repeatable). A bare spec records the document's newest
anchored-source commit date — the state this run reviewed, shown as `newestAnchoredCommit` in
`worklist.json` — derived from the scanned checkout, never the wall clock (so a run against a stale
`main` never marks commits it did not review as reviewed); a document that anchors no source is
dated by the reviewed checkout's HEAD commit instead. Without the bump, every future run re-worklists
the same documents. Never suggest bumping a document that still has an unresolved contradiction
(which now includes a dangling reference to a renamed or removed symbol).
5. **Adopt the baseline**: after fixes are applied and re-checked, suggest `--write-baseline` (or
copying `baseline.proposed.tsv`) and triaging the rows.
Do **not** perform any of these yourself unless the user asks.
If the user asks to triage or dismiss a finding, explain the baseline flow (see the module README):
add the finding's `id` to `platform-sdk/consensus-kb-freshness/baseline/kb-freshness-baseline.tsv` with
`accepted`/`dismissed`/`deferred`. Do not edit the baseline yourself unless asked.