--- name: ckb-lint description: Health-check the wiki/ — conformance, freshness, confidence decay, retention sweep, supersession detection, orphan detection, graph consistency, index/log consistency, and error-book entries — auto-fixing what it safely can and reporting the rest, then reminding the user to review and sync to origin. Also runs the same checks against each connector-backed libs//'s own generated index (see ckb-index-external), plus a source.yaml validity check, without ever touching a git-copy lib or a connector's source.yaml itself. Use when the user says "Lint", "health-check the wiki", "check the wiki", or asks for a periodic/scheduled wiki health check. This is the maintenance workflow routed by CLAUDE.md/AGENTS.md, distinct from `ckb-ingest` (which adds new content) and `ckb-sync-changes` (a pure git-level operation with no wiki synthesis at all). --- # Lint skill ## Purpose Health-check the local, mutable `wiki/` for structural rot: missing or malformed frontmatter, stale pages, decayed confidence, orphaned or archivable content, broken graph edges, and index/log drift. This is maintenance, not growth — it never adds new knowledge the way `ckb-ingest` does; it only checks and repairs the shape of what's already there. Implemented as a skill (rather than living inline in `CLAUDE.md`/`AGENTS.md`) so the full checklist only loads into context when actually invoked — on demand, or on a schedule if the user has set one up. This skill only ever writes within `wiki/` (including moves into `wiki/archived/`) and, for any connector-backed `libs//` (one with a `source.yaml` — see `CLAUDE.md`/`AGENTS.md` directory contract) where this user has local `access: write` (see `ckb-index-external`), within that connector's own agent-owned generated index (`index.md`/`entities/`/`graph/`/`log.md`). For a connector-backed `libs//` where this user is read-only (the default), findings against that index are reported only, never auto-fixed — the same access gate `ckb-index-external` applies to rebuilding applies here too. It never touches `linked/`, a git-copy `libs//`, or a connector's `source.yaml`/`source.local.yaml` — those stay immutable or user-owned — and it never touches this repo's own git remote; pushing the resulting changes is a separate, explicit step (see the final step below). ## Trigger phrases Use this skill when the user says: - "Lint" - "health-check the wiki" / "check the wiki" - "run the periodic/scheduled wiki check" Do **not** use this skill for "Ingest" / "Sync the wiki" (that's `ckb-ingest` — turning raw material into new wiki pages) or for "sync changes" / "sync with git" (that's `ckb-sync-changes` — reconciling this repo's own commit history with `origin`, no wiki content involved). ## How to run this skill Work through each check in order. A malformed page breaks every later check's ability to reason about it, so conformance comes first. Checks 1-9 below are written against `wiki/`, but the same checks also run a second time against each connector-backed `libs//`'s own generated index — scoped entirely to that one connector's `index.md`/`entities/`/ `graph/`/`log.md`. Auto-fixes there only happen where this user has local `access: write` for that source (see `ckb-index-external`); everywhere read-only, findings are reported but not applied. Findings and fixes there are logged in that connector's own `log.md`, never in `wiki/log.md`. A git-copy `libs//` (no `source.yaml`) and any `source.yaml`/ `source.local.yaml` are never touched by any of these checks. ### 1 — Conformance check Verify every non-reserved `.md` file under `wiki/` (i.e. excluding `index.md` and `log.md`) has parseable YAML frontmatter with a non-empty `type` field. Flag violations first, and treat flagged pages as unreliable input for the checks below rather than guessing at their intended type/content. ### 2 — Freshness check Scan every page whose `last_updated` exceeds its `freshness_window_days`. Flag as stale; suggest the user confirm or update the content — don't silently rewrite stale content yourself. ### 3 — Confidence decay Reduce `confidence` on pages not reinforced by a new source since the last check. Pages that fall below 0.3 confidence get flagged for re-review. ### 4 — Retention sweep Move `retention: low` pages older than 2× their `freshness_window_days` into `wiki/archived/`. Never delete — always move, and log the move (see Rule B in `CLAUDE.md`/`AGENTS.md`) with a note explaining why. ### 5 — Supersession detection When two pages appear to cover the same entity, check for contradictions. If one is clearly newer/better corroborated, add `supersedes` / `superseded_by` links between them. Preserve the older page rather than deleting it, but mark it stale. ### 6 — Orphan detection Find pages with no inbound links (`[[wikilinks]]` or `[markdown](path.md)` references from elsewhere in the wiki). Either add backlinks from relevant pages where an obvious connection exists, or move the orphan to `wiki/archived/` with a log note if no natural backlink exists. ### 7 — Graph consistency Verify every edge in `wiki/graph/edges.json` points to an existing entity page. Remove or fix broken edges; note what was removed rather than silently dropping entries. ### 8 — Index/log consistency Verify every subdirectory under `wiki/` that contains pages has an `index.md` listing all of them, and that no single change is recorded in both a subdirectory `log.md` and the root `wiki/log.md` (per the Recursive Index & Log Convention). Fix missing index entries and duplicate log entries directly. ### 9 — Error Book entry Record any systemic issue found above (a repeated broken pattern, a recurring format mismatch, the same kind of orphan appearing again) in `wiki/error-book.md` with its root cause, the fix applied, and the derived constraint that should prevent recurrence. A one-off, isolated issue doesn't need an Error Book entry — this is for patterns, not incidents. ### 10 — External source config check For each `libs//source.yaml`, verify it has a non-empty `connector` and `location` — report only, this file is never edited by any skill. If an `index:` block is present, verify it has a non-empty `store` and `location` too. Also flag (report only) a `libs//` that ambiguously has both real content files and a `source.yaml` — that's a configuration conflict for the user to resolve, not something to guess at. Don't flag a missing `libs//source.local.yaml` as an issue — its absence is the correct, read-only default (see `ckb-index-external`), not a gap to report or fix. ### Auto-fix vs. report Auto-fix what can be done safely and mechanically: broken links, missing backlinks, stale flags, missing index entries, duplicate log entries, dangling graph edges. Report anything that needs a judgment call (supersession decisions, low-confidence content, ambiguous orphans) rather than guessing on the user's behalf. ### Final step — Remind to review and sync This is always the last step, every time this skill makes any change at all to `wiki/`. Close with a short reminder — do not sync or push anything yourself here: > "Lint complete — see `wiki/log.md` for what changed (auto-fixed: ...; > flagged for your review: ...). Please review the changes, and once > you're happy with them, say 'sync changes' to commit and push them to > `origin`." If any connector-backed `libs//` was also touched, mention it separately (its own `log.md`, not `wiki/log.md`) rather than folding it into the same sentence. If the lint pass made no changes at all (clean bill of health, nothing to fix or flag), skip this reminder — there's nothing to review or sync. ## Edge cases - **Wiki is empty or near-empty** — report that there's little to lint yet; don't fabricate findings to look thorough. - **A page's frontmatter is unparseable** (not just missing `type`, but invalid YAML) — flag it prominently in the conformance check and skip it in every later numbered check rather than letting a parse error crash or silently mis-handle downstream logic. - **Retention sweep would archive a page that's clearly still in active use** (e.g. linked from a very recent `workload/` entry) — flag it for the user to confirm rather than auto-archiving; recency of use can override a stale `last_updated`/`retention` combination. - **Supersession is ambiguous** (two pages disagree and neither is clearly newer/better corroborated) — report the conflict rather than guessing which one wins. - **Repeated run with nothing changed since the last lint** — should produce essentially the same clean report each time; don't invent variation just to seem active. --- *Licensed under the Apache License, Version 2.0 — see [LICENSE](../../../LICENSE) at the repository root, or .*