Curtis AI Audit is a local-first audit trail for AI agent activity in your Obsidian vault. Every agent action gets an append-only markdown receipt — plain files, no database, stored in the vault you already own.
● Everything lives in your vault as markdown. No accounts, no uploads, no telemetry.
One audit.v1 block per agent action: who, what, when, model, duration, tokens, status — plus a rendered human summary. Readable in Obsidian, parseable by anything.
Append-only per-day ledgers. The envelope is the receipt as canonical JSON; the body is the summary. Open a day's shard like any note — metadata only, tool input content is never recorded.
Counts, statuses, tokens, durations, a per-day breakdown, errors. Rewritten on demand — the ledgers are the source of truth, the digest is a view.
External agents drop a message into Messenger/audit/inbox.md; the plugin polls with cursor semantics, rejects junk, dedupes redeliveries. The messenger plugin is not required — the inbox is just a file.
Detects malformed blocks, duplicate ids and sequences, reordered shards, and per-agent sequence gaps — deletions leave holes. No cryptography, no false promises.
A receipt, as it lands in today's shard:
<!-- curtis-audit: {"schema":"audit.v1","id":"rcp_…","seq":42,"agent":"curtis-ai-chat","action":"inference","ts":"2026-10-16T12:00:00.000Z","recorded":"2026-10-16T12:00:01.246Z","provider":"openai","model":"gpt-4o","status":"ok","durationMs":1234,"tokens":{"input":812,"output":341},"subject":"Notes/question.md"} -->
**inference** · ok · `gpt-4o` via `openai` · 1234ms · 812 in / 341 out
Subject: `Notes/question.md`
Answered a question about the spec.
<!-- /curtis-audit -->
The plugin reads, verifies, and digests. The writer lets anything on your machine file receipts — no Obsidian needed.
From a release: download main.js, manifest.json, and styles.css into <vault>/.obsidian/plugins/curtis-ai-audit/, then enable it in Obsidian (Settings → Community plugins). Not in the community directory; BRAT can track this repo for updates. Requires Obsidian 1.13.0+.
From a checkout, one line puts a curtis-audit command on your PATH:
node install.mjs
After that: … | curtis-audit --agent my-agent --inbox …
Any shell, any agent, any device that can append to a file — the whole integration is one dependency-free line:
# one-off, from a checkout
echo '{"action":"inference","summary":"Nightly digest run"}' | node bin/curtis-audit-file.mjs \
--agent research-agent --model gemini-2.5-pro \
--inbox "$HOME/vault/Messenger/audit/inbox.md"
# after `node install.mjs`
echo '{"action":"inference","summary":"Nightly digest run"}' | curtis-audit \
--agent research-agent --model gemini-2.5-pro \
--inbox "$HOME/vault/Messenger/audit/inbox.md"
In-Obsidian plugins skip the bus with the direct API — and Install agent audit hooks writes vault-scoped configs so Claude Code and OpenCode file their own receipts; Codex and Gemini get manual recipes. Full recipes: INTEGRATION.md.
| Command | What it does |
|---|---|
| Check audit inbox now | poll + ingest, with a summary notice |
| Verify ledger | integrity scan; details to console |
| Write digest | (re)write Audit/digest.md and open it |
| Open today's ledger | open/create today's shard (UTC day boundaries) |
| Install agent audit hooks | write vault-scoped hook configs for local agents |
| Prune ledger now | manual retention pass — off by default, and each prune is itself recorded as a receipt |
Deliberate honesty: Curtis AI Audit is an accountability journal for the casual, accidental, and lazy cases — someone spending thirty seconds doctoring a markdown file defeats it. Tamper-evidence and retention enforcement are the next tier up and are not pretended here. The full statement of what is and isn't built: SPEC §8, the upgrade path (deliberately unbuilt).