Inspiration

A coding agent says “done.” It has edited files, perhaps even run its own tests. But when should those edits become the platform's real, persistent state?

That question inspired CommitGate. A sandbox limits where an agent can operate; it does not, by itself, decide which changes deserve to survive into the next turn. Checking the workspace after a bad change has already become authoritative is too late for that boundary.

CommitGate — verified workspace transactions for AI agents. No evidence, no effect.

What it does

Every agent in the configured platform gets CommitGate automatically. Users create an agent and use the existing Playground as before: no special prompt, per-agent policy form, or additional agent tool call is needed.

Each turn runs against an isolated candidate rather than the persistent workspace. Only an immutable proposal, verified by platform-owned checks and authorized by a one-shot permit, may become the next authoritative workspace.

The product tells a simple story:

HEAD → PROPOSAL → PERMIT → HEAD

  • COMMITTED: the exact verified proposal becomes the next workspace version.
  • QUARANTINED: a policy violation or explicit trusted-check failure rejects the proposal.
  • CONFLICTED: the proposal's base state is stale, so it is not promoted.
  • ABORTED: cancellation, missing evidence, or an infrastructure failure stops the attempt.

For a non-commit, the attempted changes do not enter the authoritative workspace. Rejected output stays out of the next continuation, and the session is fenced. The UI distinguishes an unchanged workspace HEAD from an updated session View.

See the difference in a real workflow

Normal change: ask a new agent to create services/checkout/config.json with a small checkout configuration and result.txt containing COMMITGATE_OK. After trusted verification, the workspace advances from generation gN to gN+1.

Rejected change: ask it to change infra/production.yaml to replicas: 0 and create rejected-marker.txt. The deployment policy rejects the protected-path change; neither attempted change is promoted. The receipt shows:

Candidate world:   changed
Persistent world: unchanged

This is not an agent merely promising to behave. The gate makes the decision outside the agent's writable environment. Candidate-supplied tests cannot replace the trusted checks, and replaying a consumed permit through the public API returns 409 PERMIT_REPLAY without changing HEAD.

How we built it

We extended the supplied Agent platform rather than rebuilding its UI, CRUD, Playground, or Codex execution loop. The main integration points are AgentService, the Runner interface, Fastify endpoints, and receipt/version-history UI.

The default Docker topology separates responsibilities:

  • Transition Worker: the sole service with write access to authoritative and control volumes. It owns sealing, evidence, permits, promotion, versions, and recovery.
  • Runtime Broker: the sole service with the Docker socket. It launches restricted agent and verifier containers using run-scoped references.
  • Model Relay: holds the real model-provider credential; the agent receives a scoped relay capability instead.
  • Agent container: writes its isolated candidate, not the persistent workspace.
  • Trusted Verifier: reads a proposal export with isolated scratch space and no network.
  • API/UI: orchestrates the product and displays projections, with read-only authoritative/control mounts.

The Worker seals the candidate after runtime teardown. Trusted evidence binds the proposal to the policy, check bundle, verifier identity, and base View. Promotion requires a one-shot permit plus generation/View compare-and-swap, so an old proposal cannot become valid just because file contents happen to return to an earlier hash.

Version history is append-only: rollback creates a new version rather than rewriting history. An event log and transition journal support recovery at tested process-kill points. Signed receipts provide offline integrity checks; they do not prove that the Worker or host is uncompromised.

Challenges we ran into

The hardest issue was ensuring that the object verified is exactly the object promoted. Re-reading a mutable candidate after verification would reopen a time-of-check/time-of-use gap. A gate-owned sealed proposal gives verification and promotion one shared source.

Another challenge was cancellation racing with promotion. Once cancellation is accepted, the run must not later commit. Once a transition becomes irreversible, the API must report that fact rather than misleadingly display “cancelled.”

We also had to separate file state from conversation state. Rejecting files while reusing an agent continuation that assumes success would undermine the next turn. Session epochs and callback fencing address that mismatch.

Accomplishments and verification

The frozen pre-video evidence includes real provider-backed browser flows, permit replay, fresh-session follow-up, rollback, multi-agent reference isolation, Docker topology checks, Linux filesystem checks, and process-restart recovery scenarios.

The source-bound browser clean-clone report records 12/12 scenarios verified. Additional reports cover policy violations, forged candidate test runners, environment-variable hijacking, stale Views, accepted cancellation, malformed evidence, and receipt verification. These are project-generated evaluations, not an external audit or an official score.

The public repository includes an immutable evidence snapshot, a one-page editable architecture diagram, and source/evidence archives with SHA-256 checksums. Reports identify the tested source revision and applicable image digests.

What we learned

The valuable boundary is not “the model finished” or “a test passed.” It is the moment an untrusted attempt becomes authoritative state. A useful middleware layer must own that transition, expose an understandable product outcome, and make failure as reproducible as success.

We also learned to keep the claim narrower than the implementation: stronger evidence matters more than a larger list of features.

Try it and extend it

Follow the repository's Reviewer Quick Start: configure MODEL_*, run npm ci, start npm run demo, then run npm run demo:auth in a second terminal. Open the local UI and create a fresh agent; CommitGate is already applied.

Policy is a deployment-time, Worker-owned extension contract. The current profiles are workspace-default@1 and deployment-protected@2. Operators extend versioned profiles and rerun policy-bound evidence; agents and API callers do not supply arbitrary protection rules.

Boundaries and what's next

The guarantee is limited to Linux Docker, serial transitions per agent, workspace filesystem effects, and tested process/container kill-and-restart scenarios. It does not cover external API rollback, sudden power-loss durability, a hostile host/root or Docker engine, complete information-flow isolation, or semantic correctness of every accepted change. Passing means satisfying the configured trusted checks, not proving a patch is universally correct.

The next step is to finish the narrated demonstration and final evidence packaging, then explore additional versioned policy packs without turning the gate into a new agent platform.

Built With

Share this project:

Updates

Submission history