Firas Mohammed
← All notes
AI agents · controls

A two-key gate for AI agents: one model proposes, a second signs

One model plans and signs first. A model from another vendor co-signs without seeing that vote. A third builds. Disagreements wait for me, and an append-only ledger keeps every step.

By · · 4 min read

The short answer

A two-key gate lets an AI agent act only after a second, independent signer agrees. In my Command Center a Claude model plans each action and signs first. OpenAI's Codex signs second, from the raw evidence, without seeing the first vote. Two approvals run the action. Any disagreement waits for me.

In its first 2 days the first key approved all 48 proposals. The second key approved 25 and sent 22 back for changes. Once it didn't answer at all, and that action waited for me.

22 of 47

Proposals the second key sent back after the first key approved them.

What Command Center is

A local dashboard over my own projects: what's running, memory per project, scheduled tasks, hours spent, and buttons to pause or resume an automation. I built it on 22 and 23 October 2026, in 57 commits across 5 phases. Claude Sonnet agents did the building, each in its own git worktree. Claude Fable wrote their briefs and checked their work.

The gate governed the build itself: launching a builder, merging its branch and deleting old worktrees were all proposals. It's a personal tool, and live control is still off by default: the dashboard starts at logon with it forced off, so a pause pressed there runs as a dry run.

Separation of duties for agents

Finance teams split raising a payment from approving it. The gate does the same with models: none of them approves its own work. A second model from another vendor is less likely to share the first one's blind spots.

Every action is a written proposal classed as read, reversible or destructive, and only reads skip the gate.

What each key checks

  1. The proposal. What will happen, the exact command, the blast radius, the rollback, and raw evidence lines from the collectors. It leaves out the planner's reasoning, so the second signer judges the facts.
  2. The first key. The planning model signs, and its vote is written to the ledger before the second signer is called. For a pause or resume pressed on the dashboard, the first key is a rules check: reversible, a pause or resume, dry run succeeded, free-memory evidence present.
  3. The second key. Codex runs in a read-only sandbox with its own private configuration. It lists its checks first and decides last, and approves only if the blast radius is stated accurately, the rollback is credible and the evidence supports the action. An answer that fails the JSON schema counts as no answer.
  4. The decision. Two approvals execute. Two rejections close the proposal. Every other combination comes to me. A revise goes back to the planner, who withdraws, fixes what was raised and submits a new proposal.
  5. The fallback. If the second key is down, a destructive action fails closed and waits for me. A reversible action the first key approved waits 10 minutes for my veto, then runs. Two signer failures in a row switch the gate to human-only until I reset it.

What the ledger keeps

The ledger is the audit log: one append-only file, one JSON line per event, flushed to disk on every write. It holds the proposal, each verdict with its checks and conditions, the outcome and the execution result. My decisions go in as a verdict signed with my name. After a restart the held queue is rebuilt from the ledger, and a proposal with an execution line can't run again. Two days produced 251 lines, including 29 execution records, none failed.

What the second key caught

The first builder launch took 8 proposals over about 1 hour 45 minutes. Codex asked for changes 7 times, and the rounds added code: a rollback for the worktree creator, a lock check before any destructive rollback. The evidence grew from 129 lines to 794 before it signed.

After the sixth round I added a proportionality rule to its prompt: scale scrutiny to the blast radius, and prefer approval with conditions for local, reversible actions. The next five launches took 6, 1, 1, 3 and 1 rounds.

On the task that starts the dashboard at logon, a Codex revise produced a flag that stops an inherited setting from switching live control on. I decided 3 held proposals myself: approved 1, rejected 2 that the first key had passed.

Where I stay in the loop

I'm the third signature when the keys disagree, when the second key is down on a destructive action, and on everything in human-only mode. Live control is a switch only I flip.

Questions people ask

Why use a model from another vendor as the second signer?

It reads the same evidence with different training. In my gate it disagreed with the first key on 22 of the 47 proposals it signed.

Does every AI agent action need two signatures?

Reads run straight through. Reversible and destructive actions need both keys. If the second key is down, destructive actions wait for a person and reversible ones get a 10-minute veto window.

Related work

My own job-search automation runs on the same rule: a person approves anything that leaves the machine under my name. How that system fails quietly is in why automation fails silently, and the build is in the case study.

If you're letting AI agents take actions in your business and want a gate like this around them, I build these.