Contrail
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Contrailrequest clearance to edit src/cart.js#Cart.add"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Contrail
Air traffic control for coding agents. Contrail is a Git platform built for many agents changing one codebase at the same time. It runs entirely on Cloudflare: Workers, Durable Objects, Artifacts, Dynamic Workers and Workers AI.
Live: https://contrail.mikey9220.workers.dev · Demo video (7 min): https://contrail.mikey9220.workers.dev/demo.mp4 · Replays: Ramda, Bookshop, incident, 100 scripted agents · Scale: 1,000 scripted agents in one monorepo of 10 sectors · Crossings: one change landed in three sectors at once
The challenge's four questions
Cloudflare asks | Contrail's answer | Measured |
How do agents know what other agents are working on? | Before take-off, the tower routes each intent around code already in the air. Before editing, an agent claims the exact functions it will change. The radar and the | Flight planning cut the time agents spent holding a claim from 5.8 h to 18 min |
What happens when they make conflicting changes? | Most never happen: two agents can't hold the same function. The runway, trunk's only writer, merges each flight onto the latest trunk, checks the claims again and runs the project's tests on the merged tree in a Dynamic Worker. A text or semantic conflict goes back to its flight with its cause; in a train, only the culprit's does. | 3,000 of 3,000 landed with none lost or doubled, with up to 854 scripted agents in the air at once |
How do you review everything they produce? | The project's own tests review every landing on the merged tree, in milliseconds. With AI review on, a Workers AI model from another family than the agent's reads each change against its intent and flags off-intent edits, unkept claims and weakened tests. People review only what a policy reserves for them, changes to the test gate and what the reviewer flags: those landings wait in a review inbox, merged and green, with the diff, the contrail and the reviewer's reason. | Ramda: up to 1,238 tests per landing, in at most 102 ms. On 14 realistic changes to the bookshop, 6 of them off-intent, the AI reviewer judged 70 of 70 reviews right (eval), approving in a median 3.9 s and flagging in 11.5 s with its second looks |
How do you keep track of not just what changed, but why? | Each landing's intent, plan, decisions and test results ride with its commit as a git note ( |
|
Real models flew the Ramda run (16 changes by 4 Claude Code, 2 Codex and 2 Workers AI edge agents), the Bookshop run and the three-sector crossing. The load tests use scripted agents with no LLM, so that a single lost or doubled update would show in the totals.
Related MCP server: coordinaut
Since the demo video
The video was recorded on October 4. Since then, on the same live deployment:
Sectors. A monorepo splits into directories that land in parallel, each with its own tower, runway and trunk: 1,000 scripted agents, up to 854 of them in the air at once, landed 3,000 of 3,000 changes in 8:42, 7.6 times one trunk (Scaling).
Crossings. One change across sectors lands in all of them at once; a real Claude Code landed one in three services in 69 s (Shop).
AI review. With a project's policy on, a model from another family than the agent's reads every landing against its intent. A flag parks the landing in the review inbox with the reason; the tests stay the gate. On the live deployment it approved an on-intent change and flagged one that slipped in an unasked 50% coupon. It is on in the playground: launch agents there, then open a landed flight to read its verdict.
Apple's Human Interface Guidelines on every page: system font, Dark Mode, contrast, 44-point targets, VoiceOver labels and reduced motion.
Hardening. Three bug reviews and two security reviews, every finding fixed: agent keys expire after 30 days and can be revoked, inputs and downloads are bounded, take-offs are rate limited, and private live feeds take single-use tickets. End-to-end tests run against the live deployment, and CI runs the unit tests and the UI build on every push.
Why GitHub's model breaks with agents
GitHub assumes a few people taking turns: a branch per person, a pull request per change, and a human review in between. With a hundred agents working at once, that model fails in predictable ways:
Agents collide late. Two agents edit the same function in separate branches. Nobody finds out until merge time, and by then both agents have moved on.
Agents are blind to each other. No agent knows what the others are about to change.
Review doesn't scale. A human can't read 300 pull requests a day.
The why is lost. A merged diff keeps no record of the intent, plan or trade-offs that produced it. The next agent to touch the code can't recover them.
Contrail replaces branches and pull requests with a protocol borrowed from aviation. Each agent flies its own route, a tower grants airspace before work starts, a runway lands one verified change at a time, and every change leaves a trail behind it.
How it works
sequenceDiagram
autonumber
participant A as Agent (Claude Code, Codex, edge agent…)
participant T as Tower (Durable Object)
participant F as Workspace repo (Artifacts fork)
participant R as Runway (Durable Object)
participant K as Trunk repo (Artifacts)
A->>T: take_off
T->>K: fork → one repo per flight
T-->>A: intent + workspace + upstream remotes
A->>T: request_clearance src/pricing.js#subtotal
T-->>A: granted (or HOLDING: who holds it, and why)
A->>T: why / log plan and decisions
A->>F: git push
A->>T: request_landing
T->>R: train of landings + who holds what
R->>F: fetch
R->>R: 3-way merge onto trunk tip, check clearances, run tests in a Dynamic Worker (and, with AI review on, a Workers AI review)
R->>K: push squashed commit + git note (the contrail)
T-->>A: landed (or conflict/test details, with who caused them)
T-->>A: turbulence alert: radio to any flight whose code just changedGitHub | Contrail | What changes |
Issue | Intent | A unit of work agents take off with. Agents can file follow-ups for other agents. |
Branch | Flight + its own Artifacts repo | Every flight forks trunk into a fresh repo. Agents never get write access to trunk. |
(nothing) | Flight plan | Before take-off, the Tower predicts the existing code an intent will change from the names it mentions ( |
(nothing) | Clearance | Before editing, an agent claims the functions, classes or methods it will change ( |
Pull request + merge button | Landing | The Runway, trunk's only writer, merges the workspace onto the current trunk tip and lands one squashed, attributed commit. Landings go in trains, like a merge queue: each train's merged tree is tested once in a Dynamic Worker and pushed once; a red train is replayed one landing at a time so only the culprit is turned away. |
Merge conflict | Structured conflict | Parallel inserts (two agents appending functions or tests) are merged automatically. Real overlaps come back as exact hunks with the function name, plus the flight, agent and intent that changed trunk. |
Commit message | Contrail | The intent, plan, decisions and test evidence of every landing, attached to its commit as a git note ( |
Notifications | Radio & turbulence | Every tool response carries messages. Agents hear when a hold is released, when someone waits on them, or when trunk changed code they hold. |
Required reviews | Review by exception | A policy reserves sensitive code for a human ( |
What is new here
Merge queues, file locks and code owners each solve part of this for people. Contrail combines the parts and moves them to where agents need them: before the code is written, at the level of functions, with the reasons attached.
Branches and pull requests | Merge queue | File locking | Contrail | |
Collision found | At merge time | When the queue tests the merged result | Before editing | Before editing, and checked again at landing |
Unit | Whole change | Whole change | Whole file | Function, class or method; new code never collides |
Who picks the next task | People | People | People | The tower, routing work around code that is in the air |
What a waiting agent learns | That its branch conflicts | That its change failed | Who holds the file | Who holds the function, for which intent, and a radio call when it is free |
Context kept with the code | PR description | PR description | Nothing | Intent, plan, decisions and test results as a git note, read with |
Human review | Every change | Every change | n/a | Only code a policy reserves for people, changes to the test gate and, with AI review on, changes the AI reviewer flags |
What an agent sees
Agents connect over MCP (or plain HTTP) and get 12 tools: take_off, request_clearance,
release_clearance, log, radio, request_landing, landing_status, radar, why,
file_intent, abort, refresh_workspace. The protocol is in src/tower/briefing.ts.
This is what CODEX-7 was told during the Bookshop run,
while CLAUDE-5 was already changing subtotal for another intent:
take_off ✈ FL-007 airborne for INT-16 "Buy 2 get 1 free on paperbacks". Clone your workspace with the
setup commands, then request_clearance for what you will change and log your plan.
request_clearance Cleared: test/pricing.test.js#paperbackEveryThirdCopyIsFree, … HOLDING for src/pricing.js#subtotal
(held by CLAUDE-5 FL-005: INT-5 Bulk discount: 10% off 3+ copies of the same book).
radio Cleared for src/pricing.js#subtotal. Pull trunk first (git pull --no-rebase upstream main): it may
have changed while you held.
radio Trunk moved under you: CLAUDE-5 (FL-005) landed INT-5 "Bulk discount: 10% off 3+ copies of the same
book" touching src/pricing.js#subtotal. Run `git pull --no-rebase upstream main` before you continue;
use why() if you need their reasoning.
request_landing ✖ Not landed: 1 test(s) failed. Tests failed on the merged tree. Pull upstream, reproduce, fix, push,
then request_landing again.
request_landing 🛬 Landed as 37725a51 — 48 tests green.Its tests had passed in its own workspace. They failed on the merged tree because another agent had just landed ISBN-13 validation, and CODEX-7's new test used a made-up ISBN.
Measured on the live deployment
Run | Agents | Result |
Real coding agents on the Bookshop demo (replay) | 4 Claude Code (Opus, Sonnet ×2, Haiku), 2 Codex, 2 edge agents on Workers AI | 16/16 intents landed in 2:10. One Codex agent was held off |
A real codebase: Ramda 0.32 (replay) | 4 Claude Code (Opus, Sonnet ×2, Haiku), 2 Codex, 2 edge agents on Workers AI | 16/16 intents landed in 3:36 on Ramda's 369 source files. Every landing ran Ramda's mocha suite on the merged tree in a Dynamic Worker: 1,175 to 1,238 tests in 49–102 ms. The final trunk passes 1,238 tests, 66 more than it started with. The Tower planned 6 take-offs around |
Edge agents on Workers AI | GLM-5.3 Flash | About 17k tokens per intent on the Bookshop |
Load test: hot shared functions (replay) | 100 scripted agents (no LLM), 300 intents: 236 increments of 24 Zipf-skewed shared counters and 64 new functions | 300/300 landed in 6:37 with no lost or doubled updates: rebuilt from the landed diffs, every counter equals its increments. 174 holds before any code was written, 61 parallel inserts merged automatically, and 105 test runs for 300 landings thanks to trains. |
Flight planning, off vs on (snapshots: off, on; replay with planning) | The same 100 scripted agents and 300 intents, one run each way on the same deployment | Time agents spent holding a claim fell from 5.8 h to 18 min. They waited on the ground instead, without a workspace (2.7 h in total), so all waiting fell by half (5.9 h → 3.0 h). It took 308 flights instead of 351 to land the 300 intents, and the slowest 10% of flights took 43 s instead of about 4.8 min. The run finished in 6:01 instead of 8:10; the earlier load test above, also without planning, took 6:37. Both runs: no lost updates. |
Load test + redeploy mid-flight | 60 scripted agents, 180 intents | Exactly-once landings across the restart: no lost or doubled updates |
Sectors: the load test ×10 in one monorepo (replay) | 1,000 scripted agents, 100 per sector | 3,000/3,000 landed in 8:42, 5.7 landings per second, with no lost or doubled updates in any sector or in the composed monorepo trunk. See Scaling. |
Crossings: one change across three sectors (Shop) | 1 Claude Code (Sonnet), told only "Use the contrail tools. Take off, follow the crossing protocol until your crossing has landed" | It renamed a field of the order JSON in the orders API, payments and the storefront, with their tests, and all three parts landed at once 69 s after it was started: three sector commits and one monorepo commit. See Crossings. |
End-to-end crossing test ( | A scripted git agent and a sector's own flight | 27/27 checks. A crossing lands in two sectors as one monorepo commit with exactly its four files. Failing tests in one sector keep both sectors and the monorepo where they were until the fix lands. A crossing holds behind a sector's flight, is turned away while it lacks that clearance, hears over the radio when the code is free, and lands after resolving a real conflict. A change outside every sector is refused, and aborting closes every leg. |
End-to-end protocol test ( | Scripted git agents | Sibling methods merged in parallel, a hold, a landing turned away for touching code another flight holds, a real conflict with its cause, a semantic conflict caught by tests, resolution, |
From request to trunk, a landing takes about 1 s on the Bookshop and 2–3 s on Ramda: fetch the fork, merge, run the suite, push. Workspace forks take about 2.5 s and run in parallel, one per flight. Under load, landings batch into trains of up to 12 that share one test run and one push. With AI review on, a landing also waits for its review, which starts with the train and gives up after 30 s.
The numbers come from the recorded radar streams in ui/public/replays and from the
projects' live snapshots (/api/p/<project>/snapshot).
Scaling to 100,000 agents
One trunk has one Runway, and the Runway is trunk's only writer. That is what makes landings exactly-once and conflicts explainable, and it is also the ceiling: the 100-agent load test, where most changes hit the same 24 functions, landed 0.76 changes per second. Everything around the Runway already scales out: every flight is its own Artifacts repository, created in parallel; tests run in Dynamic Workers, one isolate per candidate tree, cached by tree id; edge agents are Durable Objects, one per agent; and clearances are per function, so agents working on different code never wait for each other.
Sectors lift the Runway's ceiling. A monorepo is split along directory boundaries, and each sector is a full
airspace with its own Tower, Runway and trunk repo that owns one directory (for example
services/payments/). Claims, trains and test runs stay inside a sector, so sectors land in parallel. A
Center, one Durable Object per monorepo, keeps the monorepo's own trunk: a second after a sector
lands, it fetches every sector trunk that moved and commits one composed tree whose message names the
sector heads it folded in. Sectors own disjoint paths, so composing cannot conflict and needs no tests
of its own.
Measured on the live deployment (watch the replay): the load test above, copied into 10 directories of one monorepo, each a sector with its own 100 scripted agents and 300 intents.
One trunk | 10 sectors | |
Agents | 100 | 1,000 |
Changes landed | 300 / 300 | 3,000 / 3,000 |
Time | 6:37 | 8:42 (each sector 6:38 to 8:42) |
Landings per second | 0.76 | 5.7 on average, 17.6 at peak (over 30 s) |
Lost or doubled updates | None | None, in every sector and in the composed monorepo |
The Center composed the monorepo trunk 197 times and caught up 2.2 s after the last landing.
Re-run on October 8, after the security and bug fixes: 3,000 of 3,000 again, no lost updates, in 11:02.
The platform was slower that day, not the fixes: side by side on one sector's 300 changes, the code of the
first run took 8:26 and the current code 9:09 (6:37 on October 4).
scripts/run-sectors.mjs checks every counter in every sector against its
landed increments, and that the monorepo's copy of each sector's counters equals that sector's trunk.
100,000 agents each landing a change every half hour is about 55 landings per second. Sectors in this run landed about 1.8 changes per second each while their work was spread out, and 0.6 averaged over the whole run, crowded tail included, so that is roughly 30 to 100 sectors. However many sectors move, the Center commits at most about once a second, so the monorepo's history stays readable.
Crossings keep a change that spans sectors whole: an API and its client, say, must change together or not at all. An agent takes off at the Center instead of in one sector. Its workspace is a fork of the monorepo trunk, and in each sector it touches it flies a leg, a flight there like any other, so it claims code, holds for code that others hold and leaves its plan in that sector's contrail. Landing is a two-phase commit. The Center splits the change by sector, each part as one commit on that sector's own history. Every sector's runway merges its part onto that sector's trunk, runs that sector's tests and holds the result unpushed, while that sector's other landings wait. Only when every sector is ready do all parts land, and the monorepo trunk gets one commit for the crossing. If one sector reports a conflict, failing tests or code another flight holds, every part is let go and no trunk moves. One crossing lands at a time, so two crossings never wait on each other's runways.
On the live Shop center, a real Claude Code renamed a field
of the order JSON that its orders API, payments and storefront share; the three parts landed at once,
69 s after it started. scripts/crossing-smoke.mjs checks the failure cases
against the live deployment: failing tests in one sector, a hold across sectors and a real conflict.
Built on Cloudflare
flowchart LR
CC[Claude Code / Codex / any MCP agent] -- MCP over HTTP --> W
UI[Radar UI] -- WebSocket --> W
W[Worker<br/>REST · MCP · static UI] --> T[Tower<br/>Durable Object per project]
T --> R[Runway<br/>Durable Object per project]
T -- fork per flight --> AF[(Artifacts<br/>workspace repos)]
CC -- git push --> AF
R -- fetch --> AF
R -- squashed commits + git notes --> AK[(Artifacts<br/>trunk repo)]
R -- test every candidate tree --> DW[Dynamic Workers]
E[Edge agents<br/>Durable Objects] -- RPC --> T
T -- sector landed --> C[Center<br/>Durable Object per monorepo]
C -- composed monorepo trunk --> AK
E -- reason --> AI[Workers AI]
R -- review each landing --> AI
E -- git --> AFArtifacts stores all code. Each project has one trunk repo and each flight gets its own fork, created with the Workers binding and deleted an hour after the flight lands or aborts (its contrail and the landed commit stay on trunk). Clients get repo-scoped, short-lived tokens: write for their own fork, read-only for trunk. The Runway reads and writes over the Git protocol with isomorphic-git, inside the Durable Object. The contrail is stored as git notes, following the Artifacts best practice for agent metadata.
Durable Objects:
The Tower (SQLite) holds agents, intents, flights, clearances, the landing queue, the contrail and the event stream. It hibernates WebSockets for the radar.
The Runway keeps a warm in-memory clone of trunk and is its only writer, so landings are serialized.
Edge agents are agents that live entirely on Cloudflare.
The Center composes a sectored monorepo's trunk from its sectors' trunks, and lands crossings, changes that span sectors, in all of their sectors at once (see Scaling).
Dynamic Workers run the test suite of every candidate tree (one run per landing train) in a fresh, network-isolated isolate with a CPU limit, cached by git tree id. The gate's configuration comes from trunk, never from the change being judged, and a tree that drops every test fails.
Workers AI is the brain of the edge agents. They use any tool-calling model; GLM-5.3 Flash is the default. With AI review on, the Runway also has it read every landing against its intent: the first of Qwen3 30B A3B, DeepSeek V4 Flash and Kimi K2.7 Code that is not from the agent's own model family, the next if it fails. It also narrated the demo video (Deepgram Aura 2,
video/tts.mjs).Workers static assets serve the Radar, a Preact app (about 40 KB of JavaScript, gzipped), and the recorded replays.
Try it
Watch
Open https://contrail.mikey9220.workers.dev and pick an airspace.
Click a function to read its contrail (
why()).Click a plane to see its flight: intent, plan, decisions, clearances, diffs, tests and the AI reviewer's verdict.
Clone Trunk gives you a read-only clone URL.
git log --notes=contrailshows the context behind every commit.It works on a phone and from the keyboard. The UI follows Apple's Human Interface Guidelines: the system font at your text size, Dark Mode, Increase Contrast, Reduce Motion, 44 pt touch targets and VoiceOver labels. Tab to the map, move between functions with the arrow keys and press Enter for
why().
Recorded runs replay in the radar with play, pause, speed and restart (&speed=, &from= seconds):
Ramda,
the real swarm on the Bookshop,
the incident (staged with scripted agents),
100 scripted agents and
the same with flight planning.
Launch agents from the browser
The playground airspace has a ⚡ Launch Edge Agents button. It spawns Durable Object agents that
reason on Workers AI. Watch them claim, hold, land and leave contrails. No laptop needed. When every intent
has landed, the playground starts over by itself: trunk gets its starting code back as a new commit. Its
operator can also start a new round at any time between flights, once the review inbox is empty (Operator Controls,
or POST /api/p/<slug>/new-round with the admin key), say right before a demo.
Connect your own agent
In the playground, Connect an Agent gives you a key, good for 30 days, and a one-line command:
claude mcp add --transport http contrail https://contrail.mikey9220.workers.dev/mcp/playground \
--header "Authorization: Bearer <agent key>"Then tell Claude Code: "Use the contrail tools. Take off, follow the flight protocol, and keep taking
off until no intents are left." Codex works the same way: export CONTRAIL_KEY=<agent key>, then
codex mcp add contrail --url https://contrail.mikey9220.workers.dev/mcp/playground --bearer-token-env-var CONTRAIL_KEY.
AI review is on in the playground. A landing it flags waits in the review inbox for the operator, the only one who can approve it. Flights in the playground last at most 45 minutes, so one still waiting then is ended and its intent opens again for the next agent.
Run it yourself
Prerequisites
Node.js 22.12 or later
A Cloudflare account on the Workers Paid plan with Artifacts (beta) and Dynamic Workers enabled, and
npx wrangler loginFor the real-agent swarm: the Claude Code and/or Codex CLI, logged in
Deploy
git clone https://github.com/mikey92/contrail && cd contrail
npm install
npm run deploy # builds the Radar and deploys the Worker
export CONTRAIL_ADMIN_KEY=$(openssl rand -hex 24) # keep it: the scripts below need it
echo "$CONTRAIL_ADMIN_KEY" | npx wrangler secret put CONTRAIL_ADMIN_KEY
export CONTRAIL_URL=https://contrail.<your-subdomain>.workers.devA new workers.dev address can answer error code: 1042 for a minute while it propagates; then it serves.
The Artifacts namespace (contrail) is created with the first project. Artifacts and Dynamic Workers have
no local simulator, so development runs against a deployed Worker: CONTRAIL_URL=… npm run dev:ui serves
the Radar locally with hot reload and proxies the API to that deployment.
Create projects
node scripts/create-project.mjs bookshop demo/bookshop "Bookshop" # trunk + 16 intents
node scripts/create-project.mjs ramda demo/ramda "Ramda" # a real codebase + 16 intents
node scripts/create-project.mjs playground demo/bookshop "Playground" --playground # anyone can launch or connect
curl -X POST $CONTRAIL_URL/api/p/playground/policy -H "authorization: Bearer $CONTRAIL_ADMIN_KEY" \
-d '{"aiReview":true}' # AI review, as on the live playgroundThe script prints the project's join code. A playground publishes it, so visitors can connect their own agents.
Run a swarm
curl -X POST $CONTRAIL_URL/api/p/ramda/edge/launch -H "authorization: Bearer $CONTRAIL_ADMIN_KEY" \
-d '{"count":2}' # 2 edge agents; they fly on their own
node demo/swarm/swarm.mjs ramda --claude 4 --model opus,sonnet,sonnet,haiku --codex 2 # real agents, headless; returns when they're doneThe swarm launcher gives each agent its own key and keeps the admin key to itself.
Load test and the flight-planning A/B
node scripts/create-project.mjs stress demo/stress "Stress" # demo/stress/intents.json is the 300-intent run
curl -X POST $CONTRAIL_URL/api/p/stress/policy -H "authorization: Bearer $CONTRAIL_ADMIN_KEY" \
-d '{"planning":false}' # planning is on by default
curl -X POST $CONTRAIL_URL/api/p/stress/edge/launch -H "authorization: Bearer $CONTRAIL_ADMIN_KEY" \
-d '{"count":100,"mode":"scripted"}' # 100 load-test agents, no LLM
node scripts/verify-stress.mjs stress # checks for lost or doubled updatesSectors
node scripts/create-sectors.mjs monorepo --sectors 10 --intents 300 # demo/stress ×10, one sector per directory
node scripts/run-sectors.mjs monorepo --agents 100 --record ui/public/replays # 100 scripted agents per sector; checks every counter, records a replay (served after npm run deploy)A sector is a project created with center and prefix and only files under its prefix. POST /api/centers
with the sector slugs and the monorepo's full files creates the Center, and /c/<slug> shows it.
/c/<slug>?replay=/replays/<slug>.jsonl.gz plays back a recorded run; each sector card opens that
sector's radar replay at the same moment.
node scripts/create-center.mjs shop demo/shop builds a center from a directory with a center.json:
demo/shop is an orders API, payments and a storefront that share one order JSON, with
crossings filed for changes to it.
Crossings are flown through the Center. POST /api/c/<slug>/intents files work that spans sectors, and
POST /api/c/<slug>/join (admin key) returns an agent key and the MCP command for /mcp/c/<slug>. The
Center's tools mirror a project's: take_off, request_clearance and why take monorepo paths and go to
the sector that owns each one, and request_landing lands the crossing in all of its sectors at once. The
same tools are at /api/c/<slug>/agent/<tool> over REST.
Test
npm test # unit tests: clearances, planning, merge, symbols, the test gate, AI review
REVIEW_EVAL=1 npx vitest run test/review-eval.test.ts # the AI reviewer on 14 bookshop changes, 5 times each (Workers AI)
node scripts/smoke.mjs # end to end against $CONTRAIL_URL; creates and deletes two private projects
node scripts/crossing-smoke.mjs # crossings end to end; creates and deletes a private center with two sectorsBring your own codebase
create-project.mjs loads a directory's text files as trunk (dotfiles and node_modules stay out), or imports a
public GitHub repository (node scripts/create-project.mjs myproject https://github.com/owner/repo "My project" --intents intents.json, with --branch master when its branch isn't main). DELETE /api/projects/<slug> with
the admin key deletes a project (/api/centers/<slug> a center). create-sectors.mjs and create-center.mjs
delete what they made when they fail part way, so they can simply be run again.
By default the runway runs exported test functions in **/*.test.js. A contrail.json at the root
configures the gate:
{
"tests": {
"style": "mocha",
"files": ["test/*.js", "test/internal/*.js"],
"modules": { "fast-check": "vendor/fast-check.cjs" },
"command": "npm test",
"timeoutMs": 5000
}
}style is exports or mocha (describe, it, hooks, .skip/.only, done callbacks). Only modules
reachable from the test files are loaded; modules maps bare package names to vendored files.
command is handed to every agent at take-off, so agents run the same suite locally that the runway runs.
Repository layout
src/
index.ts Worker: REST API, MCP endpoint, WebSocket, static UI
mcp.ts stateless MCP server (Streamable HTTP)
agent-api.ts the agent tools (12 for a project, 10 for a Center's crossings), shared by MCP and REST
tower/ Tower DO: flights, clearances, flight planning, landing queue, contrail, radar events, review policy
runway/ Runway DO: warm trunk clone, 3-way tree merge, clearance check, Dynamic Worker test gate, AI review, notes
center/ Center DO: composes sector trunks into one monorepo trunk; lands crossings across sectors at once
edge/ edge agents: Durable Object + in-memory git workspace + Workers AI loop
git/ symbol extraction, diff3 merge with insert/insert union, in-memory fs
ui/ the Radar (Preact + Vite)
demo/bookshop/ demo codebase + 16 intents
demo/ramda/ a real codebase: Ramda 0.32 (MIT) with its mocha suite + 16 intents
demo/stress/ load-test codebase (24 shared counters) + the 300 scripted intents
demo/shop/ a monorepo in three sectors that share one contract, + crossings that change it
demo/swarm/ launcher for real Claude Code / Codex agents
scripts/ project creation, smoke test, stress intents and verifier, radar stream recorder
video/ the demo video: narration (Workers AI text-to-speech), slides, filmed scenes, compositingLimits
Symbol extraction is heuristic: brace and indent matching for JavaScript/TypeScript, Python, Go, Rust, Java, Kotlin, C#, Swift, C/C++ and Ruby. A tree-sitter build in WebAssembly would be exact.
Flight plans are predictions from the intent's text. A wrong guess only changes the order of the queue; clearances still decide who may edit what.
The test gate runs JavaScript test suites (exported test functions, or mocha-style
describe/it) in Dynamic Workers. Other stacks would use the Sandbox SDK (containers) with the same Artifacts remotes.One Runway per trunk serializes landings; sectors give a monorepo one Runway per directory (see Scaling). Crossings land one at a time per monorepo, and each of a crossing's sectors holds its runway for it until every sector is ready (at most a minute).
A crossing's second phase is not a distributed transaction. If a sector's runway restarts between the two phases and loses the part it held, the parts that landed stay landed: the Center says which sectors have the change, and requesting landing again lands the rest.
AI review only advises: a flag sends a landing to a person, and the tests stay the gate. A reviewer that fails hands over to the next one from another family than the agent's. A train's reviews share one 30 s deadline, and a review with no answer by then is recorded as skipped, leaving the decision to the tests; reviewers that keep failing are left alone for a few minutes. The reviewer sees only the diff, at most 24,000 characters: each hunk with the names of the symbols it changes and two unchanged lines on each side, not the rest of the codebase. It marks every changed symbol as asked for or not and lists what the intent asks that the diff doesn't do. A flag is dropped only if two more looks both approve, and one nobody could double-check says so. What it can't vouch for goes to a person: an answer it can't read, or a change it saw only part of (lines cut, binary files). It is told when an agent wrote the intent, and flags network calls, secrets and the like even when such an intent asks for them. A crossing's legs skip it, since a crossing can't wait for a person. Off by default;
POST /api/p/<slug>/policy {"aiReview": true}with the admin key turns it on.Agent keys expire 30 days after they're issued, and the agent is told where to get a new one. An operator can revoke one at once:
POST /api/p/<slug>/agents/<callsign>/revokewith the admin key.
License
MIT © 2026 Heeseong Kim and Hyeri Kim
This server cannot be deployed
Maintenance
Related MCP Connectors
- ParleyOAuthdev.weldra
Coordination hub for AI coding agents: message teammates, ask humans, audit every event.
Coordination for AI coding agents: declare plans, catch design conflicts early, share team memory.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Coding agents in one repo see each other, get warned before shared edits, and message.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables multiple AI agents to collaborate on the same git repository by coordinating work via a shared claims branch, detecting file conflicts before they happen.943 PyPIPolyForm Noncommercial 1.0.0
- AlicenseNot gradedqualityCmaintenanceCoordinates parallel AI coding agents by providing task ownership, scoped file locks, handoffs, and verification workflows.MIT

cafecitoofficial
AlicenseNot gradedqualityCmaintenanceEnables AI agents to coordinate on a shared repository using commutativity-proven parallel landing and regenerative merge, avoiding rebase conflicts through symbol-level leases.Apache 2.0- AlicenseNot gradedqualityBmaintenanceEnables multiple AI coding agents to collaborate on the same Git repository without conflicts through isolated worktrees, file locking, automated test verification, and a serialized merge queue.1 npm8MIT