Lesson 23 of 36
Ramp: The Requester's Token Opens the PR
On this page
Ask how much of Ramp's merged code comes from its background coding agent, Inspect, and you get four answers. Ramp's own January engineering post says about 30% of merged pull requests (self-reported by Ramp, observed 2026-10-28). A newsletter that interviewed Ramp leaders puts January at about 60% (secondhand, Pragmatic Engineer, observed 2026-10-28). A speaker in a video interview on a vendor's channel says about 40%, while the video's own title says over half (vendor-hosted, observed 2026-10-28). Ramp's October launch post says 74% (self-reported by Ramp, observed 2026-10-28). Different definitions, different windows or plain error could explain the spread, and no source says which. Copy the headline and you copy a number nobody can audit. One fact in the same system is not a percentage at all: the pull request opens under the name of the person who asked for it, so that person cannot approve it. Decide now: when the percentages disagree this much, which part of Ramp's design would you still trust enough to copy, and why?
This lesson gives you factory/adopt/ramp.md - an identity and approval rule so nobody approves their own agent's change. It serves the Prove stage of the course loop (Slice, Gate, Run, Wrap, Prove): a case study is evidence for your charter, so you read it for the mechanisms it publishes and the numbers it does not.
What is actually going on
Ramp built Inspect, a background agent that takes a request, works in its own sandbox and hands back a pull request. The route has six steps, drawn from Ramp's build post and its follow-ups (Ramp, observed 2026-10-28).
A person starts a session from Slack (for example by mentioning the bot with a screenshot), GitHub, Linear, a web page, a Chrome extension that sends the page's DOM tree instead of an image, or a voice and mobile client. Sessions are multiplayer, so a colleague can join and steer. For Slack requests, a fast model picks the repo and is allowed to answer "unknown", in which case the bot asks the person.
Each session gets a Modal virtual machine built from a per-repo image rebuilt every 30 minutes, so the code is at most half an hour stale (Ramp, observed 2026-10-28). The sandbox warms while the person is still typing. Edits are blocked, reads are not, until the git sync finishes. The services the real app needs run inside. The agent, built on the OpenCode harness, uses the tools an engineer would: tests, error and metrics dashboards, feature flags, the CI system. For front-end work it checks its output visually and attaches screenshots or a live preview to the pull request.
Then comes the step this lesson is about. The sandbox pushes a branch, and Ramp's API opens the pull request with the requesting user's GitHub token instead of a bot identity. GitHub bars a pull request's author from approving it, so the person who asked cannot be the person who clears it. Webhooks track the PR afterward. A human review follows. The launch post calls the output a fully reviewed PR, and a secondhand report names a Ramp review agent too, but no first-party page found for this lesson confirms that agent as a gate. The stats page counts sessions that end in a merged PR as its key metric.
Downstream, error automations draft PRs from Sentry and Datadog alerts, and an on-call assistant investigates incidents and asks Inspect for a fix PR that a human reviews (Ramp, observed 2026-10-28).
The diagram traces one request from trigger to merge, with the identity switch marked on the edge where the PR opens.
Read the loop at the right edge: incident work returns to the same front door, and so returns to the same identity rule.
The rule and its condition
Open agent PRs with the requester's token when each run starts from one identifiable person and your platform bars a PR's author from approving it. Otherwise give the agent its own identity and an extra approval rule that excludes the requester, as GitHub's Copilot cloud agent does (GitHub docs, observed 2026-10-28).
The table uses the seven fixed dimensions of this module. Every cell is Ramp's own statement unless it says secondhand.
| Dimension | What Ramp publishes | Source and label |
|---|---|---|
| Trigger | Slack, GitHub, Linear, web, Chrome extension, voice and mobile; alert-driven automations from Sentry and Datadog | Ramp build post, self-reported |
| Where the agent works | One Modal VM per session from a per-repo image rebuilt every 30 minutes; edits blocked until git sync ends | Same post, self-reported |
| Gates before merge | Normal human review; UI work carries screenshots or a live preview; a review agent appears only in a secondhand report | Pragmatic Engineer, secondhand |
| Who approves the merge | A human other than the requester, because the requester's token opened the PR; mandatory review is implied, never stated | Build post, self-reported |
| After merge (staging, rollback) | Not described. Alerts feed error automations and an on-call assistant that asks for fix PRs | Ramp on-call post, self-reported |
| Scale claim | 74% of merged PRs from Inspect in October 2026; the on-call assistant helped with 575 of 1,220 incident-fix PRs in four weeks, partly estimated from Slack activity; 1M+ sessions by July | Launch post, self-reported; sessions figure secondhand |
| What the company has not published | Cost per session or PR; merge rate with a denominator; revert rate; whether review is mandatory on every Inspect PR; whose token a multiplayer or child session uses; staging and rollback | None of the sources read |
What it does well: the identity rule costs one API decision and needs no new approval policy. The key metric is sessions that end in a merged PR, which sits closer to an outcome than sessions started. Visual proof rides with front-end PRs.
What it costs: the history shows the requester as author of work an agent wrote, so you lose the writer unless you record it separately (Lesson 12). The rule assumes exactly one requester. And the pages are silent on checks, caps, cost and reverts.
Worked case
Ramp's pages are short on gate detail and long on mechanics, so read them as a parts list. Start with a decision.
Illustrative composite. A twelve-engineer payments team adds a Slack bot that opens PRs from a shared service account called
fixbot. The repo wants one approval from anyone with write access. The PRs are small fixes, and engineers have started asking for a fix and then approving it themselves while the others are in meetings.
Decide now: which identity should open the bot's PRs? A: the shared fixbot account. B: the requester's own token. C: fixbot, plus a rule that excludes the requester from approving.
A fails first. The platform sees fixbot as the author, so the person who asked is an eligible approver, and one human holds both ends of the change. That is the single key Lesson 04 warns about. B and C both close the gap, in different ways. Pick B when each run has one requester and the platform bars author approval, which is Ramp's situation. Pick C when runs have no requester, or when you want the history to show that a bot wrote the change. The team keeps B for Slack requests and uses C for alert-driven runs. The cost of the rejected A is the first bad fix that its own requester waved through.
Now the parts list, each tied to a lesson here:
- Open the PR as the requester: Lesson 12 (every commit traces to a named human) and Lesson 04 (the author never holds the merge key). Ramp states the rule; you add a record of who wrote it.
- Count sessions that end in a merged PR, not sessions started: Lesson 14, outcomes over usage.
- Block edits until git sync finishes: a deterministic gate inside the sandbox, Lesson 08.
- Let the router answer unknown and ask: a fact the line cannot read must be asked for, Lesson 13.
- Route incident fixes to a person: the on-call assistant asks for a fix PR and a human reviews it. Ramp does not publish lanes, so this is where your risk lanes (Lesson 07) decide how much reading a production fix gets.
- Fan out with child sessions: Inspect can spawn sessions for many small PRs, but the sources do not say whose token the children use. Your rule must say (Lesson 12).
Ramp's design has a second hint worth a line: the sandbox pushes a branch while a separate API opens the PR. That split is consistent with keeping the token out of the agent's reach, the rule of Agent Fleets, lesson 07 (the agent never holds the key), but Ramp's pages never state it outright. Check it in your own build.
The file below is the deliverable. Copy it to factory/adopt/ramp.md, fill every cell that starts with TODO, then run the validator under it. The block ships unfilled on purpose, so the validator fails until you have done the work.
factory/adopt/ramp.md - identity and approval rule
| Field | Value |
|---|---|
| Repo | TODO name the repo this rule covers |
| Rule owner (a named human) | TODO |
| Platform setting that bars an author from approving their own PR | TODO e.g. branch rule that dismisses self-approval |
| Last reviewed | TODO yyyy-mm-dd |
Entry paths
| Entry path | Requester of record | Identity that opens the PR | Barred from approving | Who may approve |
|---|---|---|---|---|
| Chat request by one person | TODO | TODO | TODO | TODO |
| Alert or scheduled run | TODO | TODO | TODO | TODO |
| Person joins a running session | TODO | TODO | TODO | TODO |
| Child session spawned by an agent | TODO | TODO | TODO | TODO |
Record on every agent PR
| Name | Who it is | Where it is recorded |
|---|---|---|
| Writer (agent and model) | TODO | TODO |
| Requester | TODO | TODO |
| Sponsor (human who owns the entry path) | TODO | TODO |
| Approver | TODO | TODO |
Token custody
| Question | Answer |
|---|---|
| Where does the token that opens the PR live? | TODO |
| Can the sandbox read it? | TODO |
| How long does it last and who revokes it? | TODO |
Rule: TODO write one sentence: who opens the PR, and who may not approve it.
Red control
| Check | Result |
|---|---|
| A requester tried to approve their own agent's PR and was refused | TODO paste the PR link or a note of the refusal |
awk -F'|' '/^\|[-:| ]+\|$/ { next }/^\|/ { for (i = 2; i < NF; i++) { c = $i; gsub(/^ +| +$/, "", c); if (c == "" || c ~ /^TODO/) { printf "line %d: empty or TODO cell\n", NR; bad = 1; break } } }/^Rule:/ { rule = 1; if ($0 ~ /TODO/) { printf "line %d: rule not written\n", NR; bad = 1 } }END { if (!rule) { print "no Rule: line"; bad = 1 } exit bad }' factory/adopt/ramp.mdThe validator prints each offending line and exits non-zero. A clean run prints nothing and exits zero. For the composite team, the chat-request row would read: requester of record is the Slack user, the PR opens with that user's token, that user is barred, and any other engineer with write access may approve.
Faded case
Skip to the open case if this is familiar. This is the compare step: here is how Ramp's identity choice sits beside three other published flows, limited to the dimensions that differ.
| Dimension | Ramp Inspect | Stripe Minions | GitHub Copilot cloud agent | Shopify River |
|---|---|---|---|---|
| Trigger | Many surfaces plus alert automations | Slack thread, CLI, web, ticket and flaky-test buttons | A user with write access | A mention in a public Slack channel |
| Where it runs | Modal VM, image rebuilt every 30 minutes | Pre-warmed devbox, no internet egress, no production data | Pushes only to one agent branch, behind a network firewall | Disposable sandbox, separate from the harness |
| Identity on the PR | The requester's token | The launching engineer opens it | The agent's own app identity | Not described |
| Who approves | A human other than the requester (implied) | Another engineer; humans review every PR | Never the requester; extra approval by default for the app identity | Human review plus CI and merge queue; approvers not specified |
| Scale claim | 74% of merged PRs, self-reported | Over 1,300 merged PRs a week, self-reported, no denominator | None published | About 1 in 8 merged PRs, self-reported |
Sources: Ramp launch post; Stripe, part 1 and part 2; GitHub docs; Shopify. All observed 2026-10-28.
Stripe lands on the same property as Ramp by a similar route: the engineer who launched the run opens the PR and asks someone else to review it. GitHub reaches it by the opposite route, a separate identity with an explicit extra rule. Shopify's posts do not spell out the approval rule, so there is nothing to compare.
Your decision. Your agent also runs overnight from alerts, with no person asking, and Ramp's sources do not say whose token opens those PRs. Which design do you choose for that path, and who approves?
Open case
This is the adopt step. The four paragraphs below are this course's judgment, not Ramp's advice.
Solo developer. Copy the metric, sessions that end in a merged PR. Skip the identity rule: with one human, no second approver exists, so the token changes nothing. First week: log every agent session and whether it merged, and put a required CI check in a path the agent cannot edit.
Small team. Copy the requester's-token rule for chat-triggered runs. Skip multiplayer sessions and child fan-out until the template answers them. First week: fill the template's chat row, enable the branch rule that bars author approval, and run the red control.
Enterprise. Copy all four entry-path rows, the four-name record and the token-custody table. Skip the assumption of one requester per run. First week: inventory every way an agent can open a PR, give each a named sponsor, and map each to an identity.
Regulated shop. Copy the template and its red control, and keep the evidence. Skip relying on the requester's token alone: it hides the writer. Prefer a separate identity with an extra approval rule, with the requester named in a commit trailer. First week: ask your auditor which four names they need, and record exactly those.
The scenario. Your team's Slack bot opens PRs from a shared service account, and the branch rule asks for one approval from anyone with write access. Alert automations use the same account. Engineers often join each other's bot threads mid-run. Before Monday, write which identity opens each kind of PR and who is barred from approving it. The quiz grades your answer.
Where this breaks
Start with what Ramp has not shown. Four figures for the share of Inspect-written PRs conflict, and no source says which is right. Ramp's build post gives no failure or revert data. Cost appears only as "effectively free to run", with no number. Whether human review is mandatory for every Inspect PR is implied by the identity rule and never stated. The review agent that a newsletter names is not confirmed by a Ramp page. The launch post is early-access product marketing, and its 74% has no stated denominator (self-reported by Ramp, observed 2026-10-28).
Next, what the sources hedge. A speaker in the vendor-hosted talk says agents do roughly half of the work, with review and verification still heavy (vendor-hosted, observed 2026-10-28). The newsletter reports that engineers start complex tasks in Inspect and finish them locally. Ramp's security post describes nearly 100 backend vulnerabilities fixed by agents, with humans only at PR review (self-reported by Ramp, observed 2026-10-28): "no humans" means none before the PR.
Last, the rule's own limits. A token stops one person approving their own PR. It does not stop two colleagues rubber-stamping each other's agents, a shared account, or a reviewer who never read the diff. It makes an agent's change look human-written. It says nothing about multiplayer or child sessions.
A published revert rate with a denominator, or a statement that review is mandatory, would raise the verdict. A shared-token incident would lower it.
Key Takeaways
- Open the PR in the name of the person who must not approve it.
- Choose the identity per entry path, because alert runs and shared sessions have no single requester.
- Treat conflicting percentages as unmeasured; copy the mechanism and drop the headline figure.
- Record writer, requester, sponsor and approver separately, because the requester's token hides which change an agent wrote.
- Count sessions that end in a merged PR, not sessions started.
- Prove the rule with a red control: a requester tries to approve their own agent's PR and is refused.
What You Have Now
factory/adopt/ramp.md - an identity and approval rule so nobody approves their own agent's change. Keep it beside factory/identity-ledger.md from Lesson 12 and factory/risk-lanes.md from Lesson 07. The ledger names each agent identity, the lane file says which diffs a human must read, and this file adds the per-entry-path rule, the token-custody answers and the red control. It serves the Prove stage: you have read one company for the mechanisms it publishes, and you hold a written list of what it does not, which becomes your own list of things to measure.
Further Reading
- Ramp, "Why we built our background agent" - the primary build post, including the sandbox, the token rule and the January share figure.
- Ramp, "How we built OCA, our AI on-call assistant" - how incident work hands a fix request back to Inspect for human review.
- Ramp, "100 vulnerabilities patched with 0 humans" - the security agents, and where the human actually sits.
- GitHub Docs, risks and mitigations for the Copilot cloud agent - the opposite route to the same property: its own identity plus an extra approval rule.
- Stripe, "Minions" part 1 - the engineer who launches opens the PR and asks another engineer to review.
- Shopify Engineering, "Under the River" - a public-thread agent, useful as a contrast on visibility.
Exercises
- Fill the template for one chat-triggered agent in your repo. Run the validator until it exits zero. Where a cell is unknown, write the question as the cell's text rather than a guess.
- Run the red control. On a scratch branch, have the requester try to approve their own agent's PR. Paste the refusal, or change the branch rule until you get one.
- Audit one published AI-share claim. Pick a company statement of the form "X% of our code comes from agents", list every figure you can find for it with source, date and provenance label, and write which one belongs in your charter and why.
Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in
Check your understanding
Not savedReading every lesson is free; you only pay to save progress and do the labs.See plansSign in