agentleFS
kfchoukfchou/wiki-skills/skills/wiki-lint/SKILL.md

wiki-lint

Skill189 starsChanged 4 months agoMITView on GitHub

Use when auditing a wiki for health issues — contradictions between pages, orphan pages, broken cross-references, stale claims, missing pages, or coverage gaps. Run after every 5-10 ingests.

42 other projects use a version of this, 1 of them edited.

Adopted by

Most recently taken up by

Used with

Projects with it also use wiki-capture, wiki-status and 8 more.

Other files people use alongside this one.

Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
  • jehrhardtSkill

    wiki-capture

    Quickly capture raw thoughts, links, images, or notes to today's Obsidian daily note from anywhere in Pi. Use when the user wants to jot something down for later wiki processing.

    Also in 6 projects that use this

  • nexuschainsSkill

    wiki-status

    Reports the current state of the wiki vault — page counts, category breakdown, hub pages, orphans, stale entries, and a delta showing what has changed since the last ingest. Use this skill when the operator asks "what's the status", "wiki dashboard", "how many pages", "what's stale", "what's been ingested", "show me the delta", or "wiki health overview". Also surfaces structural insights (top hubs, fragmented clusters, bridge pages) when the operator asks "wiki insights", "what's central", or "show me the hubs". Read-only: this skill reports and recommends; it does not modify any files.

    Also in 5 projects that use this

  • nexuschainsSkill

    cross-linker

    Scans the wiki vault and adds missing [[wikilinks]] between pages that are related but not yet connected. Use this skill when the operator says "link my pages", "find missing links", "cross-reference the wiki", "connect my wiki", "add wikilinks", or after any large ingest to weave new pages into the existing knowledge graph. Also trigger when orphaned pages need connecting or when wiki-lint reports fragmented tag clusters. This is a write-heavy skill — it modifies page files to insert links, unlike wiki-lint which only reports.

    Also in 4 projects that use this

  • Ivy-Chen1999Skill

    wiki-synthesize

    Systematically discover synthesis opportunities across the Obsidian wiki — pairs or clusters of concepts that co-occur frequently across pages but have no synthesis page connecting them. Creates new synthesis/ pages that draw explicit cross-cutting conclusions. Use when the user says "synthesize my wiki", "find connections", "what concepts keep coming up together", "/wiki-synthesize", or after a large ingest when the vault has grown significantly.

    Also in 4 projects that use this

  • Ivy-Chen1999Skill

    wiki-setup

    Initialize a new Obsidian wiki vault with the correct structure, special files, and configuration. Use this skill when the user wants to set up a new wiki from scratch, initialize the vault structure, create the .env file, or says things like "set up my wiki", "initialize obsidian", "create a new vault", "get started with the wiki". Also use when the user needs to reconfigure their existing vault or fix a broken setup.

    Also in 5 projects that use this

  • +1 more from nexuschains
  • +4 more from Ivy-Chen1999

The file

We split this skill into the rules it gives an agent

3 rules. 0 are common, 1 is distinctive, and 2 are very specific to this project.

  • 0

    Common

    Most of the 33 edited versions we read keep these.

  • 1

    Distinctive

    This author's own choices. Worth a look.

  • 2

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run python bin/lint-mechanical.py and parse its JSON.

    line 44
  2. Distinctive:

    Do not re-derive these by reading pages yourself — the script is the source of truth.

    line 66
  3. Very specific:

    Aggregate: all subagent findings in the main thread and dedup on (type, sorted(pages), detail-entity) — a page in K tags sits in K …

    line 88

“Common” is measured: kept by at least 6 in 10 of the 33 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Wiki Lint

Audit the wiki as a four-phase pipeline that keeps page bodies out of the main context: a deterministic script (Phase 1) and per-cluster subagents (Phase 2) do the heavy reading; the main thread only assembles findings. Produce a categorized report, offer concrete fixes, log the operation.

Pre-condition

Find SCHEMA.md (search from cwd upward, or ~/wikis/). If not found, tell the user to run wiki-init first. Read it to get wiki root path and conventions.

Link style. Read link_style: from SCHEMA.md. If the field is missing or <wiki-root>/config/link-style.md does not exist, default to obsidian ([[slug]]). Otherwise, read <wiki-root>/config/link-style.md. All link scanning below uses the ## Parse rule from that file (which may match more than one form). The lint report you write is itself a wiki page, so its cross-references use the ## Emit rule.

Why the pipeline

The old whole-wiki pass loaded every page body into one context — it nuked the context window as the wiki grew. Instead:

  • Phase 1 runs bin/lint-mechanical.py, which computes the deterministic checks (graph and string properties) with no LLM and no bodies in your context, and emits the tag-cluster list for Phase 2.
  • Phase 2 dispatches one subagent per tag cluster. Each reads only its cluster's pages (bodies live in the subagent's context, discarded on return) and reports the cross-page and body-level findings. You aggregate compact findings, never bodies.

Phase 1 checks are whole-wiki exhaustive. Phase 2 checks are cluster-scoped: a page that shares no tag with any other page is not body-checked (approach A's accepted recall limit — see Phase 2). Run lint periodically (every 5–10 ingests) so the scoped passes accumulate coverage.

Process

Phase 0 — regenerate the index

python bin/generate-index.py so the index reflects current page frontmatter.

Phase 1 — deterministic checks (script, no LLM)

Run python bin/lint-mechanical.py and parse its JSON. It returns:

{ "findings": { "broken_links": [...], "missing_frontmatter": [...], "orphans": [...],
                "slug_collisions": [...], "stale_date": [...], "missing_concept": [...] },
  "clusters": [ {"pages": ["slug-a", "slug-b"], "split": false}, ... ] }

These map to report sections directly:

  • 🔴 Broken links — broken_links ({page, link}).
  • 🔴 Missing frontmatter — missing_frontmatter ({page, missing:[...]}). overview.md lives in wiki/, not wiki/pages/, and is exempt.
  • 🟡 Orphan pages — orphans ({page}): zero inbound [[slug]] links.
  • 🟡 Colliding slugs — slug_collisions ({token, pages:[...]}): a bare slug clashing with qualified ones (mercury vs mercury-element). Flag the pair; never auto-rename — renaming is a wiki-merge split.
  • 🟡 Stale claims — stale_date ({page}): not updated in 90 days and the body still says current/latest/recent/state-of-the-art or names a year ≥2 years old.
  • 🔵 Missing concept pages — missing_concept ({slug, count}): a [[slug]] referenced 3+ times with no page.

Do not re-derive these by reading pages yourself — the script is the source of truth.

Phase 2 — cluster subagents (contradictions + body-level checks)

For each cluster in the Phase 1 clusters list, dispatch a subagent (parallel fan-out, batched to bound concurrency). Give it the cluster's page paths and this instruction:

Read these pages. Report, within these pages only, as a compact list — each finding as {type, pages:[slug,...], detail}, or clean if none:

  • contradiction — two pages describe the same entity with conflicting dates, counts, names, or relationships.
  • missing-xref — two pages clearly discuss the same entity but don't [[link]] each other.
  • merge-candidate — two pages describe the same concept under different slugs (near-duplicate titles / near-identical Description sections).
  • chronological-section — a page body carries date-stamped journal headers (## [Month], **[Month] N update) that should be integrated in-place.
  • addable-line-range — a footnote citing a text-addressable raw file (markdown / plaintext / code / cached HTML) with no L<start>-<end> token. Exempt: PDFs, transcripts, live URLs — never flag those. Return findings only — no page bodies.

Aggregate all subagent findings in the main thread and dedup on (type, sorted(pages), detail-entity) — a page in K tags sits in K clusters, so the same finding can surface more than once.

Coverage note: because subagents only see their cluster, body-level findings are cluster-scoped. Pages sharing no tag with any other page are not body-checked. This is the accepted limit of tag-cluster scoping; Phase 1 (graph/string checks) still covers every page.

Phase 3 — coverage gaps, then assemble the report

First, the one body-level check that needs no page bodies: read wiki/overview.md and flag 🔵 Coverage gaps — open questions that a web search or a new ingest could answer.

Then write wiki/pages/lint-<today>.md (do not ask permission — always write this), merging Phase 1 findings, the deduped Phase 2 findings, and the coverage gaps. The template below shows slug references in obsidian form for readability; in the actual report you write, every slug reference must follow the ## Emit rule from config/link-style.md:

---
title: Lint Report <today>
category: Maintenance
summary: <N> errors, <N> warnings, <N> info
tags: [lint, maintenance]
sources: []
created: <today>
updated: <today>
---

# Lint Report — <today>

## Summary
- 🔴 Errors: N
- 🟡 Warnings: N
- 🔵 Info: N
<!-- note here if any cluster was split (Phase 1 `split: true`): contradiction recall is
     reduced for those pages — they were too large a tag group to check together -->

## 🔴 Broken Links
- [[source-page]] references [[missing-slug]] — does not exist
  Fix: create the page or remove the reference

## 🔴 Missing Frontmatter
- [[page]] is missing: title, updated

## 🟡 Orphan Pages
- [[slug]] — no inbound links
  Fix: add link from [[related-page]], or delete if no longer relevant

## 🟡 Contradictions
- [[page-a]] says: "<claim>"
- [[page-b]] says: "<conflicting claim>"
  Recommendation: <which to trust, or "investigate further">

## 🟡 Stale Claims
- [[page]] last updated <date>, contains "latest" — may be outdated
  Fix: re-verify claims or add a "as of <date>" qualifier

## 🟡 Colliding Slugs
- [[mercury]] and [[mercury-element]] share base token "mercury" — possible undisambiguated homonym
  Fix: qualify the bare slug via wiki-merge split (e.g. mercury → mercury-planet)

## 🟡 Chronological Update Sections
- [[page]] has date-stamped journal headers — integrate the updates in-place

## 🔵 Missing Concept Pages
- [[slug]] referenced N times but no page exists
  Fix: run wiki-ingest or create a stub

## 🔵 Coverage Gaps
- Open question from overview.md: "<question>"
  Suggestion: search for <X> or ingest <source type>

## 🔵 Missing Cross-References
- [[page-a]] and [[page-b]] both discuss <entity> but don't link to each other

## 🔵 Merge Candidates
- [[page-a]] and [[page-b]] appear to describe the same concept under two slugs
  Fix: run wiki-merge to consolidate into one page (rewrites inbound links)

## 🔵 Addable Line-Ranges
- [[page]] [^3] cites text source [[markdown-source]] with no line-range
  Fix: add an `L<start>-<end>` token so wiki-audit can verify it deterministically

The lint report carries category: Maintenance in its frontmatter, so it lands in the index automatically — do not hand-edit index.md. Run python bin/generate-index.py.

Offer concrete fixes

For each fixable category, offer:

  • Broken links: "Remove the broken slug references? (I'll show each change before writing)"
  • Missing cross-references: "Add the missing links between these page pairs?" (emit in the wiki's link_style)
  • Colliding slugs / merge candidates: "These look like the same concept (or a homonym needing disambiguation) — want to run wiki-merge to consolidate or split them?" Do not fix these in wiki-lint; hand off to wiki-merge.
  • Orphan page tags: "Add status: orphan to frontmatter of orphan pages?"
  • Missing frontmatter: "Add missing frontmatter fields with placeholder values?"

Show the exact diff for each change before writing. Apply only after confirmation.

Record the operation

Per SCHEMA's Operation Log & Commit Convention:

  • Git wiki: suggest a commit (default Conventional Commits fix: when fixes were applied, chore: for a report-only run, plus the trailer); commit on confirmation.
    fix: resolve <what lint fixed>
    
    Wiki-Op: lint
  • Non-git wiki: append to wiki/log.md:
    ## [<today>] lint | <N errors> errors, <N warnings> warnings, <N info> info
    Report: <slug reference to lint-<today>, in the wiki's link_style>
    Fixed: <list what was auto-fixed, or "none">

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.