Lesson 24 of 36

Shopify: An Agent That Works in Public Threads

ReadFree to read · saving needs Core23 min · Slice → Gate → Run → Wrap → Prove · Updated 2026-10-28
You end this lesson with: factory/adopt/shopify.md — a visibility and proof-of-work rule for your agent threads
view

Shopify's mobile engineers each ran a coding agent on their own laptop, and it stopped scaling fast. Three or four parallel agent workflows were enough to saturate a machine, because compilers, simulators and emulators fought for the same cores, and a closed lid ended the work (Shopify Engineering, self-reported, observed 2026-10-28). The deeper cost was invisible. Whatever one engineer's agent worked out about a flaky test lived in a private terminal and died with the session, so the next engineer started from nothing (Shopify Engineering, self-reported, observed 2026-10-28). When Shopify moved the agent onto a server, a second gap appeared: it ran on Linux, so it could edit Swift and then report that it could not build or run the app. Reviewers received diffs that nobody had seen behave. Now picture your own team. Each engineer talks to an agent in a private chat, and every pull request is a claim with a diff stapled to it. Decide now: when a pull request from your agent lands, what should a reviewer be able to see without asking anyone?

This lesson gives you factory/adopt/shopify.md - a visibility and proof-of-work rule for your agent threads. It serves the Prove stage of the course loop (Slice, Gate, Run, Wrap, Prove): a company page feeds the factory charter you write at the end, by setting one published line beside your own.

What is actually going on

Shopify's agent is River, a coding agent that lives in the company's Slack. You start it by typing @river in a public channel. Direct messages are not allowed, so every conversation becomes a transcript that other employees can open (Shopify Engineering, self-reported, observed 2026-10-28).

Underneath it sits Aquifer, an internal platform that splits an agent into three parts. The session is the durable record, an append-only event log in Postgres. The harness is the agent loop: it reads that history, calls the model and emits requests to use tools, and it is cheap to recreate. The sandbox is where code runs, with the repo, a shell and build tools, and it is disposable too. Because the loop lives outside the sandbox, a dead machine loses neither the conversation nor the record of every decision (Shopify Engineering, self-reported, observed 2026-10-28).

Inside a thread River reads code, runs tests, queries the data warehouse and production traces, and opens a pull request. A second person can drop in mid-run with a constraint, and River folds it in. Shopify mines the transcripts and feeds the patterns back into River's skills, prompts and defaults, so one person's hard-won fix becomes the next person's starting point.

Mobile needed more. River ran on Linux, so it could edit Swift but could not build an iOS app, and it said so. Shopify built Remote Dev: a pool of warm remote Macs with main checked out and apps prebuilt, each claimed per session, with an Android emulator attached from a separate Linux VM. Initial compilation and checkout used to take over 30 minutes, and the wait fell to a few minutes (Shopify Engineering, self-reported, observed 2026-10-28). On the Mac, River drives the simulators, reproduces a bug, records the broken behavior, applies the fix and repeats the same steps to record the result. Those recordings go onto the pull request, so a reviewer watches the change instead of inferring it. A small, fast classifier model grades mobile conversations by outcome, and the failures feed an improvement loop.

Overnight workflows pick up bugs and open pull requests, so the day starts with fixes waiting for review. The merge gate is the thin part: the posts call these pull requests ready for review, and the monorepo has CI and merge queues, but no required approver is named.

The diagram follows one request from mention to merge.

diagram
drawing
One River request runs from a public mention to a reviewable pull request, and the public transcript feeds the next run.

The loop closes through the transcript: the evidence a reviewer sees and the lesson River learns next both come from the same public record.

The rule and its condition

The table gives one row per fixed dimension. Every cell paraphrases Shopify's own engineering posts, so every figure is self-reported.

DimensionWhat Shopify publishesSource and label
TriggerAn @river mention in a public Slack channel; overnight workflows that pick up bugs and crashesUnder the River, Remote Dev; self-reported
Where the agent worksDurable Aquifer session; disposable harness; separate disposable sandbox; for mobile, a warm remote Mac claimed from a poolSame two posts; self-reported
Gates before mergeTests, plus before and after recordings on mobile; monorepo CI and merge queues. Required checks for River pull requests are not spelled outSame two posts; self-reported
Who approves the mergeNot published. Pull requests are described as ready for review, with no approver ruleRemote Dev; self-reported
After mergeNot published for River pull requestsAbsent from all three posts
Scale claimAbout 1 in 8 merged pull requests coauthored by River. One 30-day window: 59,918 sessions, 5,170 channels, 7,000+ people, 3,536 merged River pull requests. Median session 19 minutes, 50 tool calls. Mobile share of merged pull requests 6% to 61% (chart; time axis not in the text)Under the River, Remote Dev; self-reported from Shopify's own session table
What the company has not publishedApproval rules, revert rate, incident counts, cost or token spend per pull request, what "coauthored" counts, the time axis of the mobile chartAbsence checked in all three posts, observed 2026-10-28

What it does well. Public threads turn every run into a teaching artifact, and a second human can redirect a run before it finishes. The recordings give a reviewer evidence of behavior, not a summary. A new agent is a new profile on the same platform, not a new platform. What it costs. Shopify first moved to one monorepo and one reproducible build system, and the monorepo move forced CI to scale by an order of magnitude almost overnight (Shopify Engineering, self-reported, observed 2026-10-28). The warm Mac pool needs constant rotation, and adoption took a marketing campaign. Public threads also mean anything typed into one is readable by everyone, which is this course's concern, not Shopify's stated one.

The rule you take from this case: use public threads with proof attached to the pull request when reviewers were not in the conversation; otherwise, when one person writes and reads everything, a private session with a saved test log is enough.

Worked case

Shopify's posts hold six mechanics, and each ties to a lesson of this course.

The thread is the unit of record (Lessons 12 and 14). No direct messages, and every session written to a table Shopify queries itself. That is how the company can count sessions and co-authored pull requests at all. Lesson 12 says every commit traces to a human; the thread is where "who asked" is already written down.

Proof is attached to the pull request (Lesson 9). An agent that cannot run the app is capped at suggesting code. Shopify's repair was infrastructure: a reproducible build and a warm pool of machines. Lesson 9 scores what the agent can verify before you raise autonomy.

Humans join mid-run (Lesson 13). The second person supplies the fact the repo cannot, such as a constraint or a redirect. The thread is where that context arrives.

Sessions stay small (Lesson 2). The median session is 19 minutes and 50 tool calls (Shopify Engineering, self-reported, observed 2026-10-28). A sibling tool, Helix, breaks a screen migration into checkpoints that must pass tests, a visual comparison against the old app, two adversarial code reviews and an engineer's approval before the next begins (Shopify Engineering, self-reported, observed 2026-10-28). The release is the unit; the checkpoint is the slice.

Transcripts feed the next run (Lessons 11 and 15). A classifier grades conversations and failures drive improvements. Who owns the resulting skill is not stated; Lesson 11 gives the answer.

The approver is a blank (Lesson 4). Nothing published tells you who may approve a River pull request. Fill that cell on your side.

Illustrative composite. Larkspur is a 14-person mobile team with a checkout app. Engineers talk to a coding agent in private chats. Last quarter a reviewer approved an agent pull request for a discount field after reading a six-line diff and a summary that said the flow was tested. It was not: the agent could not launch the app, and one order in five lost its discount before anyone traced the cause. These numbers are modeled, not measured.

Three designs are on the table. Design A keeps private chats and asks the agent for a longer summary in each pull request. Design B moves the agent to a shared channel and links the thread from the pull request, with nothing else required. Design C does what Shopify's posts describe in outline, then writes it down: shared channel, thread link, and a required proof for each change type, in a file the reviewer checks against.

Decide now, before reading on: which design, and what is the first thing that goes wrong with the one you reject most firmly?

Design A fails first. A longer summary is a longer claim, and the reviewer's only tool is to read it and trust it. That is precisely how the discount bug was approved. Design B fails more quietly, because it looks like Shopify. The thread is readable, and nobody reads it; and where they do, the thread proves what the agent said, not what the app did. A public record of the sentence "tested" is still the sentence "tested". Visibility lets people redirect a run and learn from it. It does not replace evidence. Proof is what a reviewer can watch, not what the agent says.

Design C is the build. It keeps B's visibility, adds an evidence requirement per change type, and gives the agent a legal way to say "I could not prove this": the pull request carries an unproven label, and the file states what that label costs. Here is the deliverable in full. The values are Larkspur's; overwrite them with yours.

markdown

factory/adopt/shopify.md

FieldValue
Repo or productlarkspur-checkout
Agent surface#agent-work in the team chat
Who can read threadseveryone in the company
Direct messages with the agentrefused, with a pointer to the channel
Rule owner@priya
Last reviewed2026-11-04

Visibility rule

  1. The agent takes tasks only in a channel its whole organisation can read. Anything sent privately is refused with a link to the channel.
  2. Every pull request the agent opens starts its description with the link to its thread.
  3. A thread stays readable for as long as the code it produced stays in the main branch.
  4. Secrets, customer data and credentials are never pasted into a thread. The agent refuses and says so in the thread.

Proof-of-work table

Change typeProof the agent attachesWhere it livesWhat the reviewer checksIf proof is impossible
User-visible changeBefore and after recording of the same stepsPull request descriptionSame steps in both clips; the visible change matches the diffLabel the pull request unproven and say what was not run
Bug fixFailing test or reproduction output before, passing afterDescription and CI logThe failing run predates the fix commitLabel unproven and attach the diagnosis only
Backend behaviorRequest and response capture from a test environmentDescriptionThe response matches the stated behaviorLabel unproven
Refactor with no visible changeFull test run and diff summaryCI logTest count unchanged or higherLabel unproven
Config or infrastructureDry-run or plan outputDescriptionPlan lists only the intended resourcesDo not open the pull request; ask in the thread

Unproven rule

An unproven pull request needs a second reviewer who reproduces the behavior by hand. The person who started the thread is not that reviewer.

Thread review

Once a month the rule owner reads five threads that ended in a revert, an unproven label or a stuck run, and records which row of the proof table failed.

The validator fails on any empty or placeholder cell and on a proof table with fewer than three rows:

bash
awk -F'|' '/^\|/ && !/^\|[-| ]+\|$/ { for (i=2;i<NF;i++) { c=$i; gsub(/^ +| +$/,"",c); if (c=="" || c ~ /TODO|TBD|<.*>/) { print FILENAME ":" NR ": empty or placeholder cell"; bad=1 } } if (NF==7) rows++ } END { if (rows<4) { print "proof table needs at least 3 rows"; bad=1 } exit bad }' factory/adopt/shopify.md

Run against Larkspur's file it prints nothing and exits zero. The cost of the rejected designs is the quarter that ended with the discount bug.

Faded case

Skip to the open case if this is familiar. Three other published lines put the work in a shared place or attach evidence, and the differences show what Shopify's design leaves out. The facts come from each company's own post, so each is self-reported.

DimensionShopify RiverBlock BuilderbotLinearRamp Inspect
Trigger@river in a public channel@builderbot in Slack, or a Linear or Jira ticketDatadog monitor files an issue; automation assigns the agentSlack, GitHub, Linear, web
Proof attachedBefore and after recordings on mobileWatches CI and iterates; no evidence format namedAgent must show it understands the problem firstScreenshots or live preview on frontend work
Who approvesNot publishedNot namedAn agent reviews every pull request, then a human gives final approvalPull request opened with the requester's token, so they cannot approve it
Scale claimAbout 1 in 8 merged pull requestsAbout 15% of production changesNone published74% of merged pull requests

Sources: Shopify, Block (newsroom post, method not given), Linear (anecdotal, no volume), Ramp (its own earlier figures conflict, see Lesson 20). All observed 2026-10-28.

Shopify's visibility and proof sit above the others. Only Ramp publishes an identity rule that blocks self-approval, and only Linear says an agent reads every pull request first. Your decision: you adopt Shopify's thread and proof pattern. Which one rule from the other columns do you add to your file, and which line of it?

Open case

These four paragraphs are this course's judgment, not Shopify's advice.

Solo developer. Copy the proof table and a saved recording or test log per pull request; skip public channels, since nobody else reads them. First week: add the table to your repo and attach proof to your next five agent changes.

Small team. Copy the shared channel and the thread link in every pull request. Skip the monthly thread review for now. First week: move agent use out of private chats and run the validator.

Enterprise. Copy visibility, but add the retention and access rules Shopify does not describe. Skip org-wide thread reading by default. First week: pick one team, one channel, one proof row.

Regulated shop. Copy the proof table as audit evidence. Skip open channels until legal approves what may be typed. First week: have compliance write the secrets rule.

Your scenario, bare. Forty engineers use an agent in private chats and terminals. Last month a pull request changed a checkout flow with a diff and a one-line summary, and it broke the discount field after merge. You may change two things this week. Which two, and what do you refuse to copy?

Where this breaks

Four limits stop you from reading this page as a recipe.

First, the figures are Shopify's own, taken from its own session table, and several things are missing. The merge approval rule, the revert rate, incident counts and cost per pull request appear in none of the three posts I read (Shopify Engineering, self-reported, observed 2026-10-28). The mobile share of 6% to 61% comes from a chart whose time axis is not in the text (Shopify Engineering, self-reported, observed 2026-10-28). One in eight counts pull requests River coauthored, which is a share of AI-touched code, not a measure of quality. Lesson 14 explains why you pair it with revert and incident rates before you act on it.

Second, public threads depend on a substrate. Shopify made a monorepo and a reproducible build system bets in 2024, and the posts say those moves hurt before they paid. If your repo cannot boot an agent environment in minutes, the proof column is where you will fall short first.

Third, adoption was psychological as much as technical: early mobile River sessions failed, engineers returned to local work, and Shopify ran an internal campaign to win them back. Public by default also puts secrets and customer data at risk, which the posts do not address.

What would change the verdict: a published revert rate for River pull requests next to the human baseline, and a stated approver rule.

Key Takeaways

  • Open every agent thread to the organization, and refuse private conversations with the agent.
  • Attach a recording, test run or captured output to each pull request the agent opens.
  • Link the thread in the first line of the pull request, so reviewers can reconstruct the run.
  • Read Shopify's one-in-eight as a share of AI-touched code, never as an outcome.
  • Proof is what a reviewer can watch, not what the agent says.
  • Write down who approves, because Shopify's posts do not and your factory must.

What You Have Now

factory/adopt/shopify.md - a visibility and proof-of-work rule for your agent threads. It holds a header table, four visibility lines, a proof table per change type with an unproven path, and a validator that fails on any empty cell. Keep it next to the identity ledger from Lesson 12, and put the file itself under the protected paths from Lesson 6, because the agent should not be able to loosen its own proof requirement. This is the Prove stage of the course loop for one published line: you now know what Shopify shows, what it leaves blank, and which of those blanks you have filled for your own repo.

Further Reading

Exercises

  1. Copy the build block into your repo as factory/adopt/shopify.md, replace every value, and run the validator. Then blank one cell on purpose and confirm the command fails.
  2. Open your last five agent pull requests. For each, record whether you can find the thread and whether any evidence besides a diff exists. Report the count as found over five.
  3. Define "agent-coauthored" for your repo, then pull your own history for the share of merged pull requests and the revert rate of that share against the rest. Write down the denominator before you read the numbers.

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