← All posts
By The agentjail team

v1.2.0: See what AgentJail actually did

agentjail v1.2.0 adds a local activity report and makes PATH-shim consent survive both manual and automatic updates.

An agentjail v1.2.0 activity report showing final outcomes, policy deny rules, and three restored agent PATH shims.

agentjail logs tells you what happened one tool call at a time. That is useful when you are watching a session or investigating one denial. It is a poor way to answer a broader question:

What has AgentJail actually done on this machine?

v1.2.0 adds the missing summary:

agentjail stats

It also fixes an update bug in the opt-in PATH shim. If you had enabled the shim before Codex and Cursor support landed, updating the AgentJail binaries could leave you with the old Claude-only wrapper. Both manual and automatic updates now rebuild the complete wrapper set from the consent you already gave.

The report

The default report reads the local SQLite store and covers all recorded activity:

AgentJail Activity (all time)
════════════════════════════════════════════════════════════

Total outcomes:             1004
Sessions:                   4
Allowed / Asked / Blocked:  930 / 2 / 72
Active days:                5  (2026-07-25 → 2026-07-29)
Latency (p50/p90/p95/p99/max): 1.2ms / 2.4ms / 2.7ms / 4.2ms / 23.5ms
Block rate: █░░░░░░░░░░░░░░░░░░░░░░░ 7.2%

Below the totals, ranked tables show the policy rules that denied calls, which agents generated activity, and which audit events occurred. This is all local. The command opens the existing database through AgentJail’s read-only store interface. It does not send a report anywhere.

For a smaller window:

agentjail stats --since 24h
agentjail stats --since 7d

For scripts and dashboards:

agentjail stats --json

--top N controls the number of rows in each ranked table, and --db can point at another AgentJail decision database.

Count what finally happened

AgentJail records more than one action because enforcement has layers.

Policy can return allow, ask, or deny. An agent adapter may need to turn an ask into a fail-closed denial when its hook protocol cannot open an approval prompt. The OS sandbox can then block something policy allowed.

Those are different facts:

FieldQuestion
policy_actionWhat did policy decide?
effective_actionWhat answer did the agent protocol receive?
final_actionWhat ultimately happened?

The headline stats count final_action. If policy allowed a read but Landlock or Seatbelt blocked it, the report counts a block. The “Top Policy Deny Rules” table stays tied to policy_action, so a sandbox block does not get invented as a policy rule.

Older rows without the newer fields still work. The queries fall back to the original action column.

Notice when recording goes quiet

A quiet report can mean a quiet agent. It can also mean the shield launched while decision recording stopped.

The report compares days with shield.activated audit events against days with recorded decisions. If a day has shield launches and zero decisions, it prints a coverage warning and points you to agentjail doctor.

This is a signal, not a verdict. An agent might genuinely launch and make no tool calls. The useful part is that the gap is now visible instead of hiding inside an otherwise healthy-looking total.

Missing agent identity gets the same treatment. New rows with no attributable agent are stored as unknown, not an empty string that disappears into a grouped report.

The PATH shim remains opt-in:

agentjail install --with-path-shim

That command installs wrappers for:

claude
codex
agent

The shell-profile block is the durable record that you asked for those wrappers. The scripts under ~/.agentjail/bin are derived files and can be rebuilt.

Install already understood that distinction. The two updater paths did not. They swapped the real binaries and repaired AgentJail’s role symlinks, but never regenerated PATH wrappers. Tests stayed green because they checked the binaries, not the derived launchers.

v1.2.0 gives install, doctor, uninstall, manual update, and daemon auto-update one shared shim contract. After a binary swap, an updater checks for an existing wrapper or the shell-profile consent marker. If either exists, it rebuilds all three wrappers from the current template.

If you never opted in, an update still does nothing to your shell profile.

Upgrade

Use the same channel you installed from:

brew upgrade agentjail
# or
agentjail update

Then run:

agentjail stats --since 24h
agentjail doctor

The first command shows what the guard did. The second checks that the guard and its launch paths are still intact.