axiom setup stats — what the gate decided, and where it is silent
axiom setup stats [--root <dir>] [--since <iso>|<n>d|<n>h|<n>m] [--json]Read-only. It answers two questions for one root:
- What did the gate decide? Counts, deny codes and latency from the decision journal.
- Is the gate running everywhere hooks run? Alarms from the harness hook logs.
Nothing is written, nothing is spawned, and a missing file is an empty result — never an error.
--since takes an ISO date or a relative window (7d, 12h, 30m); anything else is a usage
error.
What it reads
Section titled “What it reads”| Source | Path | Needs |
|---|---|---|
| Decision journal | <root>/.axiom/decisions.jsonl |
gate policy record: true |
| Gate policy | <root>/.axiom/axiom.json (or the deprecated .axiom/gate-profile.json) |
only for the decisions.empty alarm |
| VS Code hook log | newest session: <Code[ - Insiders]>/logs/<session>/window*/exthost/GitHub.copilot-chat/GitHub Copilot Chat Hooks.log |
Copilot Chat hooks enabled |
| Copilot CLI hook events | ~/.copilot/session-state/<sessionId>/events.jsonl (newest 100 by mtime) |
Copilot CLI 1.0.9x+ |
Each log file is read from its last 8 MiB only. Runs are matched to the root by their hook cwd,
case-insensitively and after resolving the root’s real path (so e:\gh\x, E:/gh/x/ and a
junction alias all match).
Fields (--json)
Section titled “Fields (--json)”decisions—total,allow,deny,ask,shadowDiffs,p50,p95(ms,nullwithout samples) andcodes({ "ERR_…": n }) over the window.- Only
allow/deny/askdecisions are counted; any other value is ignored. shadowDiffs= shadow-mode records whose decision is notallow(the gate let the call through but would have blocked it).- Percentiles are nearest-rank at index
floor((n-1)·q)over each record’sms— the same convention asscripts/check-gate-latency.mjs. byHarness— the same bucket per harness (agent_idup to the first::claude,copilot,codex,unknown, …).byTool— per tool name (Write,Bash,apply_patch, …).post— only PostToolUse records (phase: "post").
- Only
logs[]— one entry per harness log that has runs for this root:harness,files,hookRuns(PreToolUse runs of any hook),gateRuns,silent,nonBlockingErrors, andp50/p95of the gate runs where the log records durations.alarms[]—{ id, harness?, message }, below.
Alarms and fixes
Section titled “Alarms and fixes”| Alarm | Fires when | Fix |
|---|---|---|
gate.silent |
a harness log shows ≥ 20 PreToolUse hook runs for this root and 0 of them are the axiom gate (same threshold as axiom setup doctor) |
axiom setup init (writes command/bash/powershell), trust the workspace, Developer: Reload Window; then axiom setup doctor |
gate.nonBlocking |
the gate ran but errored instead of deciding (VS Code NonBlockingError, Copilot CLI hook errored, e.g. spawn axiom ENOENT) |
make the hook command resolve: install the CLI globally or use the thin client path axiom setup init writes; axiom setup doctor names the broken entry |
gate.slow |
the gate’s p95 in a harness log is above 4000 ms | axiom setup init --daemon (resident gate), or check machine load / antivirus scanning of the Node binary |
decisions.empty |
the gate policy has record: true but no decision was journaled in the window |
the gate is not running for this root at all — same fix as gate.silent; check the hook cwd resolves to this root |
Harness support
Section titled “Harness support”- VS Code (Copilot Chat) — supported. Every hook run is logged with its command, workspace
cwd, outcome and duration, so the gate is identified by its command line and the silent-gate check is exact. - Copilot CLI — supported, partially.
events.jsonllogs every hook invocation (hook.start/hook.endwithhookType,cwd,success), but one invocation covers all configured hooks of that event and a successful one does not name the hook file. Stats therefore counts PreToolUse invocations and attributes errored invocations whoseerror.sourcenames the axiom gate (gate.nonBlocking); it never raisesgate.silentfrom this log, because “0 gate runs” there is not evidence. - Claude Code — not supported as a log. The transcripts under
~/.claude/projects/<encoded-cwd>/*.jsonlcarried no hook-run records on the machine this was built and verified on, so there is no format to parse honestly. Claude Code decisions still appear indecisions.byHarness.claudewhen the policy records. - Codex, Cursor, Windsurf, Gemini CLI, Junie, Cline, Kiro, OpenCode, ACP — no hook-run log was available to verify; their
decisions appear in
byHarnessthrough the journal.
Example
Section titled “Example”$ axiom setup stats --since 7daxiom stats - E:\gh\axiom since 2026-10-07T12:00:00.000Zdecisions: 5 (allow 2, deny 3 shadow 1) p50 30 ms p95 40 ms codes: ERR_GATE_DENY_GLOB 2, ERR_SECRET_DETECTED 1 harness claude: 2 (allow 1, deny 1) p50 10 ms p95 10 ms harness copilot: 2 (allow 0, deny 2 shadow 1) p50 30 ms p95 30 ms tool Bash: 1 (allow 0, deny 1) p50 30 ms p95 30 ms tool Write: 4 (allow 2, deny 2 shadow 1) p50 20 ms p95 40 ms post-tool checks: 1 (allow 1, deny 0) p50 5000 ms p95 5000 mslog vscode: 21 PreToolUse hook runs, 0 gate runs (1 file(s))ALARM gate.silent [vscode]: 21 PreToolUse hook runs for this root, 0 of them the axiom gate - run `axiom setup init`, trust the workspace, reload the windowSee also: axiom setup doctor, checks, the decision journal in
snapshot / axiom journal attest decisions.