knowledge-lintv0.1.0

CASOON Open Source

Keep a Markdown knowledge base honest.

knowledge-lint checks a folder of Markdown entries with YAML frontmatter against the categories, types and status values you declare in one _types.yml. Undeclared folders, broken links, unencrypted secrets and missing attachments fail the run instead of drifting silently.

cargo install knowledge-lint
cargo install --git https://github.com/casoon/knowledge-lint
MITv0.1.0Rust CLINo runtime to install
knowledge-lint lint broken-knowledge-base
Checking broken-knowledge-base/secrets/api-token.yaml
  ERROR: file in a sops_secret category has no `sops:` metadata field — not SOPS-encrypted?
Checking broken-knowledge-base/decisions/2024-03-hosting.md
  WARNING: last_reviewed is 927 days old (> 365), but the entry is marked 'stable'
  ERROR: related link '../glossary/cdn.md' points to a file that doesn't exist
Checking broken-knowledge-base/decisions/2026-02-backups.md
  ERROR: status 'current' is not one of the allowed values (draft, stable, deprecated)
  ERROR: type 'process' does not match category 'decisions' (expected: 'decision')
Checking broken-knowledge-base/glossary/embedding.md
  WARNING: possible API key with prefix 'sk-' found — check whether this is a real secret
  ERROR: source is missing
  ERROR: last_reviewed '12.01.2026' is not a valid date (YYYY-MM-DD)
Checking broken-knowledge-base/meetings/
  ERROR: category 'meetings' is not declared in _types.yml
Checking broken-knowledge-base/_attachments.yml
  WARNING: attachment 'contract-scan' has no description
  ERROR: attachment 'contract-scan': path './assets/contract-2026.pdf' does not exist
  ERROR: attachment 'contract-scan': referenced_by entry 'decisions/2026-03-hosting-contract.md' points to a file that doesn't exist

0 of 3 knowledge entries are marked public.
9 error(s), 3 warning(s) found.
category kinds: entries, SOPS secrets, assets
3
commands: lint and clean
2
plaintext key markers scanned in every entry
10
exit code for warnings only / any error
0 / 1

What it does

  1. Categories are declared, not guessed

    Every folder in the knowledge directory needs an entry in _types.yml with its kind and expected type. A new category is a config change, and an undeclared folder is an error.

  2. Your own status vocabulary

    Status values and the one that means “still maintained” come from the config: current/deprecated by default, draft/stable/deprecated or aktuell/veraltet if you prefer.

  3. Reviews that come due

    With review_interval_days, an active entry whose last_reviewed date is too old gets a warning. Deprecated entries stay quiet.

  4. Secrets stay encrypted

    Files in a secrets category must be SOPS-encrypted. The check is structural and never decrypts. Entries are scanned for private-key headers and API-key prefixes.

  5. Links and attachments resolve

    related links, _attachments.yml paths and their referenced_by entries must exist. http(s) URLs get a HEAD request that only warns, so flaky CI networks do not fail the build.

Generated at build time

All examples →
knowledge-lint lint knowledge-base
Checking knowledge-base/secrets/example-credential.yaml
Checking knowledge-base/processes/entry-review.md
Checking knowledge-base/decisions/2026-01-vector-store.md
Checking knowledge-base/glossary/rag.md
Checking knowledge-base/glossary/chunking.md
  WARNING: last_reviewed is 469 days old (> 365), but the entry is marked 'current'
Checking knowledge-base/_attachments.yml

3 of 4 knowledge entries are marked public.
All checks passed (1 warning(s)).

A sample knowledge base with one entry past its review interval: warnings are reported, the run still exits 0. Captured from the release binary; the same output is in the showcase.

examples/output/lint-knowledge-base.txt

Quickstart

Install the binary, point it at the knowledge directory, and read the report. The documentation covers the config, every rule and CI usage.

  1. Install knowledge-lint from crates.io with cargo install.
  2. Declare your categories in knowledge/_types.yml.
  3. Run knowledge-lint lint; it exits 1 on any error.
terminalShell
# Install the binary
cargo install knowledge-lint

# Check the knowledge/ directory (the default)
knowledge-lint lint

# Or any other path
knowledge-lint lint docs/knowledge