---
title: "Vault Audit"
slug: "vault-audit"
category: "knowledge-vaults"
tags: ["knowledge-vaults", "audit", "linting", "quality-gates", "automation", "ci"]
status: "stable"
last_updated: 2026-08-29
summary: "Run a spec-driven deterministic auditor over a vault, triage findings by root cause rather than rule id, autofix only the mechanical tier, and re-run to show the delta."
related: ["[[knowledge-vaults/semantic-audit]]", "[[knowledge-vaults/vault-frontmatter-schema]]", "[[knowledge-vaults/vault-architecture]]", "[[knowledge-vaults/vault-maintenance]]", "[[knowledge-vaults/team-vaults]]", "[[knowledge-vaults/vault-orchestration]]", "[[tooling/github-actions]]"]
---

## Overview

A vault without an auditor degrades invisibly. Orphans accumulate, required fields go missing, verification dates go stale, and none of it announces itself. The auditor is a script that lives in the vault (`99-Tools/audit.py`), reads the vault spec, and reports structural and schema violations deterministically. Judgment-level defects are a separate pass, covered in [[knowledge-vaults/semantic-audit]].

## Split the checks into three buckets and automate the first two

- **Bucket 1, structural.** Orphans, broken links, missing frontmatter, filename convention, folder placement. Framework-agnostic.
- **Bucket 2, schema.** Framework-specific requirements: an ADR without alternatives, a theme atom with too few linked data points, a result atom with no hypothesis.
- **Bucket 3, semantic.** Is this title actually a claim? Does this atom hold one idea? Was this pre-decision section rewritten? Requires reading.

Buckets 1 and 2 are code and should never be done by hand or by a model. Bucket 3 is the only place judgment belongs.

## Configure the audit from the vault spec, not from flags

The auditor reads `vault-spec.yaml` at the vault root for note types, required fields, folder mapping, thresholds, and severity overrides. Adding a note type or making a field required is a spec edit that the auditor picks up with no code change.

Treat a missing spec as a failed audit, not a clean one. An auditor running on built-in defaults is checking someone else's vault: it should print a loud warning, emit a meta finding, and exit non-zero, so a "clean" result can never be a spec that failed to load.

## Know the rule catalog and its severities

The rule ids are the shared vocabulary between the script, the triage step, and the agent acting on the report.

| Rule | Finding | Severity |
| --- | --- | --- |
| C000 | Frontmatter unparseable | critical |
| C001 | Orphan atom, no inbound or outbound links | warning |
| C002 | Broken wikilink | warning |
| C003 | Missing frontmatter | warning |
| C005 | Decision modified after its decision date | critical |
| C007 | Decision past its expected resolution date | warning |
| C008 | Required field missing or empty | warning |
| C009 | Atom past the atomicity byte threshold | warning |
| C011 | Publishable claim failing the corroboration or review gate | critical |
| C012 | Stale verification on a decision-relevant claim | warning |
| C014 | Note filed outside its type's folder | warning |
| C015 | Content note with an absent or unmappable type | warning |

C015 matters more than it looks: without it, a note with no `type` silently evades every per-type check, so the cleanest way to pass the audit is to strip the field that makes a note checkable.

Exit codes carry the same information for CI: 0 clean, 1 warnings, 2 criticals.

## Triage by root cause, not by rule id

A flat list of 30 violations is noise. The same 30 grouped by cause is a work plan.

- Eight orphans clustering on one theme: a missing MOC, not eight missing links.
- Five unsourced claims from one book: one source-backfill session.
- Three overdue decisions in one class: one resolution-review session.
- Many atomicity violations in one folder: a domain that grew too fast, so one refactor session.
- One hindsight rewrite: handle it alone, immediately.

Present criticals first and individually, warnings grouped by cluster with a proposed batch action, and info items as a list for the next review.

## Autofix only the mechanical tier

An autofix pass should repair what it can derive with certainty and nothing else: adding a frontmatter block with the type derived from an unambiguous folder, filling `id` from the filename and dates from file mtime, and repairing a broken link when exactly one filename matches.

Everything semantic is left alone. An autofix that invents a `title`, a `source`, or a `confidence` value is fabricating research provenance. Dry run by default, require an explicit apply flag to write, and refuse to write an un-versioned vault without a further override, because there is no undo otherwise.

## Pause before bulk structural changes

Bulk renames, folder moves, and schema migrations that touch dozens of notes get a scope freeze: state the exact path list, state what undo looks like, and get explicit approval before applying. Operations that look obviously correct from a report are the ones most likely to sever a link network.

Never silently mutate a vault you audited. The report proposes; the owner accepts. This is doubly true when the auditor is being run by an agent, per [[knowledge-vaults/vault-orchestration]].

## Re-run and show the delta

After fixes, run the audit again. Report resolved findings by rule id, new findings introduced (adding a link can create a broken one), and the net change per severity.

Append every run to a log so the numbers become a trend. "Orphans down four, unsourced atoms up two this week" is worth more than any single snapshot, and it is what tells you whether the weekly review is actually happening. In a shared vault, run the auditor as a pull request check with criticals blocking merge, per [[knowledge-vaults/team-vaults]] and the workflow patterns in [[tooling/github-actions]].

## Related

- [[knowledge-vaults/semantic-audit]]
- [[knowledge-vaults/vault-frontmatter-schema]]
- [[knowledge-vaults/vault-architecture]]
- [[knowledge-vaults/vault-maintenance]]
- [[knowledge-vaults/team-vaults]]
- [[knowledge-vaults/vault-orchestration]]
- [[tooling/github-actions]]
