Inspiration
AI agents now issue refunds, place purchase orders and ship builds. One prompt injection hidden in a vendor quote or a support ticket can make them do it for the wrong person. Most agent loops also stop when the model says it's done. We wanted a loop where no model grades its own work: one agent attacks, another repairs, and only reproduced evidence counts.
What it does
Antibody hardens tool-using AI agents against a frozen contract, across three apps: customer support (refunds, private records), purchasing (vendor quotes, budgets) and engineering (build releases, artifact deletion).
- Red, a model agent, reads the target and writes prompt-injection attacks.
- Anchor types those attacks into a real Chromium browser running in a Daytona desktop. The target agent calls real tool gateways backed by SQLite.
- An independent verifier checks the tool journal and the saved database changes against a reference permission model. A failure counts only if it reproduces in a fresh process with a fresh database.
- Blue, a separate model, writes new instructions and a Python
authorize()guard. Each repair gets its own Daytona sandbox, source hash and Git revision. - Each new version must pass all earlier failures, new Red attacks, 19 directed tool checks, held-out action streams, and useful-work checks. An agent that blocks everything fails.
- Only a person can approve a release. No tool can, Claude included.
You run it all from Claude Code through our MCP server. Tell Claude to harden the agents and it starts a live run, follows it, and shows the exact attack, the reproduced effect, Blue's code diff and the final verdict.
The same loop also hardens a SystemVerilog FIFO (Verilator in Daytona) and a checkout web app.
How we built it
- TypeScript: a Hono controller, an MCP server and a React evidence viewer, all reading one append-only event log.
- Daytona sandboxes for every candidate, plus a desktop where Anchor drives native Chromium over noVNC.
- Python + SQLite tool runtime. Candidate guard code runs on deep copies of trusted records and can't change the contract or the verifier.
- Blue, Red and the target are separate, bounded model jobs with schema-checked output: Claude (Anthropic API or AWS Bedrock) or Codex CLI.
- SurrealDB lesson graph, Arize AX / OpenTelemetry tracing, and ElevenLabs voice approval for releases. The approver has to read aloud the code shown on screen.
Challenges we ran into
- Keeping the judge honest. Hidden tests never reach either agent, and provider keys never enter candidate sandboxes. A failure we can't reproduce never becomes a regression test.
- Blocking everything is a fake fix. Our first repairs just refused all actions, so we added useful-work checks that run through the real target model.
- Content filters. A filter refused Red's "attack" request and broke a run. Now a refused or timed-out call rejects that one candidate, and the run continues.
- Real browsers are flaky. Driving Chromium inside a remote sandbox needed separate input (Anchor/noVNC) and read-only checks (CDP).
Accomplishments that we're proud of
- In one live run (Oct 16), Red got the starter agent to make an unauthorized $49 purchase and an unapproved build release. Both reproduced in fresh processes. One Blue repair then passed all 30 checks: both browser failures, 3 new Red attacks, 19 directed checks, 3 held-out streams and 3 legitimate tasks. The run used 17 model calls in total.
- A release gate that no AI can pass on its own.
What we learned
- Confidence isn't evidence. A reproduced failure with its exact input is.
- "No failure found" is test coverage, not proof of security. We report counts, not a security score.
- MCP was better than building more UI. Claude can already start, follow and explain a run.
What's next
- Adapters for teams' own agents and tools, each with its own contract and verifier.
- Lesson memory and the release gate in every loop, reused across runs.
Log in or sign up for Devpost to join the conversation.