Expand ↗
Page list (55)

Finding Orphans and Dead Links

zetl check is the vault-health command. It reports three kinds of problem — dead links, orphan pages, and syntax errors — and optionally a fourth, SPL diagnostics, if you use the reasoning layer. Run it before a big refactor, before a publish, and in CI.

zetl check

Exits non-zero if anything at error level is found. That makes it a drop-in CI step.

The two main health signals

A dead link is a [[wikilink]] that points at a page that does not exist. You typed [[Zettelkasten Methog]] and meant [[Zettelkasten Method]]; or you deleted a page without updating the notes that cited it.

zetl check --dead-links

Two ways to fix each one:

  1. Create the page. If the link represents a real idea that deserves a page, the dead link is a prompt: go write the note. This is the positive use of dead links — they are a TODO list generated by your past self.
  2. Rename or delete the link. If the target was a typo, fix the typo. If the idea no longer deserves a page, remove the link or replace it with plain prose.

The zetl similar "Zettelkasten Methog" command (see Similar Pages) pairs naturally with dead-link review: for each dead link, check whether you meant an existing page.

Orphans

An orphan is a page with no inbound links and no outbound links. Nothing points at it; it points at nothing. It is disconnected from the graph.

zetl check --orphans

Two ways to treat each one:

  • Link it. If the page is real content (a book note, a meeting summary), wire it in. Add a [[link]] from an index page, a project page, or a daily note. This is usually the right move.
  • Delete it. If the orphan is a stale draft, a duplicate, or a half-thought you abandoned, delete it. Orphans are not neutral; they decay the signal-to-noise ratio of Searching and of your own browsing.

A zero-orphan vault is not a goal. Some orphans are intentional — a daily journal entry, say, that you never expect to link into the graph. Skim the list, act on the fixable ones, leave the rest.

Syntax errors

zetl check --syntax reports malformed wikilinks, malformed frontmatter, and other parse-level problems. These are usually copy-paste accidents. Fix them on sight.

zetl stats — the summary view

zetl stats
pages:           4,127
wikilinks:       9,844
dead links:          12
orphans:             31
most-linked:     Zettelkasten Method (84 inbound)
                 2026 Research Plan  (61 inbound)
                 ...

A pre-flight glance. Run it weekly; watch the dead-link and orphan counts trend. An unchanged dead-link count for a month means you are not actually reviewing them. --top N widens the most-linked section (default 10).

CI integration

The --fail-on flag controls exit code behaviour. Default is error; bump to warning if you want a strict CI that fails on anything at all.

# GitHub Actions, Woodpecker, whatever
zetl check --fail-on error

A typical pipeline step:

- name: vault health
  run: |
    zetl index
    zetl check --fail-on error

JSON output is automatic under a pipe, so you can also post results to a dashboard:

zetl check --json \
  | jq '{dead: .dead_links | length, orphans: .orphans | length}'

SPL diagnostics

If you use the reasoning layer (What is SPL), --spl surfaces Spindle-Lisp-specific problems: parse errors, duplicate labels, undefined references, unreachable literals.

zetl check --spl

Requires --features reason. A related flag, --drift, reports SPL blocks whose grounding facts have changed since the last theory build — the “your logic block is stale” warning.

Example: pre-publish pass

You are about to zetl build your public notes vault. A three-minute pass before the build:

zetl index --no-cache            # fresh index
zetl stats                       # eyeball the numbers
zetl check --dead-links          # fix typos, create missing pages
zetl check --orphans             # decide: link, delete, or leave
zetl check --fail-on error       # gate
zetl build

The exit code of the fourth command tells you whether to proceed.

Last changed by zetl · history

Backlinks