Praxis β€” How It Works

An interactive tour of the on-device guardrail for AI agents. Nothing here talks to a server; it's all local.

← Praxis home Download β†’

1 Β· Who is calling?

2 Β· What action?

3 Β· Interception layer

Request pipeline (fail-closed, top β†’ bottom)

Outcome

β€”
Run a request to see the verdict

What happened, step by step

Idle. Choose inputs and press β–Ά Run request.
Same action β€’ different verdict β€’ decided by who asks and how risky it is. T3/secret & unknown callers are always blocked.

The one question that decides everything: is Praxis on the road, or beside it?

Flip this to see which models still catch the action when the agent tries to route around Praxis.
On the road (wrap / proxy / syscall) = the call must pass through β†’ real interception. Beside the road (offer a tool) = the call may pass through β†’ best-effort.

Who owns this process?

At the OS layer every action is just a process making a syscall. Praxis only gates processes that belong to an agent β€” your own apps are never prompted. Click a process to run a delete from it.

launchd (your login session)
β”œβ”€ Finder
β”œβ”€ Terminal
β”‚   β””─ zsh (you typing)
β”œβ”€ VS Code
└─ Codex.app ← watched agent root
    β””─ zsh -c "rm x"
       β””─ /bin/rm

Attribution β†’ principal β†’ verdict

β€”
Click a process on the left
Every syscall carries a pid. Praxis walks the process tree: if the process descends from a known agent app, it's agent:* and gets policy; otherwise it's you and flows freely.

Why this matters

The same command rm x is allowed or gated purely by which branch of the tree it grew from. Your terminal's rm and Codex's rm are identical syscalls β€” attribution is what tells them apart. That's the OS-level version of the MCP principal, and it's why a real user is never spammed with prompts.

Hard parts (staff signal): pid reuse β†’ pin identity at exec-time & track the tree; agent-created scripts run later β†’ taint them; shared helper daemons β†’ attribute per-request, not per-process.

The decision matrix β€” principal Γ— risk tier (live, driven by your strictness config)

ActionπŸ§‘ You (praxis:local)πŸ€– AI agent (agent:*)
Rows are the risk tier of the action. Cells are the outcome. T3 (root/secret) and unknown callers are hard-deny floors β€” never configurable. Presets mirror praxis init exactly; "custom" lets you set every cell.

The layers (click any box)

Detail

Click a component to see exactly what it does β€” grounded in the real modules.
Legend: everything above the OS line is one local daemon + per-client MCP subprocesses. No network. No server. Your files never leave the machine.

The 6-line whiteboard

  1. Agents act; nobody guards the action boundary β†’ Praxis returns allow/block/ask there.
  2. An unforgeable principal (local key/HMAC vs agent token) rides a normalized ActionEvent.
  3. Policy = principal × risk-tier matrix + deterministic→embedding classification + user config.
  4. Executor = fail-closed pipeline: kill-switch β†’ policy β†’ approval β†’ dispatch; destructive β†’ trash-first.
  5. Evidence = append-only SHA-256 hash chain (tamper-evident).
  6. Today MCP + on-device + offline. Next: OS-level (EndpointSecurity/eBPF) for guaranteed interception.