Stripe: Deterministic Nodes Around Agent Nodes
Read24 min · Slice → Gate → Run → Wrap → Prove · Updated 2026-10-28
You end this lesson with: factory/adopt/stripe.md — your line's blueprint with deterministic and agent nodes marked, copied from the Stripe shape
Chapters
- What is actually going on01
- The rule and its condition02
- Worked case03
- Faded case04
- Open case05
- Where this breaks06
Lesson 18. Stripe: Deterministic Nodes Around Agent Nodes
Stripe's engineers work in a very large Ruby codebase backed by more than three million tests (Stripe, part 2, self-reported, observed 2026-10-28). When the team first pointed coding agents at it, the cheap fixes broke in ways Stripe has described in its own words. A rule in the prompt telling the agent to run the linter was unreliable, and a speaker at a May 2026 talk says the team moved that step into code (Stripe talk, spoken, observed 2026-10-28). Agents sharing working directories interfered with each other and wasted tokens, so the team rejected that setup. Rule files loaded unconditionally filled the model's context at that scale. A CI loop that let the agent keep trying returned less and less for the tokens, compute and time it consumed, so the team stopped it after a fixed number of rounds (Stripe, part 2, observed 2026-10-28). Every one of those costs lands on engineers and reviewers, because a person still reads every pull request. Decide now: on your own line, which steps would you trust a sentence in a prompt to make happen, and which would you refuse to leave to a sentence?
This lesson gives you factory/adopt/stripe.md - your line's blueprint with deterministic and agent nodes marked, copied from the Stripe shape. It serves the Prove stage of the loop: a company page like this one is evidence you copy from, and you leave it with a file that feeds your factory charter.
What is actually going on
Stripe calls its system Minions: unattended, one-shot coding agents that take a task from a chat thread to a drafted pull request. The Leverage team wrote it up in two blog posts, and a Stripe speaker retold the story in a recorded talk. The account in this section comes from those three sources, so treat it as first-party and self-reported.
A run starts where work already lives. Most often an engineer tags a Slack app inside a thread, but the CLI, a web UI, a docs platform, a feature-flag platform and a ticket screen can all launch one, and CI turns a flaky test into a ticket with a button that starts a run (Stripe, part 1, observed 2026-10-28). Before any model runs, plain code gathers context: it calls configured tools over the links found in the thread, and scoped rule files attach as the agent walks the directory tree.
The agent then works on a devbox, a pre-warmed cloud machine of the same type engineers use, ready in about ten seconds, sitting in a QA environment with no production data and no internet egress (Stripe, part 1, observed 2026-10-28). Because the box is the blast radius, the agent runs with full permissions and never stops to ask for confirmation.
Inside the box, a state machine written in code that Stripe calls a blueprint decides the order. Some nodes are agent nodes, such as "Implement task" and "Fix CI failures". Others are deterministic nodes, such as "Run configured linters" and "Push changes", which call no model. Lint heuristics run on every push in a few seconds, then CI runs the selected tests and applies autofixes by itself. Failures that have no autofix go back to the agent once. After the second CI round the run stops, and a person takes the branch (Stripe, part 2, observed 2026-10-28).
The diagram traces that flow. Read the boxes marked AGENT first: there are two, and each is surrounded by code.
Every path ends at the review box. The only loop that returns to an agent passes through lint and CI again, and it runs once. That is the whole design in one line: the agent writes the diff; the line decides what happens to it.
The rule and its condition
Use a blueprint of code nodes with agent nodes inside it when the step you care about has a result a command can read, such as lint, push or CI status. Leave a step to the agent only when it needs judgment and a code node can check the result afterwards. Otherwise, if neither exists, the step does not belong in an unattended line yet. This is the pattern Lesson 08 teaches in general form; this page shows one company running it.
The table fixes seven dimensions so you can set this page beside the other company pages.
| Dimension | Stripe Minions | Source and label |
|---|---|---|
| Trigger | A Slack tag in a thread (most common); also CLI, web, docs and feature-flag platforms, a ticket screen, and a one-click button on CI-detected flaky tests | Stripe part 1, first-party |
| Where the agent works | A pre-warmed isolated devbox, ready in about ten seconds, QA environment, no production data, no egress | Stripe part 1, first-party |
| Gates before merge | Lint heuristics on every push in under five seconds; one CI run with autofixes; one agent repair for what is left; stop after the second round; the full battery is over three million tests | Stripe part 2, self-reported |
| Who approves the merge | A person on every PR: the engineer who launched the run opens it and asks another engineer to review | Stripe part 1, first-party |
| After merge (staging, rollback) | Not described for minion PRs in either post | Absent from part 1 and part 2 |
| Scale claim | "Over a thousand" merged PRs a week in part 1, then over 1,300 about ten days later in part 2; both self-reported by Stripe. A speaker also said about 65% merge unchanged: spoken only, with no window | Part 1, part 2, talk, self-reported |
| What the company has not published | The share of all merged PRs these represent, the merge rate of opened PRs, a revert or defect rate, token or dollar cost per PR, reviewer time per PR, any incident or rollback data for minion changes, and whether "no human-written code" counts edits a reviewer makes after follow-up instructions | Stated gaps in the two posts and the talk |
What it does well: the gates are code, so they run on every run, and the cap turns an open-ended cost into a bounded one. Reusing the devbox humans already use means the agent meets the same lint, tests and rules an engineer would, and one set of scoped rule files serves both.
What it costs: a devbox fleet, a test battery fast enough to feed an agent, and a tool catalog. Stripe says its central tool server held more than 400 tools in part 1 and nearly 500 in part 2, with curated subsets per agent (Stripe, part 2, observed 2026-10-28). Few teams have that infrastructure on day one, and the posts do not price it.
Worked case
Here are the mechanics worth extracting, each tied to the lesson that teaches it.
Gates in code, not in the prompt (Lesson 08). The talk's speaker says rules like "please run lint" fail often enough that the team moved them into the blueprint (Stripe talk, spoken, observed 2026-10-28). This is the Graph Engineering point from lecture 3 on node contracts and lecture 6 on a model judging while the graph decides.
Hydrate context before the agent starts (Lesson 13). Deterministic code attaches thread links and scoped rule files, so the model starts with the task and its context already in hand, and conditional rules keep the window from overflowing.
Isolation in place of prompts (Lesson 03, Agent Fleets lesson 07). The agent's autonomy comes from the box, not from trust. The devbox carries no personal credentials, which is why this design needs no per-command approval.
Two CI rounds, then a human (Lessons 08 and 07). The cap is the exit; the exit is a person. In the language of risk lanes, an exhausted cap is a trigger for the lane where a human reads the change.
A different person reviews (Lesson 04). The launcher opens the PR and asks someone else to review it. That is the author-never-holds-the-key rule applied to a human who prompted the agent.
Entry points where work lives (Lesson 01). A chat tag and a flaky-test button put the queue in places engineers already visit, so the line starts from existing queues instead of a new tool.
A curated tool catalog (Lesson 11). A central tool server gives each agent a smaller subset, and an internal control framework blocks destructive actions. Stripe publishes no scorecard or approval routing for this layer, so copy the idea of subsets, not the claim that it works.
Counting without a denominator (Lesson 14). Stripe's one number is a weekly count. Lesson 14 explains why you must record the denominator that Stripe has not.
Now try it on a line of your own.
Illustrative composite. A twelve-person tools team has a ten-step ticket-to-PR line: take a chat tag and create a run; fetch the ticket and linked documents; start a container with no production access; write the change; run the formatter and linter; push the branch; run the test suite and read the failures; repair failing tests; fill the PR template; have a teammate review. The team's draft marks "run the formatter and linter" as an agent step, because the model "knows the repo's commands".
Decide now: which of the ten steps are agent nodes, and what should the draft do about the formatter?
Only two steps are agent nodes: writing the change and repairing failing tests. Everything else has a result a command can read, so it is code: creating the run, fetching documents, starting the container, linting, pushing, running the suite and reading its status, filling template fields. The review is a human node. The formatter step is the trap. An agent that "knows the commands" will skip them when its context is crowded, and the failure is silent. Make the lint an edge that runs on each push, and put a cap of two CI rounds on the test loop. Then write the file. Names in quotes are Stripe's published ones; the rest are yours to fill.
factory/adopt/stripe.md
| Field | Value |
|---|---|
| Line name | |
| Repo | |
| Owner | |
| Date filled |
Blueprint: Stripe's published shape, then yours
| # | Stripe shape | Stripe kind | Your node | Your kind | Done is decided by | Cap | Exit on cap or failure |
|---|---|---|---|---|---|---|---|
| 1 | Tag in a chat thread or ticket button | deterministic | |||||
| 2 | Hydrate context from links in the thread | deterministic | |||||
| 3 | Isolated devbox, no prod data, no egress | deterministic | |||||
| 4 | "Implement task" | agent | |||||
| 5 | "Run configured linters" on each push | deterministic | |||||
| 6 | "Push changes" | deterministic | |||||
| 7 | CI run with autofixes | deterministic | |||||
| 8 | "Fix CI failures" | agent | |||||
| 9 | PR drafted from template | deterministic | |||||
| 10 | A different engineer reviews | human |
Not copied
| Stripe element | Why I skip it |
|---|---|
Save this script as factory/adopt/validate-stripe.sh. It prints every empty cell, every kind that is not deterministic, agent or human, every agent node whose cap is none or n/a, and a missing human row. It exits 1 on any problem, so it can sit in CI.
#!/bin/sh# usage: sh factory/adopt/validate-stripe.sh factory/adopt/stripe.mdawk -F'|' '/^\|/ { if ($0 ~ /^\|[-| ]+\|$/) next if (!inT) { inT = 1; next } for (i = 2; i < NF; i++) { c = $i; gsub(/^ +| +$/, "", c) if (c == "") { printf "line %d: empty cell in column %d\n", NR, i - 1; bad = 1 } } if (NF == 10) { k = $6; gsub(/^ +| +$/, "", k) cap = $8; gsub(/^ +| +$/, "", cap) if (k != "deterministic" && k != "agent" && k != "human") { printf "line %d: kind must be deterministic, agent or human\n", NR; bad = 1 } if (k == "agent" && (cap == "none" || cap == "n/a")) { printf "line %d: agent node needs a numeric cap\n", NR; bad = 1 } if (k == "human") h = 1 } next}{ inT = 0 }END { if (!h) { print "no human node: the line needs a reviewer row"; bad = 1 } exit bad }' "$1"The script was run on a scratch copy of this template. The empty template failed with dozens of lines. A fully filled copy printed nothing and exited 0. Three broken copies each failed with exit 1: an agent node with cap none, one empty cell, and a row whose kind was bot with no human row left.
Faded case
Skip to the open case if this is familiar. Here is how three other published lines differ on the dimensions where they differ from Stripe. Every cell comes from first-party posts, and the numbers are self-reported by each company.
| Dimension | Stripe | Spotify | Ramp | Anthropic |
|---|---|---|---|---|
| Trigger | Chat tag, ticket or flaky-test button | A prompt fans out one agent per repo; also a Slack mention | Chat, GitHub, Linear, web, browser extension | Any PR; its published flow is review and approval, not a launcher |
| Where the agent works | Pre-warmed isolated devbox | Sandboxed container with few binaries, no access to surrounding systems | A cloud VM from a per-repo image rebuilt every 30 minutes | The author's session, then a fresh-context subagent reviewer |
| Gates | Code lint, CI capped at two rounds | Verifiers behind one tool, a stop hook that blocks the PR on failure, an LLM judge that vetoes scope creep | Normal review plus a review agent, secondhand | Required CI, parallel review agents with a finding vote, a security review, a three-round cap |
| Who approves | A person on every PR | Owning teams for agent PRs; classic scripted changes mostly auto-merge | PR opens with the requester's token, so a different person must approve | A risk tier set by the change: low needs no human once checks pass, high needs two |
| Scale claim | Over 1,300 merged PRs a week | 1,500+ merged agent PRs by November 2025 | 74% of merged PRs, as of the October 2026 launch post | About 90% of the repo's own code; merged PRs more than doubled, share reverted down over 40% |
Sources, all self-reported: Stripe part 2; Spotify part 1 and part 3; Ramp and its launch post, with the review agent reported secondhand by a newsletter; Anthropic. The Ramp figure conflicts with earlier ones (about 30% in its own January post, about 60% in a secondhand report), so read it as a direction, not a measurement.
The decision is yours. Your repo has almost no tests, so a CI cap has nothing meaningful to cap, and a teammate suggests copying Spotify's LLM judge as the pass condition. Decide what the blueprint does.
Open case
Four settings, one shape. The paragraphs below are this course's judgment, not Stripe's advice.
Solo developer. Copy the blueprint marking and the two-round cap; they cost a table and a loop counter. Skip the devbox fleet and the tool catalog: one disposable container is enough. First week: fill the template for your own line, run the validator, and make lint an edge.
Small team. Copy the entry point and the rule that a different person reviews. Skip the pre-warmed pool until start-up time hurts. First week: put a chat tag or ticket label in front of one repo, cap CI at two rounds, and record how many runs reach the human exit.
Enterprise. Copy the isolation first, then the scoped rule files and the per-agent tool subsets. Skip any claim about volume until you can state a denominator. First week: pick one repo whose tests run in minutes and measure those minutes, because the cap only works if CI is fast enough to feed it.
Regulated shop. Copy the human review on every PR, which suits an audit, and the run record that shows what each node did. Skip anything that assumes the posts describe change control, because they say nothing about it. First week: write what happens after the human approves, since Stripe leaves that gap open.
Illustrative composite. Your team of nine wants a Slack-tag line next month. Shared staging holds copies of customer data, the test suite takes ninety minutes, and the only agent sandbox is a developer laptop. You have one week. Choose what you copy from Stripe's shape and what you leave out, then write both in
factory/adopt/stripe.md.
Where this breaks
Most of what this page says rests on three first-party sources and one spoken figure. Stripe gives a count of PRs a week and no denominator, no merge rate, no revert rate, no cost and no incident data, so the line's quality is unmeasured in public. The talk quotes about 65% merging unchanged (Stripe talk, spoken, observed 2026-10-28), but the blog posts do not repeat it, and no window or definition is given. We read an auto-generated transcript, not the video.
Some figures differ across Stripe's own sources. The talk mentions a larger test battery and a larger tool catalog than the posts do, about five million tests and about 700 tools (Stripe talk, spoken, observed 2026-10-28), which could mean growth or different counting. We do not know which.
The design assumes things Stripe has built over years: a test battery fast enough to feed an agent, a devbox people already use, and a very large Ruby codebase with typing and lint rules. A team without them gets the shape and not the result. The model's judgment still matters inside the agent nodes; the blueprint bounds its mistakes, it does not remove them.
What would change this verdict: a published revert rate for minion PRs against a human baseline, a cost per merged PR, or any account of what happens after merge.
Key Takeaways
- Mark every step of your line deterministic, agent or human before you build anything.
- Move lint, push and CI status into code; a prompt line is a request.
- Cap CI at two rounds and name the human who takes the branch.
- Treat a PR count with no denominator as activity, not quality.
- Ask what the company has not published before you copy what it has.
- The agent writes the diff; the line decides what happens to it.
What You Have Now
factory/adopt/stripe.md - your line's blueprint with deterministic and agent nodes marked, copied from the Stripe shape. It has a header table, ten rows pairing Stripe's published nodes with yours, a "Not copied" table, and a validator script that fails on empty cells, a missing cap on an agent node, or a missing human row. Put it beside factory/blueprint.md from Lesson 08: that file holds the full node list with exits, and this one records where your line matches or departs from Stripe's. It serves the Prove stage as input to your charter.
Further Reading
- Stripe, "Minions" part 1 - the thread-to-PR flow, the devbox and the blueprint in the builders' words.
- Stripe, "Minions" part 2 - the two-round CI cap, shift-left lint and the tool catalog.
- Stripe talk on building autonomous coding agents - the spoken figures and the argument for gates in code.
- Spotify, feedback loops for background coding agents - a different gate design: verifiers, a stop hook and a judge.
- Ramp, "Why we built our background agent" - the PR-opened-as-requester rule beside Stripe's reviewer rule.
- Anthropic, solving code review - risk-tier approval, the other end of the human-reviews-everything spectrum.
Exercises
- Mark your line. List every step from trigger to review on a line you run or plan. Label each deterministic, agent or human, and write down who decides done.
- Fill and break the file. Copy the template, fill it for your line, run the validator until it prints nothing, then empty one cell and change one cap to
noneto see both failures. - Write the gap list. For a factory you operate, list five things you would have to publish to prove it works, and next to each the number you would need as a denominator.
Check your understanding
Reading is free — your progress isn't being saved
Nothing you did on this page is recorded. Paid students get saved progress and verified completions, recorded quiz answers, the spaced-repetition review queue, labs, and a certificate for each course they finish.
30-day money-back guarantee. One-time payment — lifetime access and updates.