On November 2, 2026, Microsoft published the build story of Copilot Cowork, its agent that carries out multi-step work for Microsoft 365 users. The post on Microsoft’s Command Line blog, by partner software engineer Bas Brekelmans, opens on one number: “On October 21, nine engineers merged 1,211 pull requests into the main branch of the Copilot Cowork backend.”
The team went from an empty repo on January 13 to worldwide general availability on June 16, then moved the live runtime from Python to Rust between September 23 and October 10. “Agents wrote most of the code, but engineers remained responsible for defining the work and judging the results.”
On this page · 6 sectionsOpen
On October 21, 2026, nine Microsoft engineers merged 1,211 pull requests into the Copilot Cowork backend; agents wrote most of the code.
The rule from week one: no code without a markdown spec that says what the change does, how to know it works and what it must not break.
The model runs in a container with no user credentials; a trusted host handles identity, policy and approvals for every Microsoft 365 operation.
Every check must report what it checked and fail on purpose in a test, after a size check stayed green because its output was piped through tail.
Moving the live runtime to Rust cut first-turn time to first token from 7.9 to 2.7 seconds at the median; Microsoft makes no cost claim yet.
§ 01How nine engineers ran dozens of agents
“In Copilot Cowork, the model runs in a container without user credentials.” A trusted host outside that container handles identity, policy, approvals, tools and audit, and every Microsoft 365 operation goes through it. The team did not want a crippled agent: “the model can plan and ask for anything, and the host decides what actually happens.” That split is what let them run many agents in parallel, each on one task in its own copy of the repo, and later replace the whole host with Rust without touching the agent.
| Date | Milestone |
|---|---|
| January 13 | First commit to an empty repo |
| January | 257 pull requests merged in the month |
| March 30 | Launch to first enterprise customers in the Frontier program |
| May | 2,754 pull requests merged in the month |
| June 16 | Worldwide general availability, about four and a half months in |
| September 23 to 24 | First Rust attempt rolled back; Rust serves its first production turns |
| October 9 | Python runtime deleted: about 8,000 files and 4.9 million lines |
| October 10 | Last cluster moved to Rust |
| Week of October 12 | 4,581 pull requests merged, about 650 a day |
| October 21 | 1,211 pull requests merged in one day by nine engineers |
§ 02The six lessons
The post boils the year down to six practices, each with a number attached.
| Lesson | What the team did | Number reported |
|---|---|---|
| Write the spec before the code | A markdown spec first: what it does, how we’ll know it works, what it must not break | Many specs start spoken, then an agent drafts |
| Run narrow agents inside boundaries | One agent, one task, one spec; the host holds the credentials | Merged pull requests 257 a month to 2,754 |
| Make checks prove they checked | Competing review bots; every check reports what it checked and has a test that makes it fail | First review in about 4.5 minutes (median) |
| Put what the team learns in the repo | Instruction and rule files every agent reads at start | About 30 rule files, oldest from August 6 |
| Shape the codebase for parallel work | Four crate kinds; implementations never depend on each other | Cross-implementation dependencies 216 to 0 |
| Give automated loops targets and limits | One measurable target, a measure that cannot get worse, an attempt cap | Test files 17,700 s to about 1,700 s of CI time |
The rule the team still follows from week one is blunt: “no code without a markdown spec written first.” The faster agents got at writing code, the post says, the more the bottleneck moved to knowing exactly what was wanted.
The most transferable lesson is about checks that cannot fail. A size limit on the agents’ instruction files was broken while its check stayed green, because the script piped its output through tail, and “A shell pipeline returns the exit code of its last command”. The team found the same flaw elsewhere: a formatter handed an empty file list, a changed-files list that went empty after commit. The fix is two rules: every check reports how many files it checked, and every new check ships with a test that makes it fail on purpose. Why it matters more with agents: “Agents keep working until the checks pass, so if a check can pass without testing anything, an agent will eventually find that path.”
Speed did not replace people on the riskiest code. Once, a group of reviewer agents told to break a change in a sensitive part of the product found nothing; engineers then read the same diff and found four blocking issues, fixed before merge. Critical changes now get at least one human check.
§ 03The Python to Rust move
Python got Copilot Cowork to general availability, the post says, but at scale it caused three measured problems: event-loop stalls of up to 11.9 seconds, 16.7% of session setups taking exactly 5.000 seconds because a timeout was firing, and Python processes killed for memory 539 times in one week on a single cluster.
To prove each port was correct, the team recorded what the Python actually did. Small generators ran the real Python over sets of inputs and saved the results as about 430 JSON fixtures; the Rust tests replay them and must match exactly. Traffic moved one cluster at a time behind flags that could switch back.
Microsoft is careful with the result. The same change also moved the agent loop out of a slow-starting container into the Rust service, which the author thinks accounts for much of the gain, and the team has not measured cost per turn, so it makes no cost claim. Two things broke on the way: event ordering that Python had delivered without anyone specifying it, and a Rust front door that first took about six times longer to acknowledge a new message. Both were fixed.
§ 04Our read
This is the third large Rust rewrite story in a week, after Anthropic’s Messages API port and GitHub’s Copilot runtime rewrite. The common thread is not the language. Each team recorded the old system’s behavior and made agents match it, which turns a risky rewrite into a long list of checkable tasks.
Our conflict, declared: we build CellCog, whose AI employees do multi-step work for businesses, so Copilot Cowork is a product in our space. Read our take with that in mind. Two things in the post match how we work. The agent asks and an approval layer decides; on CellCog, consequential actions wait for the owner’s approval. And the tail bug is one we hit in our own publishing checks in October; the fix was the same: a check keeps its own exit code, and every gate has a control that must fail. Microsoft’s broader conclusion is the one worth keeping: human time moves to what to build, where the boundaries go, and whether a passing check means what it seems to.
§ 05What we are watching
- Cost per turn. Microsoft says it has not measured it properly yet; that number decides whether the Rust move paid off.
- The factory. Microsoft’s harness that turns production signals into fixes on its own; the post says a growing share of merges comes from it.
- Others publishing. Whether more teams share pull-request and review numbers at this level of detail.
§ 06Sources
- Microsoft Command Line: Nine engineers, 1,211 pull requests in a day: Lessons from building Copilot Cowork, Bas Brekelmans, November 2, 2026, read directly.
- Microsoft: Copilot Cowork and the Frontier program.
Q1How many pull requests did the Copilot Cowork team merge?
1,211 on October 21, 2026 by nine engineers, and 4,581 in the week of October 12, about 650 a day.
Q2How long did Copilot Cowork take to build?
About four and a half months from the first commit on January 13 to worldwide general availability on June 16, 2026.
Q3Why did Microsoft move Copilot Cowork from Python to Rust?
Event-loop stalls of up to 11.9 seconds, a hidden 5-second timeout on 16.7% of session setups, and frequent memory kills of the Python process.
Q4How did they check the Rust port?
About 430 fixtures recorded by running the real Python; the Rust tests replay them and must match exactly.
Q5Did the Rust move lower costs?
Microsoft says it has not measured cost per turn properly yet and makes no claim about cost.
