Skip to content
Back to skills

Kmd Lint

ASecurity

Health check for a markdown knowledge base (Obsidian-compatible, the LLM-wiki pattern) — personal or shared. Use whenever asked to lint, audit, check, review, or clean up a KB, on any scheduled hygiene/maintenance run, or when KB quality is in doubt (stale pages, contradictions, broken links, unprocessed sources, index drift). Drift is the KB's primary failure mode; if in doubt whether a lint pass is warranted, it is.

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 29, 2026
ai-agentspythongobashgit

Works with

  • cli

Security analysis

A100/100

Pro scans all 5 files and shows the line behind each finding

Scanned September 29, 2026

npx -y skills add yasik/kmd --skill kmd-lint --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Kmd Lint?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Kmd Lint
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/yasik-kmd-lint/badge)](https://www.skillsdirectory.com/skills/yasik-kmd-lint)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: kmd-lint
version: 0.3.1
description: Health check for a markdown knowledge base (Obsidian-compatible, the LLM-wiki pattern) — personal or shared. Use whenever asked to lint, audit, check, review, or clean up a KB, on any scheduled hygiene/maintenance run, or when KB quality is in doubt (stale pages, contradictions, broken links, unprocessed sources, index drift). Drift is the KB's primary failure mode; if in doubt whether a lint pass is warranted, it is.
---

# kmd-lint — KB health check

A knowledge base rots by default: indexes drift from pages, claims go stale,
duplicates accumulate, sources pile up un-ingested. Lint is the counter-force
and it is not optional — every production implementation of the LLM-wiki
pattern reports drift as *the* failure mode. Lint runs in two phases:
deterministic checks (a script — free, exhaustive) and judgment passes (you —
expensive, so spent only where scripts can't reach).

## Before you start

Locate the KB root and transport the same way kmd-ingest does (its
`references/obsidian-cli-transport.md` covers the Obsidian CLI, whose
`backlinks`/`orphans`/`unresolved` commands can corroborate graph
findings when available): a path you were given >
`$KMD_ROOT` > `.kmd.json` at the workspace root > a directory containing
`schema.md`/`log.md` > the default `kb/`. The script's `--kb` flag implements
this resolution. Then check for the **org extension**: if `.kmd.json` declares
an `"org"` key or the workspace has `_charter/ORG.md`, read
[references/org-extension.md](references/org-extension.md) — it changes how
findings are routed in Phase 3. Otherwise the core protocol below applies
as written.

## Phase 1 — mechanical checks (run the script first)

```bash
python3 scripts/lint_mechanical.py --kb <kb-root> --report --agent <your-name-or-agent-id>
```

This checks: broken wikilinks, invalid/missing frontmatter (including the
provenance rule), modified files under `sources/` (append-only violation,
via git — when the KB is not under git the script says so explicitly rather
than implying coverage), unreferenced sources (un-ingested intake; a
`skip` log entry closes a source intake reviewed and declined), orphan
pages, page updates with no LOG entry, oversized pages, and a missing or
stale `index.md` (fix: `recompile_index.py` from kmd-ingest). With
`--report` it writes a
report skeleton to `<kb>/.lint/<date>-mechanical.md` (or the `report_dir`
configured in `.kmd.json`) with empty **Judgment findings** and **Resolution**
sections for you to fill in. Use `--format json` to process findings
programmatically.

## Phase 2 — judgment passes (what scripts cannot catch)

Read `index.md` (or list pages) to plan the passes; read full pages only
where a pass flags something. Four passes, in order of value:

1. **Contradictions.** Cluster pages that speak about the same entity/topic
   (index descriptions and shared tags are good signals). Compare their
   claims. Two pages asserting incompatible facts is the highest-severity
   finding lint can produce — a KB that contradicts itself is worse than no
   KB, because it answers confidently either way. When you find one, mark
   **both** pages with the `> [!contradiction]` callout per schema.md's
   framework (each side's claim, what would resolve it) — that marking IS a
   direct fix; the resolution itself is an open item unless dates, context,
   or primary sources settle it on the spot. The mechanical pass counts
   unresolved callouts on every future run.
2. **Staleness.** Pages whose `sources:` have newer material filed in
   `sources/` that they don't yet reflect; pages on volatile topics with
   old `updated` dates; claims with dates in them that have since passed.
   Flag, don't silently rewrite — the fix is a re-ingest against the newer
   source.
3. **Near-duplicates.** Pages whose titles/descriptions suggest the same
   concept split across two homes (the dedup gate at ingest time misses
   some). Propose a merge direction: which page survives, which becomes a
   redirect stub or is deleted after its unique content moves.
4. **Confidence downgrades.** Pages marked `confidence: high` whose sources
   are thin (single bare URL, no filed source) or contradicted elsewhere.
   Downgrading confidence is a cheap, honest fix you can apply directly.

## Phase 3 — triage and resolution

Every finding ends in exactly one of two places (core protocol):

- **Fixed directly** — mechanical, judgment-free repairs: a broken link whose
  target was renamed, a missing frontmatter field derivable from content, a
  confidence downgrade, an orphan page linked from the obvious related page.
  Every fix you apply is itself a KB write: follow the kmd-ingest protocol
  (bump `updated`/`author` on touched pages, validate, log with
  `--action lint`).
- **Recorded as open items** — anything requiring knowledge the linter
  doesn't have (which side of a contradiction is true, whether a merge loses
  nuance, whether a stale claim still holds): write it into the report's
  **Resolution** section as a concrete, actionable item for the KB owner.
  Un-ingested sources are open items too — each is a pending ingest, or a
  `kb_log.py --action skip` once someone has reviewed and declined it.

*Org installations route instead of recording* — judgment calls go to page
authors' inboxes, intake to the owning agent. See
[references/org-extension.md](references/org-extension.md); the report still
records every handoff.

Complete the report (all three sections), then log the pass:

```bash
python3 scripts/kb_log.py --action lint --agent <your-name-or-agent-id> \
    --title "lint pass: <N> errors, <M> warnings, <K> open items"
```

(`kb_log.py` ships with the kmd-ingest skill; a copy of the shared helpers is
bundled here — the log line matters more than which copy writes it.)

## What lint never does

- Rewrite page *content* wholesale — lint repairs structure and surfaces
  judgment; substantive rewrites are re-ingests
- Touch anything under `sources/` (append-only, even for lint) beyond
  restoring a tampered file to its committed state
- Hand-edit `index.md` (script-generated) or write log.md by hand
- Silently "fix" a contradiction by picking a side — surface it; the owner
  or a re-ingest against sources decides

## Done looks like

Script run clean or findings triaged → judgment passes done over the full
page set → report with all three sections filled → open items concrete enough
to act on (or handoffs delivered, in org mode) → one LOG entry. A lint pass
that only runs the script is half a lint pass.

Files in this skill

  • SKILL.md6.5 KB
  • references/org-extension.md3 KB
  • scripts/kb_common.py23.4 KB
  • scripts/kb_log.py6.9 KB
  • scripts/lint_mechanical.py15 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.