The software your agents are built on.

Estelle is the framework your agents are written with, shipped with, and repaired in. It goes to production with them and keeps working there. The nine suites are how that shows up, and you do not pick between them: Estelle invokes them on its own as it does the work, in your editor and under your running agents. Every one below is live.

Nothing mergesuntil it's proven.

How the gate works
  • Deterministic, not a second opinion. A parser and a set-membership test against your real code, with no model in the loop, so the same diff always gets the same verdict.

  • Every claim resolves to a file and line. A claim that passes carries its citation. A claim that resolves to nothing is refused rather than softened into a maybe.

  • It runs where merges happen. The check arrives on the pull request, so an invented API is stopped before a reviewer spends attention on it.

estelle / grounding-gate#214resolving
create_user()diff · api/routes.py:+112queued
extract
symbol table
membership
RateLimiter.allow()diff · api/routes.py:+118queued
extract
symbol table
membership
retry_backoff()diff · api/routes.py:+131queued
extract
symbol table
membership
0 proven, cited0 refusedchecking the diff against the repo
estelle · gate
no model in the looprequired check

Three operations, none of them probabilistic: parse the diff for the symbols it claims, look each one up in the symbol table built from your real code, and test for membership. The same diff gets the same verdict every time, which is what makes it safe to make required.

One memory,for the whole team.

  • Code-native, not a chat log. Recall is addressed by file and line, so an answer points at the code it came from instead of paraphrasing a conversation about it.

  • Gated by role, never leaking across. Each repo and each team keeps its own namespace, and a question scoped to one never resolves against another.

  • The reasons live outside the diff. It indexes the threads and the issues where decisions were actually made, because the code alone cannot tell you why.

Team memoryfatelabs / api
decisionssessionsconventionsreposrepos/billing
decisions/0007-retry-queue.md+6 0
Why we forked the retry queue off the main worker
cited
2d
sessions/checkout-incident.md+12 3
Stripe webhook failure, root cause, and PR #218
cited
3h
conventions/pagination.md+4 0
Cursor pagination on every list endpoint, cited
cited
1d
repos/api/auth-model.md+3 1
Session TTL, refresh path, and the gate on /login
cited
4d
recall
grounded
why did we fork the retry queue?
decisions/0007-retry-queue.md:12cited
src/queue/retry.py:130cited
role: engineer · repo: api · two cited passages, nothing outside the role
one brain, for the whole team

The codebase, the decisions, and the work in flight, recalled with citations. Access follows role, so an engineer's agent sees what that engineer can see. Repos and teams stay in separate namespaces.

role-based accesscited recallnever leaks across

It buildsin your real files.

Read the docs
  • Real edits, not a suggestion box. It works in the actual repo on a branch, so what you review is the change itself rather than a snippet to transcribe by hand.

  • Every change carries its citation. Each edit resolves to the code it was derived from, and the gate refuses the ones that do not.

  • A reviewable pull request by default. The base plan is a sandbox write and an open PR. A human merges it.

fate-labs · api/users.pyestelle · done
users.py query.py pagination.md
41def list_users(session, cursor=None):
42 q = select(User).order_by(User.id)
- page = q.offset(offset).limit(PAGE)
+ if cursor:
+ q = q.where(User.id > cursor)
+ rows = session.scalars(q.limit(PAGE)).all()
47 return Page(rows, next=_cursor(rows))
estelletests green in sandbox
read src/api/users.py · src/db/query.py
edit cursor pagination · every line cited
out · reviewable PR
tests green
+18 −4every line citeda human merges
estelle · code

Estelle works in your real files, in the same editor you already use. It reads the code that exists, makes the change, runs the tests in a sandbox, and cites every line it touched. The result arrives as a reviewable pull request, and a human merges it. Propose-only by default.

reads before it writessandbox-tested

Review that landson the pull request.

  • Grounded in the repo, not the diff. A change that breaks a caller three files away is found because the caller was read, not because the pattern looked risky.

  • Adversarially cross-checked. Findings are put to an independent pass that tries to refute them, so what posts is what survived.

  • Cited comments, on the line. Every finding arrives attached to the code it concerns, with the evidence that produced it.

Review · PR #231advisory
src/auth/session.py:52
TTL ignores the refresh path, so long sessions never expire.
evidence · src/auth/refresh.py:19
src/db/pool.py:88
This diff drops the pool cap from 20 to the default.
evidence · git blame · this PR
1 finding could not be grounded, dropped before you saw it
grounded comments
2
each cited to evidence
ungrounded, dropped
1
never reached the PR
estelle · review

Review reads the diff against the whole repository, not just the patch. Every comment lands on the pull request anchored to the exact line, with the evidence cited. A finding that cannot be grounded in the code is dropped before you ever see it.

anchored to the lineevidence citedyou decide what ships

Watches production.Finds the line.

See how tracing works
  • From a failure to a file. It follows a production error back through the trace to the exact line, instead of stopping at the service that happened to report it.

  • It says where, not just what. An alert names the code path that broke and the change that introduced it, so triage starts at the cause.

  • The fix goes through the gate. A repair is checked like any other change and arrives as a pull request, not as a silent write to production.

acme-storefront.com/checkout
Acme Storefront
Pay $48.00
Pay
link
OR
Email
estelle@fatelabs.ca
Card information
5312 6698 4471 2035
04 / 27
257
Cardholder name
Alex Rivera
Country or region
Canada
 
acme-storefront · productioncheckout health: operational
active error sessions
3
LIVE
60m agonow
checkout errors 3error rate 0.1%nominal
estelle is tracing the failure to source…

Long sessionswithout the drift.

  • A ceiling on the context, enforced every turn. The working set is fitted to a token budget derived from the model's own window, so a session that has run all day sends a prompt the size of the one that started it.

  • Curated context, not a bigger window. What the model already tried is distilled into short lessons and kept when the raw trace is cut, so a dead end is not re-read at length and not walked twice either.

  • Model-agnostic, on your keys. It sits under whichever model you already pay for, and never asks you to switch to keep the benefit.

guardian · lever ablation, loop family
measured 2026-07-30, n=8

We took our own feature apart and scored each lever on its own, with the grounded recall held byte-identical across all six arms so the only thing that varies is the lever. Two independent runs, both shown.

Step-zero accuracy is exactly 100% on all six arms in both runs, so every gap above is degradation and not difficulty. Scope, stated: one model (gpt-4o-mini), one session length, n=8. Wilson 95% on 8 of 8 is 68 to 100 and on 4 of 8 is 22 to 78, and those intervals overlap, so read the +50 point estimate, reproduced twice, as strong directional evidence on a 14-probe fixture rather than a population rate.

the lever that earned its place
error curation, loop family
50% to 100%
tokens sent
3.4x fewer

The mechanism is visible in the last column of the table: truncation leaves the model evidence of 1 of 4 failed attempts, curation restores 4 of 4 as compact lessons. It also beats keeping the whole verbose trace, 100% against 87.5% and 75%, while sending 32K tokens instead of 108K. The same information, distilled, outperforms the same information, verbose.

what measured zero
  • Rot budget

    No measured accuracy effect: 37.5 and 50.0 against the governor's 50.0 and 50.0. It does cut the prompt 19%, so it is a cost lever, not an accuracy one.

  • Goal recitation

    Earned nothing on its own. The drift family scored 100% with it and without it in both runs, and on the loop family it scored 25.0 and 50.0 against 50.0 and 50.0: never better, once much worse.

  • Repetition ratio

    Could not be scored. It is a trigger, not an output, and it only inspects the last eight turns, so a slow loop spread over a long session reads 0.00.

Guardian’s separate 100% against 20% retention number belongs to the grounded recall paging the fact back into the prompt, not to these levers: a governor plus oracle control arm also scores 100%. We tested our own feature, found most of it contributed nothing on this battery, and shipped the part that works.

Many agents.One orchestra.

  • Parallel work, properly isolated. Each agent gets its own git worktree, so two of them editing the same file cannot corrupt each other's run.

  • Routed by cost and by difficulty. Cheap work goes to a cheap model and hard work escalates, across every provider key you have already bought.

  • One autonomy ceiling for every lane. All of them merge through the same gate, and no lane can raise its own permissions to get around it.

orchestra · 30-day routing, worked example
settling
saved
$0
requests routed
100,000
Every request at the frontier$31,000
Estelle cost-routed$0
Routing tableshare · requests · per request
Retrieval, lint, format, test scaffoldsClaude Haiku 4.5 · Kimi K2.6
62% · 62,000 · $0.012
Implementation, refactors, grounded editsClaude Sonnet 5
27% · 27,000 · $0.090
Architecture, hard debugging, deep reviewClaude Opus 4.8
11% · 11,000 · $0.310
Every lane runs on a key you already own, and all of them merge through the same gate. Cheap work cannot escalate itself.

A pentestthat never stops.

  • It runs against a clone, never production. The attack surface is a mirrored sandbox, so a probe can be as aggressive as it needs to be without reaching a customer.

  • Finds it, then proves it. A finding carries the request that reproduced it. The ones that cannot be reproduced are not filed as findings.

  • Arrives as a gated pull request. The fix comes with its repro attached and waits for a human, like every other change Estelle proposes.

acme/storefrontclone · sandbox-7f2 · never productionsweeping
swarmfour probes, one clone, in parallel
probe-01session replay, token confusion
probe-02sort-param injection, 412 payloads
probe-03header spoof, trust-boundary walk
probe-04entropy sweep over the working tree
probes resolved
0 / 5
exploitable
0
not exploitable
0
criticalEST-0441Authentication bypass on session refreshprobing
CWE-287POST /auth/refresh
criticalEST-0442SQL injection via sort parameterqueued
CWE-89GET /api/orders
highEST-0443Trusted header spoof reaches admin routesqueued
CWE-290GET /admin
mediumEST-0444Secrets committed to the working treequeued
CWE-798repo scan
mediumEST-0445Rate limit absent on password resetqueued
CWE-307POST /auth/reset
Probing a mirrored clone. Nothing here touches production traffic.
estelle · disposition
repro attacheda human merges

The one exploitable finding leaves as a gated pull request against middleware/auth.py:63, with the spoofed request that proved it and a regression test that fails on the current code. Nothing is written to production, and nothing merges on its own.

Drop it underany agent you run.

Wire up MCP
  • MCP, so it works where you already are. Claude Code, Cursor and any other MCP client pick it up without rewriting the agent around it.

  • It grounds the tool call, not just the prose. Claims and tool arguments are checked against your real code before the agent is allowed to act on them.

  • Your keys, your repo. Estelle is the infrastructure around the model rather than another model, and it never marks up what you already pay for.

Thread#eng-incidents
Khai11:42 PM
@Estelle why did checkout start failing in prod?
EstelleAPP11:43 PM
read webhooks/stripe.py
searched Stripe webhook changelog
grounded 3 claims to file and line
Your Stripe webhook still listens for charge.succeeded, which Stripe deprecated when checkout moved to Payment Intents, so paid orders never confirm. I opened PR #218 with the fix, gate-verified against Stripe's current docs.
Grounded in
webhooks/stripe.py:38docs.stripe.com/webhooksPR #218
connected surfaces
live
Slackconnected
GitHubconnected
Linearconnected
estelle · under the agent

Estelle sits under any agent you run, over MCP, and checks every answer against your real repo before it posts. A claim it cannot ground is refused.

refuses what it cannot resolve to a file and line

cites every claim it does let through

runs underCursor · Claude · CI · your keys