specialist agent · Pydantic AI · Python
Sentinel
Finds the bug, then tries to disprove itself
A code review agent with an adversarial second stage. Only findings that survive a majority reach you, so the report is short and real.
Verification panel · F-418
Unbounded session payload can be written to a key that never expires
- correctness: confirmedTrue of the signature: data is Record<string, unknown> and createSession imposes no limit itself.
- security: refuteddata is never attacker-controlled. Both call sites build it from already-validated server-side fields.
- repro: refuted64 MiB payload → PayloadTooLarge at store.ts:16, nothing written. express.json caps the body at 16 KiB first.
01What makes it special
Three verifiers, each told to refute
Every candidate goes to three verifier agents built from the same code with different instructions: correctness, security and repro. They run concurrently, default to refuting when unsure, and a finding is reported only if a strict majority confirms it.
The repro lens reasons over the diff and the surrounding source. It does not execute code.
Killed findings stay on the page
Refuted candidates are printed with each lens’s reason, struck through rather than dropped, so you can watch the filter work instead of taking it on faith.
A vague finding fails the type
Findings are typed Pydantic models, and the failure scenario is a required field that must name something observable: a literal input, an expected-versus-actual result. A hedged claim, or one citing a line the diff does not contain, is rejected and handed back to the model to fix.
No way around the panel
If the model skips a lens, the orchestrator runs it anyway, and reporting a finding that was never registered is a hard error. A confirmed critical or high exits with code 1, so it drops straight into CI.
02Inside the demo
- run 1/3
||vs??regressionA one-character change that makes an explicit ttl of 0 unreachable. - run 2/3A finding gets killed 2–1Sentinel raises a plausible OOM claim, then the panel refutes it. Nothing is reported.
- run 3/3Critical: auth guard narrowedread_diff fails on a detached HEAD, then an empty bearer turns out to grant scopes ["*"].
Watch forA finding getting killed. Sentinel surfaces its own refuted candidates so you can see the filter working: this is what keeps a review from being plausible-sounding noise.
03Under the hood
- Stack
- Pydantic AI · Python
- Pattern
- Typed agent + adversarial verification ensemble
- Packages
- pydantic-ai · pydantic
- Source
- agents/sentinel-review/sentinel/reviewer.py
- Doc
- api_documentation/pydantic-ai.md
Pydantic AI validates every finding against a schema and retries the model when it does not conform, so the verification stage receives structured findings rather than prose it has to parse. Strong typing is what makes the multi-voter stage cheap to build.
Tools
read_diffrisk: safeRead the changed hunks under review.raise_findingrisk: safeRaise a candidate finding with a concrete failure scenario.verify_findingrisk: safeAttempt to refute a finding through a named lens.
Watch a review run
The diff, the run log and every panel vote, across 3 reviews.