[{"data":1,"prerenderedAt":1639},["ShallowReactive",2],{"writing-\u002Fwriting\u002Fruntime-subagents-orchestration":3},{"id":4,"title":5,"body":6,"date":1631,"description":1632,"extension":1633,"meta":1634,"navigation":195,"path":1635,"seo":1636,"stem":1637,"__hash__":1638},"writing\u002Fwriting\u002F20260510.runtime-subagents-orchestration.md","Runtime Subagents: Orchestration as Code",{"type":7,"value":8,"toc":1621},"minimark",[9,35,38,44,47,63,68,71,87,103,341,344,348,363,368,379,454,467,473,494,500,504,523,528,534,538,544,551,572,578,581,589,603,1449,1453,1459,1503,1511,1517,1523,1526,1536,1540,1571,1605,1611,1617],[10,11,12],"content-alert",{},[13,14,15,19,20,29,30,34],"p",{},[16,17,18],"strong",{},"June 2, 2026:"," Anthropic recently shipped ",[21,22,28],"a",{"href":23,"rel":24,"target":27},"https:\u002F\u002Fcode.claude.com\u002Fdocs\u002Fen\u002Fworkflows",[25,26],"noopener","noreferrer","_blank","Dynamic Workflows"," in Claude Code, built on the same core idea as this post. I added a ",[21,31,33],{"href":32},"#the-pattern-converged","section on the parallels",".",[13,36,37],{},"I often ask coding agents to do work that sounds like this:",[39,40,41],"blockquote",{},[13,42,43],{},"Check each of these five areas in parallel. Follow up on anything that looks risky. Compare the results, and make a recommendation.",[13,45,46],{},"There is a fan-out. There is a join. There is a conditional second pass. There is aggregation at the end. If I describe that in prose, the model has to hold the whole orchestration plan in its head while it is also reading code, choosing tools, tracking partial results, deciding what to launch next, and remembering how the branches relate to each other.",[13,48,49,50,54,55,58,59,62],{},"The point of runtime subagents is to make that orchestration explicit: give the model ",[51,52,53],"code",{},"run()",", ",[51,56,57],{},"join()",", and ",[51,60,61],{},"cancel()",", and let it write the workflow as JavaScript.",[64,65,67],"h2",{"id":66},"prose-is-the-wrong-runtime","Prose Is The Wrong Runtime",[13,69,70],{},"Ask a model to narrate a ten-branch, two-wave, race-and-cancel workflow and it will try. But prose is just a bad medium for concurrent control flow. Code has already solved this, and the model knows code.",[13,72,73,74,79,80,54,83,86],{},"Cloudflare's ",[21,75,78],{"href":76,"rel":77,"target":27},"https:\u002F\u002Fblog.cloudflare.com\u002Fcode-mode\u002F",[25,26],"Code Mode"," made the same observation at the tool layer: a model writes code more naturally than it calls tools. They know ",[51,81,82],{},"Promise.all",[51,84,85],{},"async\u002Fawait",", typed interfaces; the tool-call format is comparatively synthetic. Their fix was to convert the MCP schema into a TypeScript API and let the model write code.",[13,88,89,90,92,93,95,96,98,99,102],{},"The same argument extends to orchestration. The model writes an async body with three primitives: ",[51,91,53],{}," to spawn a child, ",[51,94,57],{}," to collect its result, and ",[51,97,61],{}," to stop work. Once ",[51,100,101],{},"run"," is non-blocking, basic fan-out is just JavaScript:",[104,105,110],"pre",{"className":106,"code":107,"language":108,"meta":109,"style":109},"language-js shiki shiki-themes github-dark","const agents = await Promise.all([\n  run({ prompt: \"Find security risks\" }),\n  run({ prompt: \"Find database risks\" }),\n  run({ prompt: \"Find frontend risks\" }),\n]);\n\ntry {\n  \u002F\u002F Collect all outputs within a strict 15-second deadline\n  const pendingJoins = agents.map(a => join(a.id, { timeout: 15000 }));\n  return await Promise.all(pendingJoins);\n} catch (timeout) {\n  \u002F\u002F Kill all branches past deadline to save tokens\n  await Promise.all(agents.map(a => cancel(a.id)));\n  throw new Error(\"Scan timed out.\");\n}\n","js","",[51,111,112,144,160,172,184,190,197,206,213,251,268,280,286,315,335],{"__ignoreMap":109},[113,114,117,121,125,128,131,134,137,141],"span",{"class":115,"line":116},"line",1,[113,118,120],{"class":119},"snl16","const",[113,122,124],{"class":123},"sDLfK"," agents",[113,126,127],{"class":119}," =",[113,129,130],{"class":119}," await",[113,132,133],{"class":123}," Promise",[113,135,34],{"class":136},"s95oV",[113,138,140],{"class":139},"svObZ","all",[113,142,143],{"class":136},"([\n",[113,145,147,150,153,157],{"class":115,"line":146},2,[113,148,149],{"class":139},"  run",[113,151,152],{"class":136},"({ prompt: ",[113,154,156],{"class":155},"sU2Wk","\"Find security risks\"",[113,158,159],{"class":136}," }),\n",[113,161,163,165,167,170],{"class":115,"line":162},3,[113,164,149],{"class":139},[113,166,152],{"class":136},[113,168,169],{"class":155},"\"Find database risks\"",[113,171,159],{"class":136},[113,173,175,177,179,182],{"class":115,"line":174},4,[113,176,149],{"class":139},[113,178,152],{"class":136},[113,180,181],{"class":155},"\"Find frontend risks\"",[113,183,159],{"class":136},[113,185,187],{"class":115,"line":186},5,[113,188,189],{"class":136},"]);\n",[113,191,193],{"class":115,"line":192},6,[113,194,196],{"emptyLinePlaceholder":195},true,"\n",[113,198,200,203],{"class":115,"line":199},7,[113,201,202],{"class":119},"try",[113,204,205],{"class":136}," {\n",[113,207,209],{"class":115,"line":208},8,[113,210,212],{"class":211},"sAwPA","  \u002F\u002F Collect all outputs within a strict 15-second deadline\n",[113,214,216,219,222,224,227,230,233,236,239,242,245,248],{"class":115,"line":215},9,[113,217,218],{"class":119},"  const",[113,220,221],{"class":123}," pendingJoins",[113,223,127],{"class":119},[113,225,226],{"class":136}," agents.",[113,228,229],{"class":139},"map",[113,231,232],{"class":136},"(",[113,234,21],{"class":235},"s9osk",[113,237,238],{"class":119}," =>",[113,240,241],{"class":139}," join",[113,243,244],{"class":136},"(a.id, { timeout: ",[113,246,247],{"class":123},"15000",[113,249,250],{"class":136}," }));\n",[113,252,254,257,259,261,263,265],{"class":115,"line":253},10,[113,255,256],{"class":119},"  return",[113,258,130],{"class":119},[113,260,133],{"class":123},[113,262,34],{"class":136},[113,264,140],{"class":139},[113,266,267],{"class":136},"(pendingJoins);\n",[113,269,271,274,277],{"class":115,"line":270},11,[113,272,273],{"class":136},"} ",[113,275,276],{"class":119},"catch",[113,278,279],{"class":136}," (timeout) {\n",[113,281,283],{"class":115,"line":282},12,[113,284,285],{"class":211},"  \u002F\u002F Kill all branches past deadline to save tokens\n",[113,287,289,292,294,296,298,301,303,305,307,309,312],{"class":115,"line":288},13,[113,290,291],{"class":119},"  await",[113,293,133],{"class":123},[113,295,34],{"class":136},[113,297,140],{"class":139},[113,299,300],{"class":136},"(agents.",[113,302,229],{"class":139},[113,304,232],{"class":136},[113,306,21],{"class":235},[113,308,238],{"class":119},[113,310,311],{"class":139}," cancel",[113,313,314],{"class":136},"(a.id)));\n",[113,316,318,321,324,327,329,332],{"class":115,"line":317},14,[113,319,320],{"class":119},"  throw",[113,322,323],{"class":119}," new",[113,325,326],{"class":139}," Error",[113,328,232],{"class":136},[113,330,331],{"class":155},"\"Scan timed out.\"",[113,333,334],{"class":136},");\n",[113,336,338],{"class":115,"line":337},15,[113,339,340],{"class":136},"}\n",[13,342,343],{},"The plan is now in code and not working memory. Each branch runs in an isolated context. The parent collects clean outputs instead of absorbing every intermediate token from every child.",[64,345,347],{"id":346},"the-tiny-api","The Tiny API",[13,349,350,351,356,357,362],{},"I tested this in ",[21,352,355],{"href":353,"rel":354,"target":27},"https:\u002F\u002Fpi.dev\u002F",[25,26],"Pi",", a minimal agent-harness, similar to Claude Code. It's intentionally small, inspectable, and easy to extend (Mario Zechner's ",[21,358,361],{"href":359,"rel":360,"target":27},"https:\u002F\u002Fmariozechner.at\u002Fposts\u002F2025-11-30-pi-coding-agent\u002F",[25,26],"design post"," covers the architecture). This extensibility makes it a good place to try my weird orchestration idea.",[364,365,367],"h3",{"id":366},"the-extension","The Extension",[13,369,370,371,374,375,378],{},"The extension (called ",[51,372,373],{},"pi-dispatch"," hereafter) registers a single tool that accepts a code string. The model writes an async JavaScript body, and the runtime evaluates it with one injected object, ",[51,376,377],{},"sa",", which exposes five methods:",[104,380,382],{"className":106,"code":381,"language":108,"meta":109,"style":109},"sa.run({ prompt, model?, ...})   \u002F\u002F -> { id }\nsa.join(id)                      \u002F\u002F -> { ..., output?, error? }\nsa.cancel(id)                    \u002F\u002F kill a running child\nsa.status(id)                    \u002F\u002F inspect one run\nsa.list()                        \u002F\u002F inspect all runs\n",[51,383,384,403,416,429,441],{"__ignoreMap":109},[113,385,386,389,391,394,397,400],{"class":115,"line":116},[113,387,388],{"class":136},"sa.",[113,390,101],{"class":139},[113,392,393],{"class":136},"({ prompt, model?, ",[113,395,396],{"class":119},"...",[113,398,399],{"class":136},"})   ",[113,401,402],{"class":211},"\u002F\u002F -> { id }\n",[113,404,405,407,410,413],{"class":115,"line":146},[113,406,388],{"class":136},[113,408,409],{"class":139},"join",[113,411,412],{"class":136},"(id)                      ",[113,414,415],{"class":211},"\u002F\u002F -> { ..., output?, error? }\n",[113,417,418,420,423,426],{"class":115,"line":162},[113,419,388],{"class":136},[113,421,422],{"class":139},"cancel",[113,424,425],{"class":136},"(id)                    ",[113,427,428],{"class":211},"\u002F\u002F kill a running child\n",[113,430,431,433,436,438],{"class":115,"line":174},[113,432,388],{"class":136},[113,434,435],{"class":139},"status",[113,437,425],{"class":136},[113,439,440],{"class":211},"\u002F\u002F inspect one run\n",[113,442,443,445,448,451],{"class":115,"line":186},[113,444,388],{"class":136},[113,446,447],{"class":139},"list",[113,449,450],{"class":136},"()                        ",[113,452,453],{"class":211},"\u002F\u002F inspect all runs\n",[13,455,456,457,460,461,463,464,466],{},"When ",[51,458,459],{},"sa.run(spec)"," fires, it launches a child Pi process in JSON-event mode. The parent reads that process's stdout, tracks the events, and resolves a handle when the child exits cleanly. ",[51,462,101],{}," is non-blocking by design. That's what makes ",[51,465,82],{}," over a set of handles ordinary JavaScript rather than a special case.",[13,468,469,472],{},[51,470,471],{},"sa.cancel"," is the primitive that changes what the parent can express. Killing a running process is a small thing to implement, but without it, a parallel dispatch is just fan-out and wait. With it, the model can write a race: launch several approaches, take the first answer that comes back good, and stop paying tokens on everything else.",[13,474,475,476,479,480,482,483,486,487,54,490,493],{},"The orchestration body runs inside a ",[51,477,478],{},"new AsyncFunction(\"sa\", code)"," call, which means ",[51,481,377],{}," is the only named parameter and ",[51,484,485],{},"await"," works natively throughout. The scoping is deliberate but not a security boundary: the model's code simply has no access to ",[51,488,489],{},"require",[51,491,492],{},"process",", or anything else from the surrounding extension, just the one interface it actually needs.",[13,495,496],{},[497,498,499],"em",{},"Five methods and a code string. That's the whole runtime.",[64,501,503],{"id":502},"why-not-just-use-the-built-in-subagent-tools","Why Not Just Use The Built-In Subagent Tools?",[13,505,506,507,510,511,514,515,518,519,522],{},"Both Claude & Codex provide the pieces: an ",[51,508,509],{},"Agent"," tool for spawning subagents, ",[51,512,513],{},"run_in_background"," for concurrent dispatch, ",[51,516,517],{},"TaskStop"," to kill a running agent, ",[51,520,521],{},"Monitor"," to watch process output. You could approximate a race-and-cancel: spin up background agents, monitor their output, stop the losers when one wins. The right operations exist.",[13,524,525],{},[497,526,527],{},"But look at what that requires.",[13,529,530,531,533],{},"Between each step, the parent has to hold the orchestration state as running text between turns: read what the monitor surfaced, decide which branch won, call ",[51,532,517],{},", reconcile the result. The workflow isn't written anywhere. It lives as working memory across turns. If a branch fails at step four, there is no checkpoint.",[64,535,537],{"id":536},"benchmark-same-task-two-harnesses","Benchmark: Same Task, Two Harnesses",[13,539,540,541,543],{},"Codex is the control: native tool-call orchestration, no external runtime. ",[51,542,373],{}," is the runtime harness: the model writes JS, fan-out and join happen server-side, only the final return comes back to the parent. The variable is how much context the parent holds while the orchestration runs.",[13,545,546,547,550],{},"We send the same task to both harnesses, running ",[51,548,549],{},"gpt-5.5:medium",": evaluate five strategies in parallel, stop early on hard blockers, and synthesize a ranked recommendation from the strategies that survive.",[552,553,555],"content-collapsible",{"title":554},"Full Prompt",[39,556,557,560,563,566,569],{},[13,558,559],{},"You are orchestrating an analysis. Spawn five concurrent subagents (one per strategy) and synthesize their results into a ranked recommendation.",[13,561,562],{},"Context: an engineering team needs a query-answering assistant for their monorepo. The codebase is 500k tokens across approximately 3k files. The constraints are fixed: the available model has a 200k-token context window, every answer must cite exact file paths and line numbers (approximate or summarized citations disqualify the answer), query latency must be ≤ 30 seconds p95, and cost must be ≤ $0.10 per query at 10k queries\u002Fday. Pricing: $3\u002FM input tokens, $15\u002FM output tokens, $0.02\u002FM tokens for embeddings.",[13,564,565],{},"The five strategies, one subagent per strategy: RAG (chunk-embed-retrieve), map-reduce summarization, long-context single-shot, hierarchical two-stage retrieval, agentic search (grep and file tools).",[13,567,568],{},"Each subagent begins with a feasibility check. If a strategy has a fatal blocker (a hard constraint violation, not a risk or caveat), it reports the blocker and stops. Otherwise it elaborates a full six-section analysis covering implementation, failure modes, rollout plan, latency and cost projections, fallback strategy, and final recommendation.",[13,570,571],{},"Once subagents complete, synthesize a ranked recommendation from the surviving analyses.",[13,573,574,575,577],{},"The ",[51,576,373],{}," orchestration follows a small shape: fan out five runs, join them, parse one verdict line from each result, and synthesize only the survivors. The interesting part is the contract the parent creates with its children.",[13,579,580],{},"Each subagent is told to end with exactly one machine-readable line:",[104,582,587],{"className":583,"code":585,"language":586,"meta":109},[584],"language-text","FINAL_VERDICT: BLOCKED\nor\nFINAL_VERDICT: PROCEED\n","text",[51,588,585],{"__ignoreMap":109},[13,590,591,592,595,596,599,600,602],{},"The parent parses that line, splits the results into ",[51,593,594],{},"blocked"," and ",[51,597,598],{},"surviving",", then sends only the surviving analyses into the synthesis pass. Codex arrives at the same split by reading prose output and deciding what sounds blocked. ",[51,601,373],{}," makes the split deterministic code.",[552,604,606],{"title":605},"Full Orchestration Body",[104,607,609],{"className":106,"code":608,"language":108,"meta":109,"style":109},"const strategies = [\n  \"RAG (chunk-embed-retrieve)\",\n  \"map-reduce summarization\",\n  \"long-context single-shot\",\n  \"hierarchical two-stage retrieval\",\n  \"agentic search (grep and file tools)\"\n];\n\nconst basePrompt = `\nEvaluate this strategy for a monorepo query-answering assistant.\n\nContext:\n- Codebase: 500,000 tokens across ~3,000 files\n- Model context: 200,000 tokens\n- Answers must cite exact file paths and line numbers\n- Latency: \u003C= 30s p95\n- Cost: \u003C= $0.10\u002Fquery at 10,000 queries\u002Fday\n- Pricing: $3\u002FM input tokens, $15\u002FM output tokens, $0.02\u002FM embeddings\n\nStrategy: {{STRATEGY}}\n\nBegin with a feasibility check.\nIf there is a fatal hard-constraint blocker, explain it and stop.\nOtherwise provide:\n1. Implementation\n2. Failure modes\n3. Rollout plan\n4. Latency and cost projections\n5. Fallback strategy\n6. Final recommendation\n\nEnd with exactly one line:\nFINAL_VERDICT: BLOCKED\nor\nFINAL_VERDICT: PROCEED\n`.trim();\n\nconst runs = await Promise.all(\n  strategies.map(strategy =>\n    sa.run({\n      prompt: basePrompt.replace(\"{{STRATEGY}}\", strategy)\n    })\n  )\n);\n\nconst results = await Promise.all(runs.map(r => sa.join(r.id)));\n\nconst analyses = results.map((r, i) => {\n  const output = r.output || \"\";\n  const verdict = output.match(\n    \u002FFINAL_VERDICT:\\s*(BLOCKED|PROCEED)\\b\u002Fi\n  )?.[1]?.toUpperCase() ||\"BLOCKED\";\n\n  return { strategy: strategies[i], verdict, output };\n});\n\nconst blocked = analyses.filter(a => a.verdict === \"BLOCKED\");\nconst surviving = analyses.filter(a => a.verdict === \"PROCEED\");\n\nconst synthPrompt = `\nSynthesize a ranked recommendation.\n\nRank only surviving strategies.\nList blocked strategies separately with their disqualifying constraint.\n\nSurviving:\n${surviving.map(a => `\\n## ${a.strategy}\\n${a.output}`).join(\"\\n\")}\n\nBlocked:\n${blocked.map(a => `\\n## ${a.strategy}\\n${a.output}`).join(\"\\n\")}\n`.trim();\n\nconst synthRun = await sa.run({ prompt: synthPrompt });\nconst synth = await sa.join(synthRun.id);\n\nreturn synth.output;\n",[51,610,611,623,631,638,645,652,657,662,666,678,683,687,692,697,702,707,713,719,725,730,736,741,747,753,759,765,771,777,783,789,795,800,806,812,818,824,838,843,864,880,891,908,914,920,925,930,968,973,1006,1028,1046,1080,1105,1110,1118,1124,1129,1162,1191,1196,1208,1214,1219,1225,1231,1236,1242,1311,1316,1322,1381,1392,1397,1416,1435,1440],{"__ignoreMap":109},[113,612,613,615,618,620],{"class":115,"line":116},[113,614,120],{"class":119},[113,616,617],{"class":123}," strategies",[113,619,127],{"class":119},[113,621,622],{"class":136}," [\n",[113,624,625,628],{"class":115,"line":146},[113,626,627],{"class":155},"  \"RAG (chunk-embed-retrieve)\"",[113,629,630],{"class":136},",\n",[113,632,633,636],{"class":115,"line":162},[113,634,635],{"class":155},"  \"map-reduce summarization\"",[113,637,630],{"class":136},[113,639,640,643],{"class":115,"line":174},[113,641,642],{"class":155},"  \"long-context single-shot\"",[113,644,630],{"class":136},[113,646,647,650],{"class":115,"line":186},[113,648,649],{"class":155},"  \"hierarchical two-stage retrieval\"",[113,651,630],{"class":136},[113,653,654],{"class":115,"line":192},[113,655,656],{"class":155},"  \"agentic search (grep and file tools)\"\n",[113,658,659],{"class":115,"line":199},[113,660,661],{"class":136},"];\n",[113,663,664],{"class":115,"line":208},[113,665,196],{"emptyLinePlaceholder":195},[113,667,668,670,673,675],{"class":115,"line":215},[113,669,120],{"class":119},[113,671,672],{"class":123}," basePrompt",[113,674,127],{"class":119},[113,676,677],{"class":155}," `\n",[113,679,680],{"class":115,"line":253},[113,681,682],{"class":155},"Evaluate this strategy for a monorepo query-answering assistant.\n",[113,684,685],{"class":115,"line":270},[113,686,196],{"emptyLinePlaceholder":195},[113,688,689],{"class":115,"line":282},[113,690,691],{"class":155},"Context:\n",[113,693,694],{"class":115,"line":288},[113,695,696],{"class":155},"- Codebase: 500,000 tokens across ~3,000 files\n",[113,698,699],{"class":115,"line":317},[113,700,701],{"class":155},"- Model context: 200,000 tokens\n",[113,703,704],{"class":115,"line":337},[113,705,706],{"class":155},"- Answers must cite exact file paths and line numbers\n",[113,708,710],{"class":115,"line":709},16,[113,711,712],{"class":155},"- Latency: \u003C= 30s p95\n",[113,714,716],{"class":115,"line":715},17,[113,717,718],{"class":155},"- Cost: \u003C= $0.10\u002Fquery at 10,000 queries\u002Fday\n",[113,720,722],{"class":115,"line":721},18,[113,723,724],{"class":155},"- Pricing: $3\u002FM input tokens, $15\u002FM output tokens, $0.02\u002FM embeddings\n",[113,726,728],{"class":115,"line":727},19,[113,729,196],{"emptyLinePlaceholder":195},[113,731,733],{"class":115,"line":732},20,[113,734,735],{"class":155},"Strategy: {{STRATEGY}}\n",[113,737,739],{"class":115,"line":738},21,[113,740,196],{"emptyLinePlaceholder":195},[113,742,744],{"class":115,"line":743},22,[113,745,746],{"class":155},"Begin with a feasibility check.\n",[113,748,750],{"class":115,"line":749},23,[113,751,752],{"class":155},"If there is a fatal hard-constraint blocker, explain it and stop.\n",[113,754,756],{"class":115,"line":755},24,[113,757,758],{"class":155},"Otherwise provide:\n",[113,760,762],{"class":115,"line":761},25,[113,763,764],{"class":155},"1. Implementation\n",[113,766,768],{"class":115,"line":767},26,[113,769,770],{"class":155},"2. Failure modes\n",[113,772,774],{"class":115,"line":773},27,[113,775,776],{"class":155},"3. Rollout plan\n",[113,778,780],{"class":115,"line":779},28,[113,781,782],{"class":155},"4. Latency and cost projections\n",[113,784,786],{"class":115,"line":785},29,[113,787,788],{"class":155},"5. Fallback strategy\n",[113,790,792],{"class":115,"line":791},30,[113,793,794],{"class":155},"6. Final recommendation\n",[113,796,798],{"class":115,"line":797},31,[113,799,196],{"emptyLinePlaceholder":195},[113,801,803],{"class":115,"line":802},32,[113,804,805],{"class":155},"End with exactly one line:\n",[113,807,809],{"class":115,"line":808},33,[113,810,811],{"class":155},"FINAL_VERDICT: BLOCKED\n",[113,813,815],{"class":115,"line":814},34,[113,816,817],{"class":155},"or\n",[113,819,821],{"class":115,"line":820},35,[113,822,823],{"class":155},"FINAL_VERDICT: PROCEED\n",[113,825,827,830,832,835],{"class":115,"line":826},36,[113,828,829],{"class":155},"`",[113,831,34],{"class":136},[113,833,834],{"class":139},"trim",[113,836,837],{"class":136},"();\n",[113,839,841],{"class":115,"line":840},37,[113,842,196],{"emptyLinePlaceholder":195},[113,844,846,848,851,853,855,857,859,861],{"class":115,"line":845},38,[113,847,120],{"class":119},[113,849,850],{"class":123}," runs",[113,852,127],{"class":119},[113,854,130],{"class":119},[113,856,133],{"class":123},[113,858,34],{"class":136},[113,860,140],{"class":139},[113,862,863],{"class":136},"(\n",[113,865,867,870,872,874,877],{"class":115,"line":866},39,[113,868,869],{"class":136},"  strategies.",[113,871,229],{"class":139},[113,873,232],{"class":136},[113,875,876],{"class":235},"strategy",[113,878,879],{"class":119}," =>\n",[113,881,883,886,888],{"class":115,"line":882},40,[113,884,885],{"class":136},"    sa.",[113,887,101],{"class":139},[113,889,890],{"class":136},"({\n",[113,892,894,897,900,902,905],{"class":115,"line":893},41,[113,895,896],{"class":136},"      prompt: basePrompt.",[113,898,899],{"class":139},"replace",[113,901,232],{"class":136},[113,903,904],{"class":155},"\"{{STRATEGY}}\"",[113,906,907],{"class":136},", strategy)\n",[113,909,911],{"class":115,"line":910},42,[113,912,913],{"class":136},"    })\n",[113,915,917],{"class":115,"line":916},43,[113,918,919],{"class":136},"  )\n",[113,921,923],{"class":115,"line":922},44,[113,924,334],{"class":136},[113,926,928],{"class":115,"line":927},45,[113,929,196],{"emptyLinePlaceholder":195},[113,931,933,935,938,940,942,944,946,948,951,953,955,958,960,963,965],{"class":115,"line":932},46,[113,934,120],{"class":119},[113,936,937],{"class":123}," results",[113,939,127],{"class":119},[113,941,130],{"class":119},[113,943,133],{"class":123},[113,945,34],{"class":136},[113,947,140],{"class":139},[113,949,950],{"class":136},"(runs.",[113,952,229],{"class":139},[113,954,232],{"class":136},[113,956,957],{"class":235},"r",[113,959,238],{"class":119},[113,961,962],{"class":136}," sa.",[113,964,409],{"class":139},[113,966,967],{"class":136},"(r.id)));\n",[113,969,971],{"class":115,"line":970},47,[113,972,196],{"emptyLinePlaceholder":195},[113,974,976,978,981,983,986,988,991,993,995,998,1001,1004],{"class":115,"line":975},48,[113,977,120],{"class":119},[113,979,980],{"class":123}," analyses",[113,982,127],{"class":119},[113,984,985],{"class":136}," results.",[113,987,229],{"class":139},[113,989,990],{"class":136},"((",[113,992,957],{"class":235},[113,994,54],{"class":136},[113,996,997],{"class":235},"i",[113,999,1000],{"class":136},") ",[113,1002,1003],{"class":119},"=>",[113,1005,205],{"class":136},[113,1007,1009,1011,1014,1016,1019,1022,1025],{"class":115,"line":1008},49,[113,1010,218],{"class":119},[113,1012,1013],{"class":123}," output",[113,1015,127],{"class":119},[113,1017,1018],{"class":136}," r.output ",[113,1020,1021],{"class":119},"||",[113,1023,1024],{"class":155}," \"\"",[113,1026,1027],{"class":136},";\n",[113,1029,1031,1033,1036,1038,1041,1044],{"class":115,"line":1030},50,[113,1032,218],{"class":119},[113,1034,1035],{"class":123}," verdict",[113,1037,127],{"class":119},[113,1039,1040],{"class":136}," output.",[113,1042,1043],{"class":139},"match",[113,1045,863],{"class":136},[113,1047,1049,1052,1056,1059,1062,1065,1068,1071,1074,1077],{"class":115,"line":1048},51,[113,1050,1051],{"class":155},"    \u002F",[113,1053,1055],{"class":1054},"sns5M","FINAL_VERDICT:",[113,1057,1058],{"class":123},"\\s",[113,1060,1061],{"class":119},"*",[113,1063,1064],{"class":1054},"(BLOCKED",[113,1066,1067],{"class":119},"|",[113,1069,1070],{"class":1054},"PROCEED)",[113,1072,1073],{"class":119},"\\b",[113,1075,1076],{"class":155},"\u002F",[113,1078,1079],{"class":119},"i\n",[113,1081,1083,1086,1089,1092,1095,1098,1100,1103],{"class":115,"line":1082},52,[113,1084,1085],{"class":136},"  )?.[",[113,1087,1088],{"class":123},"1",[113,1090,1091],{"class":136},"]?.",[113,1093,1094],{"class":139},"toUpperCase",[113,1096,1097],{"class":136},"() ",[113,1099,1021],{"class":119},[113,1101,1102],{"class":155},"\"BLOCKED\"",[113,1104,1027],{"class":136},[113,1106,1108],{"class":115,"line":1107},53,[113,1109,196],{"emptyLinePlaceholder":195},[113,1111,1113,1115],{"class":115,"line":1112},54,[113,1114,256],{"class":119},[113,1116,1117],{"class":136}," { strategy: strategies[i], verdict, output };\n",[113,1119,1121],{"class":115,"line":1120},55,[113,1122,1123],{"class":136},"});\n",[113,1125,1127],{"class":115,"line":1126},56,[113,1128,196],{"emptyLinePlaceholder":195},[113,1130,1132,1134,1137,1139,1142,1145,1147,1149,1151,1154,1157,1160],{"class":115,"line":1131},57,[113,1133,120],{"class":119},[113,1135,1136],{"class":123}," blocked",[113,1138,127],{"class":119},[113,1140,1141],{"class":136}," analyses.",[113,1143,1144],{"class":139},"filter",[113,1146,232],{"class":136},[113,1148,21],{"class":235},[113,1150,238],{"class":119},[113,1152,1153],{"class":136}," a.verdict ",[113,1155,1156],{"class":119},"===",[113,1158,1159],{"class":155}," \"BLOCKED\"",[113,1161,334],{"class":136},[113,1163,1165,1167,1170,1172,1174,1176,1178,1180,1182,1184,1186,1189],{"class":115,"line":1164},58,[113,1166,120],{"class":119},[113,1168,1169],{"class":123}," surviving",[113,1171,127],{"class":119},[113,1173,1141],{"class":136},[113,1175,1144],{"class":139},[113,1177,232],{"class":136},[113,1179,21],{"class":235},[113,1181,238],{"class":119},[113,1183,1153],{"class":136},[113,1185,1156],{"class":119},[113,1187,1188],{"class":155}," \"PROCEED\"",[113,1190,334],{"class":136},[113,1192,1194],{"class":115,"line":1193},59,[113,1195,196],{"emptyLinePlaceholder":195},[113,1197,1199,1201,1204,1206],{"class":115,"line":1198},60,[113,1200,120],{"class":119},[113,1202,1203],{"class":123}," synthPrompt",[113,1205,127],{"class":119},[113,1207,677],{"class":155},[113,1209,1211],{"class":115,"line":1210},61,[113,1212,1213],{"class":155},"Synthesize a ranked recommendation.\n",[113,1215,1217],{"class":115,"line":1216},62,[113,1218,196],{"emptyLinePlaceholder":195},[113,1220,1222],{"class":115,"line":1221},63,[113,1223,1224],{"class":155},"Rank only surviving strategies.\n",[113,1226,1228],{"class":115,"line":1227},64,[113,1229,1230],{"class":155},"List blocked strategies separately with their disqualifying constraint.\n",[113,1232,1234],{"class":115,"line":1233},65,[113,1235,196],{"emptyLinePlaceholder":195},[113,1237,1239],{"class":115,"line":1238},66,[113,1240,1241],{"class":155},"Surviving:\n",[113,1243,1245,1248,1250,1252,1254,1256,1258,1260,1263,1266,1269,1271,1273,1275,1278,1280,1282,1284,1286,1289,1292,1295,1297,1299,1302,1304,1306,1309],{"class":115,"line":1244},67,[113,1246,1247],{"class":155},"${",[113,1249,598],{"class":136},[113,1251,34],{"class":155},[113,1253,229],{"class":139},[113,1255,232],{"class":155},[113,1257,21],{"class":123},[113,1259,238],{"class":119},[113,1261,1262],{"class":155}," `",[113,1264,1265],{"class":123},"\\n",[113,1267,1268],{"class":155},"## ${",[113,1270,21],{"class":136},[113,1272,34],{"class":155},[113,1274,876],{"class":136},[113,1276,1277],{"class":155},"}",[113,1279,1265],{"class":123},[113,1281,1247],{"class":155},[113,1283,21],{"class":136},[113,1285,34],{"class":155},[113,1287,1288],{"class":136},"output",[113,1290,1291],{"class":155},"}`",[113,1293,1294],{"class":155},").",[113,1296,409],{"class":139},[113,1298,232],{"class":155},[113,1300,1301],{"class":155},"\"",[113,1303,1265],{"class":123},[113,1305,1301],{"class":155},[113,1307,1308],{"class":155},")",[113,1310,340],{"class":155},[113,1312,1314],{"class":115,"line":1313},68,[113,1315,196],{"emptyLinePlaceholder":195},[113,1317,1319],{"class":115,"line":1318},69,[113,1320,1321],{"class":155},"Blocked:\n",[113,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1349,1351,1353,1355,1357,1359,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379],{"class":115,"line":1324},70,[113,1326,1247],{"class":155},[113,1328,594],{"class":136},[113,1330,34],{"class":155},[113,1332,229],{"class":139},[113,1334,232],{"class":155},[113,1336,21],{"class":123},[113,1338,238],{"class":119},[113,1340,1262],{"class":155},[113,1342,1265],{"class":123},[113,1344,1268],{"class":155},[113,1346,21],{"class":136},[113,1348,34],{"class":155},[113,1350,876],{"class":136},[113,1352,1277],{"class":155},[113,1354,1265],{"class":123},[113,1356,1247],{"class":155},[113,1358,21],{"class":136},[113,1360,34],{"class":155},[113,1362,1288],{"class":136},[113,1364,1291],{"class":155},[113,1366,1294],{"class":155},[113,1368,409],{"class":139},[113,1370,232],{"class":155},[113,1372,1301],{"class":155},[113,1374,1265],{"class":123},[113,1376,1301],{"class":155},[113,1378,1308],{"class":155},[113,1380,340],{"class":155},[113,1382,1384,1386,1388,1390],{"class":115,"line":1383},71,[113,1385,829],{"class":155},[113,1387,34],{"class":136},[113,1389,834],{"class":139},[113,1391,837],{"class":136},[113,1393,1395],{"class":115,"line":1394},72,[113,1396,196],{"emptyLinePlaceholder":195},[113,1398,1400,1402,1405,1407,1409,1411,1413],{"class":115,"line":1399},73,[113,1401,120],{"class":119},[113,1403,1404],{"class":123}," synthRun",[113,1406,127],{"class":119},[113,1408,130],{"class":119},[113,1410,962],{"class":136},[113,1412,101],{"class":139},[113,1414,1415],{"class":136},"({ prompt: synthPrompt });\n",[113,1417,1419,1421,1424,1426,1428,1430,1432],{"class":115,"line":1418},74,[113,1420,120],{"class":119},[113,1422,1423],{"class":123}," synth",[113,1425,127],{"class":119},[113,1427,130],{"class":119},[113,1429,962],{"class":136},[113,1431,409],{"class":139},[113,1433,1434],{"class":136},"(synthRun.id);\n",[113,1436,1438],{"class":115,"line":1437},75,[113,1439,196],{"emptyLinePlaceholder":195},[113,1441,1443,1446],{"class":115,"line":1442},76,[113,1444,1445],{"class":119},"return",[113,1447,1448],{"class":136}," synth.output;\n",[64,1450,1452],{"id":1451},"what-the-runtime-buys","What The Runtime Buys",[13,1454,1455,1456,1458],{},"With Codex, every subagent return lands in the parent's context. It's in the data path for every intermediate value. With ",[51,1457,373],{},", the orchestration body runs server-side: subagent outputs flow JS-variable to JS-variable, and only the final synthesis comes back.",[1460,1461,1462,1477],"table",{},[1463,1464,1465],"thead",{},[1466,1467,1468,1472,1474],"tr",{},[1469,1470,1471],"th",{},"Metric",[1469,1473,373],{},[1469,1475,1476],{},"Codex",[1478,1479,1480,1492],"tbody",{},[1466,1481,1482,1486,1489],{},[1483,1484,1485],"td",{},"Parent context used",[1483,1487,1488],{},"2.2%",[1483,1490,1491],{},"5%",[1466,1493,1494,1497,1500],{},[1483,1495,1496],{},"Wall clock",[1483,1498,1499],{},"1m 47s",[1483,1501,1502],{},"2m 32s",[13,1504,1507],{"className":1505},[1506],"text-center",[1508,1509,1510],"small",{},"Results are aggregated over three runs.",[13,1512,1513,1514,1516],{},"That is why ",[51,1515,373],{}," holds less than half the context: the parent sees the JS body plus one synthesis return, not five subagent returns and the prose reasoning between them.",[13,1518,1519,1520,1522],{},"The wall clock results also surprised me. I expected parity since both fan out in parallel, but the Codex loop spends turns deciding what to do next between returns; ",[51,1521,373],{}," fans out once and waits.",[13,1524,1525],{},"The useful part is how small the runtime is: any harness with subagents is one small layer away from making orchestration executable.",[13,1527,1528],{},[497,1529,1530,1531],{},"The full extension is just 200 lines of TypeScript. ",[21,1532,1535],{"href":1533,"rel":1534,"target":27},"https:\u002F\u002Fgist.github.com\u002Fnidhishs\u002Fb15bb8513652f0a1cf8b0250065d9738",[25,26],"(link)",[64,1537,1539],{"id":1538},"the-pattern-converged","The Pattern Converged",[13,1541,1542,1543,1546,1547,1550,1551,1554,1555,1558,1559,1562,1563,1565,1566,1565,1568,1570],{},"A few weeks after I wrote this post, Anthropic shipped ",[21,1544,28],{"href":23,"rel":1545,"target":27},[25,26]," in Claude Code, and it's the same idea. Claude writes a script against a small set of primitives: ",[51,1548,1549],{},"agent()"," spawns a subagent and hands back its result, ",[51,1552,1553],{},"parallel()"," runs a batch at once and waits for all of them, ",[51,1556,1557],{},"pipeline()"," streams items through stages without stopping at each one, and ",[51,1560,1561],{},"phase()"," groups the run into labeled stages you can watch. It's a higher-level take on my ",[51,1564,53],{}," \u002F ",[51,1567,57],{},[51,1569,61],{},", but the design lines up:",[1572,1573,1574,1581,1595],"ul",{},[1575,1576,1577,1580],"li",{},[16,1578,1579],{},"Plan."," It lives in code, not the transcript, so the model doesn't have to carry it in its head from one turn to the next.",[1575,1582,1583,1586,1587,1590,1591,1594],{},[16,1584,1585],{},"Context."," Intermediate results stay out of it. Their docs describe them living in ",[497,1588,1589],{},"“script variables,”"," so ",[497,1592,1593],{},"“Claude's context holds only the final answer.”"," Same variable-to-variable flow that helped shrink the parent context here.",[1575,1596,1597,1600,1601,1604],{},[16,1598,1599],{},"Runtime."," It ",[497,1602,1603],{},"“executes the script in an isolated environment, separate from your conversation,”"," which is just the orchestration body running harness-side.",[13,1606,1607,1608,1610],{},"It's not a perfect match. There's no script-level ",[51,1609,61],{},", so you can't write the race-and-cancel I made a fuss about earlier. That part didn't make the jump.",[13,1612,1613,1614,1616],{},"None of this was a prediction. Once you feel the friction of bloated context, you end up here anyway. ",[51,1615,373],{}," was 200 lines on a hobby harness; Dynamic Workflows is that idea built at scale.",[1618,1619,1620],"style",{},"html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .sAwPA, html code.shiki .sAwPA{--shiki-default:#6A737D}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sns5M, html code.shiki .sns5M{--shiki-default:#DBEDFF}",{"title":109,"searchDepth":146,"depth":146,"links":1622},[1623,1624,1627,1628,1629,1630],{"id":66,"depth":146,"text":67},{"id":346,"depth":146,"text":347,"children":1625},[1626],{"id":366,"depth":162,"text":367},{"id":502,"depth":146,"text":503},{"id":536,"depth":146,"text":537},{"id":1451,"depth":146,"text":1452},{"id":1538,"depth":146,"text":1539},"2026-05-10","Making multi-agent orchestration explicit: give the model a small async runtime and let it write concurrent control flow as JavaScript instead of narrating it in prose.","md",{},"\u002Fwriting\u002Fruntime-subagents-orchestration",{"title":5,"description":1632},"writing\u002F20260510.runtime-subagents-orchestration","6jNHmSGGUOFwHUEfYmWYzm8WWDgTtZUTpP106XVwV0c",1780404016750]