Inspiration

A single AI code reviewer can hide the tradeoffs behind its answer. A security concern, a performance improvement, and a compatibility risk deserve different perspectives. We built Perch to make those perspectives visible: five reviewers debate a change, challenge each other's evidence, and show the developer how they reached a decision.

Perch grew from the Cisco Cloud track's Collective Intelligence challenge and the shared-channel pattern in Cisco's coffeeAGNTCY demo. Our goal was to make disagreement useful, inspectable, and grounded in the code.

What it does

Perch reviews a pasted or uploaded code diff, or a real GitHub pull request. Five AI reviewers bring distinct priorities: Security, Performance, Compatibility, Quality, and Product.

Reviewers first assess the diff independently. In later rounds, they reference actual peer messages to agree, challenge, or propose a compromise. They can change their positions when evidence warrants it or pass when they have nothing new to contribute.

The browser presents the diff, reviewer contributions, positions, confidence, and the final tradeoff map. For ordinary reviews, a judge reads the diff and debate to return an approval, requested changes, or a block, with a root cause and suggested fix. An uncertain judge can request up to three additional debate rounds. Critical security findings escalate to a human.

GitHub integration lets developers load open pull requests and choose which ones to review. An optional automatic mode watches for new revisions. The local queue preserves results and transcripts across restarts, avoids repeating unchanged revisions, and supports pausing, ignoring, and retrying reviews. Results stay local; the browser workflow does not post comments to GitHub.

How we built it

We froze a shared Python contract early: typed Message objects published to a Bus with publish and subscribe. Four teammates could then work against the same data shape while prompts lived in editable Markdown files.

The runtime gives each reviewer the diff and prior-round transcript. Reviewers in the same round work from the same history, so a later response cannot simply echo an earlier response from that round. A round clock coordinates turns; reviewers choose their own contributions. The separate judge evaluates the resulting debate.

Pydantic validation checks model output, including positions, confidence, and references to real earlier peer messages. The runtime sets reviewer identity, review ID, round, message ID, and timestamp itself. Invalid responses receive a corrective retry. Required assessments fail explicitly if they remain invalid, rather than being presented as successful reviews.

Convergence rules are implemented in code. Critical security risks stop the debate; otherwise stable positions or the round limit lead to a severity-based decision and judge evaluation. The final map includes resolved concerns, remaining disagreements, human decisions, and reviewer positions derived from the actual transcript.

Our backend uses FastAPI, WebSockets, asyncio, and SQLite. The React and TypeScript frontend uses Vite and Tailwind CSS. Model access is configurable, including an Ollama endpoint hosted on NVIDIA Brev and a Cisco proxy option. A concurrency limit and response cache help manage latency and repeated development runs.

The transport abstraction supports an in-memory bus and Cisco AGNTCY SLIM group messaging. Our SLIM adapter uses a publishing hub and receiving tap because group members do not receive their own messages. Publishing waits for local handlers to finish, preserving the ordering that the debate relies on.

Challenges we ran into

Models sometimes returned malformed JSON or invented references. We addressed that with explicit prompt rules, typed validation, server-controlled identity, and corrective retries.

Early prompts encouraged superficial agreement. Distinct reviewer priorities and evidence-based rebuttal rules helped expose useful disagreements.

Slow model calls revealed a SLIM timeout bug: a receive timeout was being mistaken for a closed session. Distinguishing those conditions kept the shared channel alive while reviewers were thinking.

Streaming also introduced a race: messages can arrive before the browser opens its WebSocket. Per-review history lets a late connection receive the backlog. Persistent queues required an additional guard against two servers processing the same local queue.

Accomplishments that we're proud of

We built an end-to-end system connecting real diffs, five reviewer perspectives, a structured debate, and an actionable decision. We integrated Cisco SLIM and tested full council runs over the real transport. We also added GitHub access, durable review queues, and validation that keeps model-generated claims separate from application invariants.

We assembled eight reverted pull requests from real open-source projects to compare the council with a single-reviewer baseline. The dataset gives us a concrete way to investigate where multiple perspectives help; we do not claim a measured advantage before completing that comparison.

What we learned

Typed protocols make multi-agent behavior easier to inspect and test. Models can supply judgment while application code owns identity, references, and decision rules. Disagreement takes deliberate design, and latency changes assumptions that seem harmless in fast demos.

What's next for Perch

Complete and report the baseline comparison, improve live progress and reviewer history, distribute reviewers across separate processes over SLIM, and add richer observability. We also want configurable reviewer roles so teams can bring accessibility, cost, or compliance perspectives into the debate.

Built With

Share this project:

Updates

Submission history