Grounded Vault
Seth HobsonCommunityCreated by Niksa BarlovicDistributed by Seth Hobson
- Skill
- Guidelines
- Documents and content
- MIT
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
Grounded Vault is a documentation pattern that organizes information into three layers: raw source material, compiled wiki pages, and an archive for superseded content. It ensures that every claim, number, or quote in a wiki page is linked to an immutable source file. By using git fingerprints, the system allows for efficient checks to determine if a page has become stale due to changes in the underlying code or source material, without requiring a full re-read of the documentation.
What it does
- Defines a three-layer directory structure for raw sources, wiki pages, and archived content.
- Establishes a header contract for wiki pages to track source links, git fingerprints, and monitoring status.
- Provides a mechanism to link every claim, number, or quote to its specific raw source file.
- Enables drift detection by comparing git fingerprints against monitored code paths.
- Supports an append-only log and index for tracking changes to the knowledge store.
- Includes a script for validating grounding and detecting stale pages.
When to use it
- When you need to maintain a knowledge base where every claim must be verifiable against source material.
- When documentation describes code and needs to detect if that code has changed.
- When you want to preserve history by archiving outdated pages rather than deleting them.
- When you need a lightweight way to check for documentation staleness using git.
Advantages
- Ensures documentation remains grounded in verifiable source data.
- Allows for rapid staleness checks using existing git infrastructure.
- Maintains a clear audit trail of knowledge evolution through an index and log.
- Prevents the loss of information by archiving instead of deleting superseded content.
Usage examples
- “How do I verify that my documentation is still accurate after a code change?”
- The agent uses the git fingerprint in the page header to run a git diff against the monitored files, identifying if any changes occurred since the last compilation.
- “How should I structure a new page that cites a technical specification?”
- The agent creates a Markdown file with a header block containing the raw source link, the current git fingerprint, and the monitored code paths, ensuring all claims link back to the source.
Install
Download the skill as a ZIP:
https://mp-staging.autogineer.com/agent-skills/wshobson/grounded-vault/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip grounded-vault.zip -d .agents/skills
Documentation by Niksa Barlovic
Grounded Vault
A grounded vault is a three-layer Markdown store in which every compiled claim can be traced
back to an immutable source and every page can be checked for staleness with one git diff.
It needs a git repository and nothing else. The convention comes from the llm-wiki-loop
project, which is a reference implementation rather than a dependency; this skill teaches the
pattern so it works with plain files and whatever agent is in the session.
When to Use
An agent compiles notes, papers, transcripts, logs, or code into wiki pages that later sessions rely on.
A page cites numbers, dates, or quotes, and a reader must be able to verify each one against its source.
Pages describe code, and rereading the codebase every session to check whether they still hold is too expensive.
Knowledge must be corrected without losing history: superseded pages are archived, never deleted.
Session state, task queues, and conversation continuity are a different problem; use the context-management or conductor plugins for those. This skill is about provenance and drift on a durable knowledge store.
The three layers
| Layer | Contents | Who writes it | Rule |
|---|---|---|---|
raw/ | source material: notes, papers, transcripts, logs, exported data | people and ingestion only | immutable once added; agents never edit a raw file |
wiki/ | compiled pages built from raw/ and from code | agents and people | every number, date, and quote links to its source |
archive/ | pages that drifted or were superseded | agents, during garbage collection | moved, never deleted; the header says why |
Two files sit at the vault root. index.md is the map of every current page. log.md is an
append-only record of what changed and why. Both change in the same commit as the page they
describe.
Page header contract
Every wiki/ page opens with a header block:
# Authentication architecture
> Raw: [raw/notes/auth-v1.md](../raw/notes/auth-v1.md), [raw/adr/0007-jwt.md](../raw/adr/0007-jwt.md)
> Fingerprint: git:5b237fa
> Monitored: src/auth/jwt.ts, src/auth/session.ts, package.json
> Status: CurrentRaw:lists every source the page was compiled from. Inline claims link to their specific source as well:Tokens expire after 15 minutes ([raw/adr/0007-jwt.md](../raw/adr/0007-jwt.md)).Fingerprint:is the short commit hash the page was compiled against.Monitored:lists the code paths the page describes. A change to any of them after the fingerprint means the page may be stale.Status:isCurrent,Outdated(monitored code moved on), orDisputed(a newer source contradicts the page).
Grounding rule
A compiled page states only what a source supports, and every number, date, or quotation appears verbatim in the linked source. A synthesis says it is one and links its inputs. A gap in the sources is written into the page as a gap rather than filled by guessing.
Check it mechanically: for each linked claim, search the linked raw file for the exact figure
or quoted phrase. A miss is a grounding error and blocks the commit. The script in
references/details.md does this for a whole vault.
Drift detection
Compare the fingerprint with the current tree instead of rereading monitored code:
git diff --stat 5b237fa..HEAD -- src/auth/jwt.ts src/auth/session.ts package.jsonEmpty output means the page still describes the code it was compiled against. Any output means recompile: reread only the changed files, update the page, and stamp the new fingerprint. The check runs in milliseconds and spends no model tokens.
Workflow
Ingest. Put new material in
raw/under a dated or sourced filename. Never rewrite an existing raw file; add a new one beside it.Compile. Write or update the
wiki/page with the header block, a source link on every claim, and the fingerprint of the commit the code was read at.Check. Run the grounding check and the drift check before committing. Fix misses at the source; do not weaken a claim to make the check pass.
Garbage collect. When drift or a contradicting source appears and the page is not recompiled now, change its status, move it to
archive/, and record the reason:> Status: Outdated > Reason: src/auth/session.ts changed after git:5b237fa; see log.md 2026-09-01Update the map. Every add, move, or archive updates
index.mdand appends one line tolog.mdin the same commit.
Commit gate
Run both checks from a pre-commit hook or a CI step so a page cannot land with an unverifiable number or a stale fingerprint:
python3 scripts/check_vault.py --strict # exits 1 on any grounding miss or drifted pageGoing deeper
references/details.md covers: the vault check script, batching the drift check across pages,
templates for index.md and log.md, renamed or deleted monitored files, sources that are
binary or live at external URLs, and the reference implementation.
Files
- ATTRIBUTION.mdAdded by AutoGineer991 B
- LICENSELicence file added by AutoGineer1.0 KiB
- SKILL.md5.3 KiB
- references/details.md8.2 KiB
references/details.md
Grounded vault: details
Deep material for the grounded-vault skill. SKILL.md carries the convention; this file
carries the scripts, templates, and edge cases.
Vault check script
scripts/check_vault.py walks every page under wiki/, verifies each linked claim against
its raw source, and compares each fingerprint with the current tree. It uses only the standard
library and git.
#!/usr/bin/env python3
"""Grounding and drift checks for a grounded vault. Run from the vault root."""
import re
import subprocess
import sys
from pathlib import Path
RAW = (Path.cwd() / "raw").resolve()
WIKI = Path("wiki")
HEADER = re.compile(r"^> (Raw|Fingerprint|Monitored|Status): (.*)$", re.M)
LINK = re.compile(r"\[([^\]]+)\]\(([^)]+\.md)\)")
NUMBER = re.compile(r"(?<![\w.,])\d[\d.,]*%?(?![\w.,])")
QUOTE = re.compile(r"[\"\u201c]([^\"\u201d]{8,})[\"\u201d]") # shorter quoted words are not claims
def header(text: str) -> dict[str, str]:
return {k: v.strip() for k, v in HEADER.findall(text)}
def prose(text: str) -> str:
"""Body text without the header block, headings, and fenced code."""
kept, fenced = [], False
for line in text.splitlines():
if line.startswith("```"):
fenced = not fenced
continue
if fenced or line.startswith((">", "#")):
continue
kept.append(line)
return "\n".join(kept)
def claims(text: str):
"""Yield (item, is_number, raw_links) for every figure or quotation in the prose."""
for sentence in re.split(r"(?<=[.!?])\s+", prose(text)):
links = [path for _, path in LINK.findall(sentence) if "raw/" in path]
bare = LINK.sub(" ", sentence) # link labels and paths are not claims
for item in NUMBER.findall(bare):
yield item, True, links
for item in QUOTE.findall(bare):
yield item, False, links
def raw_source(page: Path, rel: str) -> Path | None:
"""The raw file a link points at, or None when it escapes raw/ or is missing."""
src = (page.parent / rel).resolve()
return src if src.is_relative_to(RAW) and src.is_file() else None
def grounded(item: str, is_number: bool, sources: list[str], page: Path) -> bool:
token = re.compile(r"(?<![\w.,])" + re.escape(item) + r"(?![\w.,])")
for rel in sources:
src = raw_source(page, rel)
if src is None:
continue
text = src.read_text(errors="replace")
if token.search(text) if is_number else item in text:
return True
return False
def drift(fingerprint: str, monitored: str) -> str:
"""Non-empty when monitored paths changed since the fingerprint, or git cannot tell."""
sha = fingerprint.removeprefix("git:")
paths = [p.strip() for p in monitored.split(",") if p.strip()]
if not paths:
return ""
out = subprocess.run(
["git", "diff", "--stat", f"{sha}..HEAD", "--", *paths],
capture_output=True, text=True, check=False,
)
if out.returncode != 0:
return f"git cannot compare {sha}: {out.stderr.strip() or 'unknown fingerprint'}"
return out.stdout.strip()
def main(strict: bool) -> int:
errors = 0
for page in sorted(WIKI.rglob("*.md")):
text = page.read_text()
meta = header(text)
if meta.get("Status", "Current") != "Current":
continue
if not meta.get("Fingerprint"):
print(f"{page}: no Fingerprint header")
errors += 1
for item, is_number, sources in claims(text):
if not sources:
if strict:
print(f"{page}: {item!r} has no raw/ source link")
errors += 1
continue
if not grounded(item, is_number, sources, page):
print(f"{page}: {item!r} not found in {', '.join(sources)}")
errors += 1
stat = drift(meta["Fingerprint"], meta.get("Monitored", "")) if meta.get("Fingerprint") else ""
if stat:
print(f"{page}: drifted since {meta['Fingerprint']}\n{stat}")
errors += 1
print(f"{errors} problem(s)")
return 1 if (errors and strict) else 0
if __name__ == "__main__":
sys.exit(main(strict="--strict" in sys.argv))What it checks, and what it deliberately does not:
Only the prose is scanned. The header block, headings, fenced code, and the labels and paths of Markdown links are excluded, so a source path such as
raw/adr/0007-jwt.mdnever reads as a claim of0007.A number is grounded when it appears in a linked source as a whole token, so
15does not match150or2015. A quotation must appear verbatim. Quoted phrases shorter than eight characters are not treated as claims; a two-word quote is not evidence of anything. Reformatted figures (1,000versus1000) fail on purpose; copy the source's form.A link must resolve inside
raw/. A path that escapes it, or points at a file that is missing, is a miss, so a page cannot ground a claim on something outside the vault.Under
--strict, a number or quotation with noraw/link in its sentence is an error. Without--strictit is skipped, which is the mode for a first pass over an old vault.Every current page needs a
Fingerprint:. An emptyMonitored:is allowed: a page compiled only fromraw/has no code to drift against.Drift is a non-empty
git diff --statbetween the fingerprint andHEADrestricted to the monitored paths. When git cannot compare, for example after a history rewrite removed the fingerprint, that counts as drift too; recompile and stamp a fresh fingerprint.Archived and disputed pages are skipped; they are records, not claims.
Batching the drift check
For a vault with many pages, collect fingerprints first and run one git diff per distinct
fingerprint rather than one per page:
grep -rh '^> Fingerprint: git:' wiki | sort -u | sed 's/^> Fingerprint: git://' \
| while read -r sha; do
echo "== $sha"; git diff --stat "$sha..HEAD" -- $(grep -rl "git:$sha" wiki \
| xargs grep -h '^> Monitored:' | sed 's/^> Monitored: //' | tr ',' '\n' | sort -u)
doneTemplates
index.md:
# Vault index
| Page | Status | Fingerprint | Sources |
|---|---|---|---|
| [Authentication architecture](wiki/auth-architecture.md) | Current | git:5b237fa | raw/notes/auth-v1.md, raw/adr/0007-jwt.md |log.md, one line per change, newest last:
2026-09-01 compile wiki/auth-architecture.md from raw/adr/0007-jwt.md at git:5b237fa
2026-09-14 archive wiki/session-store.md: Outdated, src/auth/session.ts changed after git:5b237faPre-commit hook (.git/hooks/pre-commit):
#!/bin/sh
python3 scripts/check_vault.py --strict || {
echo "vault check failed; fix the claim or the fingerprint before committing" >&2
exit 1
}The same command runs as a CI step on pull requests so the gate holds for every contributor.
Edge cases
Renamed or deleted monitored files.
git diffreports the deletion as a change, which is correct: the page describes something that moved. Recompile with the new paths inMonitored:.Binary sources (PDFs, images). Store the binary in
raw/and add a sibling text extraction (report.pdfandreport.pdf.txt) produced once by a deterministic tool. Link claims to the text file so the grounding check can read it.External URLs. A URL is not immutable. Save a dated snapshot into
raw/and link the snapshot; keep the URL in the snapshot's first line for attribution.Multiple repositories. Fingerprint with
git:<repo-name>@<sha>and keep one vault per repository, or one vault whoseMonitored:paths are prefixed by repository. The check script above assumes a single repository.Large raw files. Verbatim search is linear in file size; it stays fast up to tens of megabytes. Split larger exports by date when ingesting.
Reference implementation
llm-wiki-loop (MIT, https://github.com/PALAN-K/llm-wiki-loop) scaffolds this layout with
npx llm-wiki-loop init, ships a stricter check_evidence.py, and adds an event-driven
garbage collector and a step that promotes repeated fixes in log.md into agent skills. Read
it for the full loop; nothing in this skill requires it. The pattern was proposed for this
catalog by its author in wshobson/agents issue #673.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs a command-line tool, Needs Python
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Niksa Barlovic
- Publisher
- Seth Hobson (Community)
- Distributed by
- Seth Hobson
- Source
- wshobson/agents · plugins/documentation-standards/skills/grounded-vault · commit 4bde316
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Niksa Barlovic or Seth Hobson.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download grounded-vault.zip