Riding two AI horses: Claude Code and Rovo
Ten revisions in one afternoon took a design document from first draft to near perfect, by my own read, with Claude Code and Rovo each adding what the other couldn't see.
The job was a design document for a small infrastructure module: create an API key on one cloud and deliver it to a service running on another. I gave it to Claude Code and to Atlassian's Rovo, and sat between them as the harness. Each one's answer went to the other as a challenge. At the tenth version I published 1.0 to the ticket. By my own read it was near perfect, and Rovo's final review supported that: it found every design decision traced to the code or the docs. Every claim was re-checked against the tickets and the wiki, and the two questions left open each had a named owner.
Two AIs, two different views
| Brings | Doesn't see | |
|---|---|---|
| Claude Code | The code: modules, configs, providers, a grep away | The org: decisions in tickets, standards in the wiki, design docs |
| Rovo | The org: Jira tickets, Confluence pages, design docs | The code |
| Me, the harness | Both answers side by side | Nothing on its own; my job is to make them meet |
One AI working alone shares its own blind spots. Two AIs with different views each lift what the other can't reach, and the design got better at each of the four turning points below.
Four turning points in the iteration
| Revision | The plan until then | What the check found | What it became | The value |
|---|---|---|---|---|
| v0.4 | The code can write the key to the secrets store | Claude Code searched the code: no such path exists | Seed it by hand first, automate later | A two-second search found it |
| v0.5 | The platform already does this | Claude Code asked Rovo for the file. Rovo couldn't cite one: the feature was a draft design that never shipped, and Rovo said so | Copy a pattern already running in production | No manual steps, and rotation automated in the design |
| v0.7 | A key made on one cloud is visible to a service on the other | Rovo found a rule in the design docs, not the code, that says it isn't. This one would have passed review and failed at the first deploy | Treat it as a vendor credential | A failure that would have passed review, found at the design stage, and three fewer dependencies |
| v0.8 | The credential path still matches after the rename | Rovo traced how the platform finds credentials: the new name pointed at a folder that doesn't exist | An open question for the platform owner, with three ways to resolve it | A failure the pipeline can't see, found in the document and left as a named open question |
Rovo caught me once too. My v0.6 live test ran in a dev project, so my "the blocker is fixed" was an inference, and at v0.8 Rovo flagged it as one.
The lesson from v0.5: when an AI says "the platform already does this", ask for the file. If it can't cite one, that is the answer.
What I did in the middle
- Fed each answer across as a challenge, not as a summary.
- Asked for citations: the file, the ticket, the closest working example.
- Ran a live test when both AIs were guessing about the running system. Neither of them can see production.
- Set the document's shape, so the top section pastes straight into the ticket.
- Decided when it had converged, and published it.
How this compares with the Swiss cheese model
James Reason's Swiss cheese model is the classic picture of safety layers: each slice has holes, and harm gets through only when the holes line up. My agent fleet already runs on it: a doer, a validator and a gatekeeper as separate layers, which I describe on my AI Boost page.
| Swiss cheese | Two horses | |
|---|---|---|
| What it's for | Stopping a bad outcome | Raising the quality of a design while you build |
| Shape | Fixed layers, one pass | A loop, ten versions here |
| The layers | Static | Each round patches the hole the other found |
| When to stop | Every item passes every layer | When a round finds nothing new |
| Where it fails | Holes line up | Both AIs share a blind spot |
The two-horse loop borrows the Swiss cheese idea for a different job: two layers, picked because their blind spots differ in kind, run as a loop while you build. The weak spot in any layered check is layers that share the same holes, like a model reviewing its own work. Picking two AIs that can't see the same things avoids that by design. My live test was a third slice when both of them were blind.
Which one is more efficient depends on the work. I haven't timed the two side by side; this is how I choose.
- For a one-off design, the loop wins. What decides the quality is the assumptions underneath, and a stack of reviewers with the same context lets those through. Each round of the loop goes straight at one assumption.
- For work that repeats, the layers win. Every pull request, every deploy, every run: fixed checks run on each one without a person in the middle.
- Use both, in that order. Design with the loop, then turn each catch into a permanent layer: the v0.4 search can become a check in the pipeline, and the v0.7 rule a lint. The loop is a one-time cost, and the layers keep working after it.