No. 06of 22LandmarkSoftware
Local guardrails for AI coding agents
PAMO
A macOS daemon and native app that sits between me and terminal AI coding agents. It lets routine actions through, holds destructive ones for a human, and logs every decision. In three weeks of logged use it made 3,699 decisions and held 258.
- When
- Apr – Nov 2026
- Status
- Built
- Team
- Personal project.
- Role
- Sole builder.
Progress
Progress75%
Phase 1 works end to end and the native app is built. There is no demo recording or commit history yet, and later phases are not started.
What comes next
- Label about 200 logged decisions and report how often PAMO and I agree, which would turn usage into an accuracy figure.
- Record a short demo: a routine prompt approved, a dangerous command held, the ledger.
- Commit the history and publish the code without its data folder.
3,699
permission decisions made and logged
Three weeks of real use, 18 May to 8 June 2026, all from Claude Code sessions. Usage, not accuracy: no decision has been checked against a labeled answer.
PAMO's decision ledger (data/pamo.sqlite3, table decisions), opened read-onlyVerified. Backed by a file or public page that has been checked.PAMO's decision ledger (data/pamo.sqlite3, table decisions), opened read-only — Read in the project audit of 13 November 2026.258
actions held for a human instead of being allowed
104 for secrets, 54 irreversible, 43 payments, 12 personal information, 45 other. The remaining 3,441 were allowed automatically.
PAMO's decision ledger (data/pamo.sqlite3, table decisions), opened read-onlyVerified. Backed by a file or public page that has been checked.PAMO's decision ledger (data/pamo.sqlite3, table decisions), opened read-only — Read in the project audit of 13 November 2026.1,023
terminal session logs captured
From 20 May to 3 November 2026. The decision ledger itself covers only the first three weeks.
Terminal capture folder (data/terminals/)Verified. Backed by a file or public page that has been checked.Terminal capture folder (data/terminals/) — Read in the project audit of 13 November 2026.111
test functions in 11 files
A count of tests, not of passes: the last recorded run, on 1 June 2026, had 5 failures, which may be stale.
pytest cache (feature1/.pytest_cache)Verified. Backed by a file or public page that has been checked.pytest cache (feature1/.pytest_cache) — Read in the project audit of 13 November 2026.15
architecture decision records in the project's documentation
Project documentation (docs/decisions/)Verified. Backed by a file or public page that has been checked.Project documentation (docs/decisions/) — Read in the project audit of 13 November 2026.Exhibit 01 · Compare
Allowed, or held for a human
Allowed automatically
3,441
Actions PAMO let through without stopping the agent. Whether each one matched what I would have chosen has not been measured.
Held under "Needs you"
258
Actions stopped and queued for me: 104 involving secrets, 54 irreversible, 43 payments, 12 personal information and 45 other. That is about 7 in every 100.
3,699 decisions in three weeks of real use, 18 May to 8 June 2026, all from Claude Code sessions. Usage, not accuracy.
Exhibit 02 · Chart
Why 258 actions were held
Exhibit 03 · Scorecard
The ledger, in numbers
Read from PAMO's own data, opened read-only in the project audit of 13 November 2026. These are usage numbers. No decision has been compared with a labeled answer.
| Measure | Result | Note | Source |
|---|---|---|---|
| Permission decisions made and logged | 3,699 | 18 May to 8 June 2026. Every one came from a Claude Code session. | data/pamo.sqlite3, table decisions |
| Allowed automatically | 3,441 | data/pamo.sqlite3, table decisions | |
| Held for the owner | 258 | data/pamo.sqlite3, table decisions | |
| Decided by the main rules path | 3,155 | Logged under the actor name "pamo"; the audit reads it as the rules engine. | data/pamo.sqlite3, table decisions |
| Decided by the persona model | 280 | data/pamo.sqlite3, table decisions | |
| Decided by the seatbelt | 213 | data/pamo.sqlite3, table decisions | |
| Decided by the fast path | 51 | data/pamo.sqlite3, table decisions | |
| Ledger scale | 31 projects, 39 sessions, 760 turns, 99 terminals | data/pamo.sqlite3 | |
| Terminal sessions captured | 1,023 logs | 20 May to 3 November 2026. | data/terminals/ |
| Test suite | 111 test functions | 234 collected cases in 11 files. The last recorded run, on 1 June 2026, had 5 failures, which may be stale. | feature1/.pytest_cache |
| Accuracy of the automatic decisions | Not measured | Nothing has been checked against labeled ground truth yet. | Project audit, 13 November 2026 |
01
What it is
Terminal AI coding agents ask for permission constantly: run this command, edit this file. Saying yes to everything is dangerous, and saying no to everything makes the agent useless. PAMO answers those prompts the way I would, stops for me only when it matters, and writes every decision to a ledger. It is a personal project, built for my own machine.
02
The hard part
A language model cannot be the thing that decides whether a destructive command runs. So the first layer is a deterministic "seatbelt": fixed rules that hold destructive or irreversible commands, secrets, payments and personal information under "Needs you". Only then does a persona model, an advisor that runs locally by default, predict what I would decide.
03
What was built
A Python daemon with a standard-library HTTP API, SQLite in WAL mode, a launchd service, and install and doctor scripts. Hooks into Claude Code's tool-permission prompts, plus a zsh hook that captures terminal sessions. The seatbelt (573 lines) and the persona engine (379 lines), which talks to a local model through Ollama by default and can use OpenAI or Anthropic instead. A ledger of every decision, session, turn and terminal command. Adapters for three more coding CLIs. A native app, a Tauri 2 shell around a plain JavaScript dashboard, built as a release bundle. And 111 test functions and 15 architecture decision records.
04
What the ledger shows
Between 18 May and 8 June 2026 PAMO made and logged 3,699 permission decisions. It allowed 3,441 and held 258: 104 for secrets, 54 as irreversible, 43 for payments, 12 for personal information and 45 for other reasons. The persona model made 280 of the decisions; the audit reads the rest as rule decisions: 3,155 from the main rules path, 213 from the seatbelt and 51 from a fast path. Terminal capture kept running until November 2026 and holds 1,023 session logs. These are usage numbers. Whether each automatic decision was the one I would have made has not been measured.
05
What it does not claim
It is designed for several coding CLIs, but every logged decision came from Claude Code. The last recorded test run, on 1 June 2026, had 5 failures, so the 111 is a count of tests, not of passes. The repository has no commit history yet, so no code is linked, and there are no screenshots or recordings. Screen and audio capture, a memory graph, a voice persona and an autonomous driver are on the roadmap only.
One question
The answer is on this page. Get it right and it goes in your passport on the map.
Challenge· stamped
In three weeks an AI coding agent asked PAMO for permission 3,699 times. How many of those did PAMO hold for a human?
258, about 7 in every 100. The other 3,441 were allowed automatically. These are usage numbers from PAMO's own decision ledger (18 May to 8 June 2026), read in the project audit of 13 November 2026; they are not a measure of accuracy.
Show the answer
258. 258, about 7 in every 100. The other 3,441 were allowed automatically. These are usage numbers from PAMO's own decision ledger (18 May to 8 June 2026), read in the project audit of 13 November 2026; they are not a measure of accuracy.
- Stack
- Python (standard-library HTTP, sqlite3)
- SQLite (WAL mode)
- Claude Code hooks
- zsh hooks
- launchd
- Ollama (qwen2.5-coder:32b)
- OpenAI and Anthropic APIs (optional)
- Tauri 2 (Rust)
- JavaScript
- pytest