grithdocs

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

SubcommandWhat it does
export --format jsonDump every record as a JSON array (stdout; redirect to a file).
export --format csvSame records, as CSV.
diagnoseInspect the audit chain — verification outcome, forks, and gaps. Read-only, and works even when the chain is quarantined.
compactReclaim 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 batches

JSON 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 diagnose

Read-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

Last updated: 2026-05-14Edit this page on GitHub →