Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/cad0p/pi-napkin/llms.txt

Use this file to discover all available pages before exploring further.

Before every distill spawn — whether triggered by the interval timer, a manual /distill, or session shutdown — pi-napkin runs a layered health check to confirm the vault is in a state that worktree-based distill can actually run against. The check is split into two cadences so the cost of routine session-start probes stays near-zero while the rare, slower git-state probes only fire when a worktree is about to be spawned.

Two cadences

CadenceWhenWhat it coversTypical cost
Fast-levelEvery session_start (every pi launch in the vault)Subdir vs legacy embedded layout, managed .gitignore block matches canonical content (auto-recover if drift), auto-init git init + initial commit if .git/ is missingSub-second (a handful of file probes)
Full-levelBefore every worktree-based spawn: manual /distill, each interval-timer fire, and session shutdownEverything fast-level covers, plus: .napkin/config.json is git-tracked, HEAD resolves to a commit, .napkin/config.json not gitignored outside the managed block, .napkin/distill/ not tracked in git, cache root writable, no orphaned worktree registry entries, no stale distill/* branches past the grace periodA few extra git probes; runs only when a worktree spawn is imminent
Fast-level findings surface as one-shot notifications at session start; the session continues regardless. Full-level findings are gated by category: auto-recoverable findings emit an info notification and distill proceeds; loud-error findings abort the spawn and emit an error notification.

Auto-recover findings

These are drift states the health check repairs in place. Each produces a single info-level notification and distill proceeds normally afterward.
  • Managed-block drift — the markers in .gitignore were reordered, content inside the block drifted from canonical, or canonical lines leaked outside the block into user territory. Resolution: the bracketed region is rewritten to canonical content and any leaked lines outside the markers are removed.
  • Untracked .napkin/config.json (full-level only) — the config file exists on disk but is not yet in git’s index. Worktrees are checked out via git worktree add HEAD, which only copies tracked files; an untracked config.json would never reach the worktree and distill would silently break. Resolution: the file is staged (git add) and committed so every subsequent worktree checkout includes it.
  • Vault HEAD resolves to a commit (full-level only) — the vault has a .git/ directory (from a hand git init) but has never had a commit, so git rev-parse --verify HEAD fails. Without a commit to pin to, git worktree add HEAD fails with fatal: invalid reference: HEAD. Resolution: an empty initial commit is seeded (git commit --allow-empty) so HEAD is valid before the worktree spawn.
  • Orphaned distill worktrees (full-level only) — a previous distill crashed and left a git worktree list registry entry pointing at a directory that no longer exists on disk. Stale entries accumulate if pi instances crash before cleanup. Resolution: git worktree prune --expire=now removes all registry entries pointing at missing directories.
  • Stale distill/* branches (full-level only) — a distill/* branch whose committerdate is older than 24 hours AND has no live worktree pointing at it. These are branches from distills that completed (or failed) but whose cleanup step didn’t delete the branch ref. Resolution: git branch -D <branch>. The reflog grace period gives you a recovery window — the branch tip remains reachable via git reflog for approximately two weeks.

Loud-error findings

These are conditions where auto-distill cannot safely proceed. Each produces an error-level notification and the distill spawn is aborted before any git work starts.
  • Subdir-layout violation — the vault uses napkin’s legacy embedded layout (config.json at <vault>/config.json with no .napkin/ subdir, where configPath === contentPath). Worktree-based concurrency requires the subdir layout because the worktree branch must track a .napkin/config.json that napkin’s findVault can resolve. Fix: follow the migration steps in the README to move the config into a .napkin/ subdir. Manual /distill continues to work on the legacy layout; only auto-distill requires migration.
  • .napkin/config.json gitignored outside managed block (full-level only) — a rule in user territory (outside the BEGIN/END markers, or in a parent-directory .gitignore, or in a global git ignore file) excludes config.json. Worktrees checked out from git would have no config to read, and future distills would silently break. Fix: find the rule with git check-ignore -v .napkin/config.json and remove it. Rules inside the managed block are reset automatically by the gitignore-block invariant and never trigger this error.
  • .napkin/distill/ tracked in git (full-level only) — the per-worktree session fork directory has been committed into the git index. This typically happens when someone ran git add -f .napkin/distill/ explicitly, or from a stale commit made before the managed .gitignore block was installed. Fix: untrack the directory with git rm --cached -r .napkin/distill/ and commit the result. pi-napkin does not auto-untrack because git rm --cached -r can discard staged changes without warning.
  • Cache root unwritable (full-level only)$XDG_CACHE_HOME/napkin-distill/<vault-hash>/ (typically ~/.cache/napkin-distill/…) cannot be created or written to. Worktrees are placed under this directory, so a non-writable cache root prevents any worktree spawn. Fix: check disk space and filesystem permissions on your home directory or ~/.cache, or point XDG_CACHE_HOME at a writable path and restart pi.

Opting out

Set distill.enabled = false in .napkin/config.json:
napkin --vault ~/path/to/vault config set --key distill.enabled --value false
With auto-distill disabled, pi-napkin runs no health checks, installs no managed .gitignore block, and never probes git state at session start. Manual /distill still works — it has no concurrency-safety prerequisites and requires neither git nor the subdir vault layout.
Health check findings are surfaced as one-shot notifications at session start. Once an auto-recovered finding fires and repairs the vault, the same finding will not fire again on the next session start — the vault is healthy for subsequent spawns. If you see a recurring auto-recover notification, it means something external is undoing the repair between sessions (for example, a script overwriting .gitignore).

Build docs developers (and LLMs) love