Skip to content

wiki lint: orphan pages, stale pages, dead links, uncited sections (roadmap 1.4) #726

Description

@joaovictor91123

What you're trying to do

ROADMAP.md's 1.4 milestone calls for "wiki lint: orphan pages, stale pages,
dead links, uncited sections" — none of the four exist today. Once a page
is approved, nothing re-checks it: a [[wikilink]] whose target is later
archived, a page nothing else links to, a page not touched in a year, or a
hand-edited page whose citation coverage eroded after approval all surface
nowhere. health.lint()/vouch lint is the equivalent sweep for claims
(broken citations, stale claims, dangling refs) — pages have no sibling.

What you've tried

  • wiki_render.backlinks() already computes the inbound-link map (used
    internally by render_moc), but nothing flags a page with zero entries.
  • wiki_render.resolve_link() link resolution is only exercised at render
    time (silently drops anything unresolved) and at compile.py's
    draft-approval gate (_first_dangling_link rejects a new draft with a
    dangling link) — never as a standing check against the live, approved
    page set.
  • compile.py's _citation_coverage() / MIN_CITATION_COVERAGE guardrail
    runs once, on a draft, before it's ever proposed — a page's body can
    drift after approval without re-triggering it.
  • render-wiki already excludes archived pages from the front door (fix(wiki): render-wiki includes archived pages in index and MOC #695);
    nothing extends that policy to say a link into an archived page is
    dead.

Suggested shape

kb.wiki_lint — a page-level sibling to kb.lint, registered the same
way (MCP kb_wiki_lint, JSONL kb.wiki_lint, CLI vouch wiki-lint),
reusing wiki_render's link index/backlinks and compile's
citation-coverage walk rather than reimplementing either:

  • orphan_page — zero inbound backlinks.
  • dead_wikilink — a [[link]] that doesn't resolve against the live
    (non-archived) page set.
  • stale_page — not updated in --stale-days (default 180, mirroring
    vouch lint --stale-days).
  • uncited_section — citation coverage below --min-coverage (default
    0.5, mirroring compile.py's own MIN_CITATION_COVERAGE).

Suggested severities: orphan_page as info (a root/index page is
naturally unlinked, not inherently wrong), the other three as warning
(actionable, matching stale_claim's existing severity) — none as error,
since none represent a data-integrity violation the way broken_citation
or dangling_relation do.

Compatibility considerations

Purely additive, read-only, no VEP needed — no object model, on-disk
layout, or existing kb.* method signature changes. Like
wiki_render's index/MOC/backlinks, this is a derived view over already-
approved pages, so it doesn't touch proposals.py, lifecycle.py, or the
review gate at all.

Alternatives

Folding these checks into health.lint()/kb.lint directly instead of a
new method — rejected because lint()'s docstring scopes it explicitly to
claim/proposal health, and its stale_after_days parameter already means
something different (claim confirmation, not page edit recency); a shared
stale_days flag with two different semantics under one method would be
confusing. A dedicated method mirrors how kb.lint and kb.doctor are
already two separate entry points for two different sweep scopes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions