Inspiration

The idea started with a terrifyingly ordinary failure mode: an agent treats a real directory like a temporary one, then runs a perfectly valid cleanup command against the wrong path. The model does not need malicious intent. It only needs to be wrong once, at machine speed.

The usual answers are sensible: disable full access, add a sandbox, take checkpoints, and ask for approval. But each solves a different problem. A sandbox limits the blast radius. A guard recognizes dangerous syntax. A checkpoint keeps a copy. An approval records consent. None of them proves that the affected state can actually be restored before it disappears.

That distinction became the project:

A backup is a noun. Recovery is a verb. I wanted destructive permission to depend on the verb.

What it does

Recovery Authority is an open-source Codex plugin that turns destruction into a two-key protocol. The machine must first prove the exact inverse works. A person must then release authority through a separate channel. Neither is sufficient alone.

When an agent requests a supported destructive action, Recovery Authority:

  1. Narrows the action to an exact effect and scope.
  2. Captures the state required to reverse it.
  3. Restores that artifact in an isolated drill.
  4. Runs the exact destructive effect against the drill and records before and expected-after witnesses.
  5. Shows the human a proof digest in a separate terminal.
  6. Issues one short-lived Ed25519-signed capability bound to the operation, scope, state, proof, and expiry.
  7. Rechecks live state before commit and preserves the verified recovery path afterward.

Preparation does not execute the deletion. Approval does not execute it either. The original state remains untouched until the exact commit adapter receives both valid proof and independent authority.

The working adapters cover POSIX filesystem deletion, local SQLite mutation, scoped PostgreSQL mutation, and git reset --hard. PostgreSQL recovery uses a full logical database artifact because deleting one row can cascade into another schema. Recovery Manifests bind several independent effects into one aggregate proof, one approval, ordered execution, and reverse-order compensation if a later step fails.

The Rust TUI is the control room. It displays intercepted effects, operations, subagents, manifests, proof receipts, adapter coverage, and a living consequence graph. The graph tells the agent the minimum missing safety edge, but it has no signing power. It can explain authority; it cannot create it.

If Recovery Authority cannot prove the complete inverse, it refuses to pretend. Container purges, remote-storage deletion, filesystem overwrites, unsupported database changes, infrastructure effects, and opaque scripts remain blocked.

How I built it

I split the system at the authority boundary. The model-facing mcp.js worker can prepare recovery, calculate witnesses, and verify public capabilities, but its bundle contains no private signer. The hook is a second signer-free binary. A separate authority.js human broker owns the Ed25519 key. The process that proves recovery cannot approve itself, and the process that approves cannot silently execute the operation.

The MCP runtime is written in TypeScript on Bun using the official Model Context Protocol SDK and Zod contracts. Bash commands are parsed structurally, Windows commands go through PowerShell's native AST, and PostgreSQL scope is checked with pgsql-ast-parser. The local ledger records digests and structured evidence instead of storing raw destructive commands or capability tokens.

On Linux, Bubblewrap runs Codex and every descendant inside a constrained filesystem view. The authority daemon, signer, evidence ledger, and recovery artifacts remain outside that mount namespace. The agent reaches them only through a narrow typed Unix-socket protocol. The mission-control interface is a separate Rust binary built with Ratatui and Crossterm.

I used Codex with GPT-5.6 throughout the build to research purge vectors, challenge my original CLI-only design, implement the MCP server and Rust TUI, build shell policies, design capability contracts, implement PostgreSQL recovery, diagnose live failures, package the plugin, and run the verification matrix.

I made the decisions that define the product: prove recovery instead of promising it; keep approval outside the chat; use full-database artifacts for cross-schema cascades; compose multi-effect work as a compensated saga; and block unsupported effects instead of weakening the claim.

Challenges I ran into

The first challenge was uncomfortable but fundamental: a security tool for coding agents has to distrust the agent using it. That includes parent agents, subagents, shell wrappers, interpreters, package hooks, and any alternate route the model can construct when its preferred tool is unavailable.

I saw this happen while preparing the demo. Codex built a manual JavaScript MCP client inside a shell command instead of using the registered native MCP tools. It was not directly destructive, but it created an opaque alternate authority path and an unreadable transcript. I preserved the exact command shape as a regression, blocked shell-built MCP authority clients, tightened the skill contract, and added a preflight that verifies native MCP registration and every forwarded authority variable before recording.

The second challenge was defining "exact recovery" honestly. A file is more than its contents. SQLite must survive an integrity check. A hard reset touches HEAD, the index, tracked state, and untracked work. PostgreSQL triggers, publications, functions, and foreign-key cascades can escape the scope suggested by one SQL statement. Some cases had to receive a hard no because a partial backup would create dangerous confidence.

The plugin eventually began protecting itself, which made normal development fail for the right reason. Updating the authority boundary required an explicit uninstall, edit, complete verification, cachebuster release, marketplace upgrade, and reinstall. I treated that friction as evidence that the boundary was real, not as something to bypass.

Accomplishments I'm proud of

The demo is not safety theater. A judge can install the public plugin, prepare recovery against real sample state, watch the original data remain present, approve a displayed proof in another terminal, commit through the exact adapter, restore the state, and inspect the entire chain in the Rust TUI.

Recovery Authority now has four exact adapters, immediate pre-commit artifact validation, interrupted-commit reconciliation, cross-process compare-and-set ledgers, proof-bound expiring capabilities, a signer isolated from the model, non-exportable manifest child authority, subagent receipts, cross-platform command classification, an enforceable Linux boundary, and a consequence graph that remains deliberately non-authoritative. Unsupported remote billing mutations such as Stripe cancellation fail closed instead of receiving a fake recovery promise.

The verification matrix passes 132 Bun tests, 5 Rust tests, and 3 nested Linux sandbox integration tests. Those tests include real PostgreSQL restore drills, cross-schema cascades, destructive operations against disposable state, capability tampering, stale witnesses, scope conflicts, parser evasions, and the shell-built MCP route discovered during the demo.

What I am proudest of is not that the system blocked an obvious rm -rf. It is that the product exposed a weakness in its own workflow, and I converted that weakness into enforcement, a regression test, and a cleaner native-tool path before submission.

What I learned

Sandboxing, authorization, and recovery are complementary, not interchangeable. A sandbox answers "where may this run?" Authorization answers "who allowed it?" Recovery answers "can the consequence be reversed?" Reliable agent autonomy needs all three answers.

I learned that prompts can teach a path, but they cannot secure it. If an alternate shell, interpreter, tool, or subagent can bypass the contract, the contract exists only in prose. Unknown execution must remain unknown, not get rounded down to safe.

I also learned to keep observability separate from authority. The consequence graph can help an agent understand what is missing. The TUI can help a person understand what happened. Neither should ever become a permission source. Only an exact adapter, a successful restore drill, a separate human signature, and a fresh state witness can create a destructive capability.

What's next for Recovery Authority

I want to expand exactness, not collect checkbox coverage. The next platform work is native macOS containment and stronger Windows restoration that preserves ACLs, alternate data streams, and reparse-point metadata. Additional database and infrastructure adapters will ship only when their complete inverse can be demonstrated; until then they will stay block-only.

The team version would add organization policy, remote or hardware-backed signing, multi-person approvals, artifact retention, and OpenTelemetry or SIEM exports. I also want to publish an adversarial benchmark built from real agent purge vectors so recovery claims can be measured instead of marketed.

The long-term goal is a portable recovery-authority protocol for any coding harness: agents may move quickly, but destructive authority exists only after recovery has already worked.

Built With

Share this project:

Updates