grith audit
Browse and export the audit log of every filter decision.
grith audit [diagnose | export | compact]The audit log is the persistent record of every decision grith made — including
auto-allows. It lives in a SQLite database under ~/.local/share/grith/audit/.
Subcommands
| Subcommand | What it does |
|---|---|
export --format json | Dump every record as a JSON array (stdout; redirect to a file). |
export --format csv | Same records, as CSV. |
diagnose | Inspect the audit chain — verification outcome, forks, and gaps. Read-only, and works even when the chain is quarantined. |
compact | Reclaim free database pages left by retention pruning. Manual maintenance: rewrites and atomically swaps the audit database; the daemon must be stopped and the chain must not be quarantined. |
Export
grith audit export --format json > audit.json
grith audit export --format csv > audit.csv
grith audit export --format json --offset 1000 --limit 1000 # page through in batchesJSON output is one record per array element. Paging is by --offset / --limit
(default offset 0, limit 1000); there is no time or session filter on export —
filter the emitted records downstream.
Diagnose the audit chain
grith audit diagnoseRead-only inspection of the tamper-evident audit chain. It reports the
verification outcome and, if the chain is broken or forked, where the break is —
including the sequence numbers involved. Unlike the other audit subcommands,
diagnose still runs when the chain is quarantined (that is exactly when you need
it), so it never refuses on a failed verification.
Compact the database
grith audit compact # prompts for confirmation
grith audit compact --yes # skip the prompt (for scripts)Reclaims free pages left behind by retention pruning: it rewrites the audit
database into a fresh copy, verifies that copy's chain, and atomically swaps it in;
on any failure the original is left untouched. This is a manual maintenance
operation — it never runs on a timer. It needs exclusive write access, so stop
the daemon first (grith daemon stop), and it refuses to run on a quarantined
chain so evidence is preserved. On success it prints the on-disk and free-page
bytes reclaimed.
What a record looks like
{
"id": "uuid-...",
"ts": "2026-05-14T09:14:23Z",
"session": "abc12345-...",
"operation": "file_read",
"target": "/home/you/.ssh/config",
"decision": "queue",
"resolved": "deny",
"composite_score": 4.2,
"filters": [
{ "name": "sensitive-path-heuristic", "score": 3.5 },
{ "name": "path-match", "score": 1.2 }
],
"profile": "claude-code",
"pid": 17421,
"command": "claude"
}decision is what the pipeline returned (allow / queue / deny). resolved is what
ultimately happened (auto-allows have no resolved transition; queues resolve to
allow/deny via review or timeout).
Storage and retention
The active SQLite database keeps a bounded window of recent records and prunes
older ones automatically. Retention is configured under [audit]:
[audit]
retain_full_days = 30 # days kept in the active database (0 = keep all)
cold_storage_enabled = true # archive pruned records under audit/cold/ first
prune_interval_hours = 24 # prune cadence (0 = prune once on startup only)Deleting rows does not shrink the SQLite file. Run grith audit compact to
rewrite the database and reclaim the freed space — a manual operation that
needs exclusive write access, so stop the daemon first (grith daemon stop).
See Logging & audit retention for the trade- offs.
See also
- Audit API — same data, REST
- Analytics overview (Pro)
- Compliance reporting (Enterprise)