[{"data":1,"prerenderedAt":1024},["ShallowReactive",2],{"navigation_docs":3,"-build-plugins-harnesses":320,"-build-plugins-harnesses-surround":1019},[4,35,69,109,133,193,228,262,305],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-ph-house",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-ph-rocket-launch",{"title":21,"path":22,"stem":23,"icon":24},"Concepts","\u002Fgetting-started\u002Fconcepts","1.getting-started\u002F3.concepts","i-ph-book-open",{"title":26,"path":27,"stem":28,"icon":29},"Install","\u002Fgetting-started\u002Finstall","1.getting-started\u002F4.install","i-ph-download-simple",{"title":31,"path":32,"stem":33,"icon":34},"What works today","\u002Fgetting-started\u002Fstatus","1.getting-started\u002F5.status","i-ph-list-checks",{"title":21,"icon":6,"path":36,"stem":37,"children":38,"page":6},"\u002Fconcepts","2.concepts",[39,44,49,54,59,64],{"title":40,"path":41,"stem":42,"icon":43},"Architecture","\u002Fconcepts\u002Farchitecture","2.concepts\u002F1.architecture","i-ph-planet",{"title":45,"path":46,"stem":47,"icon":48},"Jobs and durability","\u002Fconcepts\u002Fjobs","2.concepts\u002F2.jobs","i-ph-infinity",{"title":50,"path":51,"stem":52,"icon":53},"Routing","\u002Fconcepts\u002Frouting","2.concepts\u002F3.routing","i-ph-path",{"title":55,"path":56,"stem":57,"icon":58},"Security model","\u002Fconcepts\u002Fsecurity","2.concepts\u002F4.security","i-ph-shield-check",{"title":60,"path":61,"stem":62,"icon":63},"Tenants","\u002Fconcepts\u002Ftenants","2.concepts\u002F5.tenants","i-ph-buildings",{"title":65,"path":66,"stem":67,"icon":68},"Temporal","\u002Fconcepts\u002Ftemporal","2.concepts\u002F6.temporal","i-ph-clock",{"title":70,"icon":6,"path":71,"stem":72,"children":73,"page":6},"Run a fleet","\u002Ffleet","3.fleet",[74,79,84,89,94,99,104],{"title":75,"path":76,"stem":77,"icon":78},"Dev mode","\u002Ffleet\u002Fdev-mode","3.fleet\u002F1.dev-mode","i-ph-laptop",{"title":80,"path":81,"stem":82,"icon":83},"Run a cluster","\u002Ffleet\u002Fcluster","3.fleet\u002F2.cluster","i-ph-hard-drives",{"title":85,"path":86,"stem":87,"icon":88},"Join nodes","\u002Ffleet\u002Fjoin-nodes","3.fleet\u002F3.join-nodes","i-ph-plugs-connected",{"title":90,"path":91,"stem":92,"icon":93},"Manage nodes","\u002Ffleet\u002Fmanage-nodes","3.fleet\u002F4.manage-nodes","i-ph-list-bullets",{"title":95,"path":96,"stem":97,"icon":98},"Secrets","\u002Ffleet\u002Fsecrets","3.fleet\u002F5.secrets","i-ph-key",{"title":100,"path":101,"stem":102,"icon":103},"High availability","\u002Ffleet\u002Fhigh-availability","3.fleet\u002F6.high-availability","i-ph-copy",{"title":105,"path":106,"stem":107,"icon":108},"Upgrades, backups and restores","\u002Ffleet\u002Fupgrades","3.fleet\u002F7.upgrades","i-ph-arrows-clockwise",{"title":110,"icon":6,"path":111,"stem":112,"children":113,"page":6},"Use plugins","\u002Fplugins","4.plugins",[114,119,124,128],{"title":115,"path":116,"stem":117,"icon":118},"What a plugin is","\u002Fplugins\u002Foverview","4.plugins\u002F1.overview","i-ph-puzzle-piece",{"title":120,"path":121,"stem":122,"icon":123},"Install and update","\u002Fplugins\u002Finstall","4.plugins\u002F2.install","i-ph-package",{"title":125,"path":126,"stem":127,"icon":123},"Existing MCP packages","\u002Fplugins\u002Fpackages","4.plugins\u002F3.packages",{"title":129,"path":130,"stem":131,"icon":132},"The catalog","\u002Fplugins\u002Fcatalog","4.plugins\u002F4.catalog","i-ph-books",{"title":134,"icon":6,"path":135,"stem":136,"children":137,"page":6},"Build plugins","\u002Fbuild-plugins","5.build-plugins",[138,143,148,153,158,163,168,173,178,183,188],{"title":139,"path":140,"stem":141,"icon":142},"Your first plugin","\u002Fbuild-plugins\u002Ffirst-plugin","5.build-plugins\u002F1.first-plugin","i-ph-hammer",{"title":144,"path":145,"stem":146,"icon":147},"Harnesses","\u002Fbuild-plugins\u002Fharnesses","5.build-plugins\u002F10.harnesses","i-ph-cpu",{"title":149,"path":150,"stem":151,"icon":152},"Example: support triage","\u002Fbuild-plugins\u002Fexample-support-triage","5.build-plugins\u002F11.example-support-triage","i-ph-lifebuoy",{"title":154,"path":155,"stem":156,"icon":157},"Tools","\u002Fbuild-plugins\u002Ftools","5.build-plugins\u002F2.tools","i-ph-wrench",{"title":159,"path":160,"stem":161,"icon":162},"Agents","\u002Fbuild-plugins\u002Fagents","5.build-plugins\u002F3.agents","i-ph-robot",{"title":164,"path":165,"stem":166,"icon":167},"Skills","\u002Fbuild-plugins\u002Fskills","5.build-plugins\u002F4.skills","i-ph-graduation-cap",{"title":169,"path":170,"stem":171,"icon":172},"Develop and test","\u002Fbuild-plugins\u002Fdevelop-and-test","5.build-plugins\u002F5.develop-and-test","i-ph-flask",{"title":174,"path":175,"stem":176,"icon":177},"Publish and version","\u002Fbuild-plugins\u002Fpublish","5.build-plugins\u002F6.publish","i-ph-tag",{"title":179,"path":180,"stem":181,"icon":182},"Hooks","\u002Fbuild-plugins\u002Fhooks","5.build-plugins\u002F7.hooks","i-ph-anchor",{"title":184,"path":185,"stem":186,"icon":187},"Flows","\u002Fbuild-plugins\u002Fflows","5.build-plugins\u002F8.flows","i-ph-flow-arrow",{"title":189,"path":190,"stem":191,"icon":192},"Evals and quality gates","\u002Fbuild-plugins\u002Fevals","5.build-plugins\u002F9.evals","i-ph-seal-check",{"title":194,"icon":6,"path":195,"stem":196,"children":197,"page":6},"Run agents","\u002Fagents","6.agents",[198,203,208,213,218,223],{"title":199,"path":200,"stem":201,"icon":202},"Run jobs","\u002Fagents\u002Frun-jobs","6.agents\u002F1.run-jobs","i-ph-play",{"title":204,"path":205,"stem":206,"icon":207},"Models and keys","\u002Fagents\u002Fmodels-and-keys","6.agents\u002F2.models-and-keys","i-ph-sparkle",{"title":209,"path":210,"stem":211,"icon":212},"Delegation","\u002Fagents\u002Fdelegation","6.agents\u002F3.delegation","i-ph-git-fork",{"title":214,"path":215,"stem":216,"icon":217},"Contracts and limits","\u002Fagents\u002Fcontracts-and-limits","6.agents\u002F4.contracts-and-limits","i-ph-ruler",{"title":219,"path":220,"stem":221,"icon":222},"Runtime API","\u002Fagents\u002Fruntime-api","6.agents\u002F5.runtime-api","i-ph-plug",{"title":224,"path":225,"stem":226,"icon":227},"Approvals","\u002Fagents\u002Fapprovals","6.agents\u002F6.approvals","i-ph-hand-palm",{"title":229,"icon":6,"path":230,"stem":231,"children":232,"page":6},"Monitor","\u002Fmonitor","7.monitor",[233,238,243,248,253,258],{"title":234,"path":235,"stem":236,"icon":237},"Web UI","\u002Fmonitor\u002Fweb-ui","7.monitor\u002F0.web-ui","i-ph-monitor",{"title":239,"path":240,"stem":241,"icon":242},"Cost and usage","\u002Fmonitor\u002Fcost-and-usage","7.monitor\u002F1.cost-and-usage","i-ph-coins",{"title":244,"path":245,"stem":246,"icon":247},"Node health","\u002Fmonitor\u002Fnodes","7.monitor\u002F2.nodes","i-ph-heartbeat",{"title":249,"path":250,"stem":251,"icon":252},"Job history","\u002Fmonitor\u002Fhistory","7.monitor\u002F3.history","i-ph-clock-counter-clockwise",{"title":254,"path":255,"stem":256,"icon":257},"Tracing and metrics","\u002Fmonitor\u002Fobservability","7.monitor\u002F4.observability","i-ph-chart-line",{"title":259,"path":260,"stem":261,"icon":152},"Troubleshooting","\u002Fmonitor\u002Ftroubleshooting","7.monitor\u002F5.troubleshooting",{"title":263,"icon":6,"path":264,"stem":265,"children":266,"page":6},"Reference","\u002Freference","8.reference",[267,281,286,290,295,300],{"title":268,"icon":269,"path":270,"stem":271,"children":272,"page":6},"CLI","i-ph-terminal-window","\u002Freference\u002Fcli","8.reference\u002F1.cli",[273,277],{"title":274,"path":275,"stem":276},"orchestrator-zero","\u002Freference\u002Fcli\u002Forchestrator-zero","8.reference\u002F1.cli\u002F1.orchestrator-zero",{"title":278,"path":279,"stem":280},"orchestrator-zero-node","\u002Freference\u002Fcli\u002Forchestrator-zero-node","8.reference\u002F1.cli\u002F2.orchestrator-zero-node",{"title":282,"path":283,"stem":284,"icon":285},"oz0-plugin.yaml","\u002Freference\u002Fplugin-manifest","8.reference\u002F2.plugin-manifest","i-ph-file-code",{"title":287,"path":288,"stem":289,"icon":162},"Agent definition","\u002Freference\u002Fagent-definition","8.reference\u002F3.agent-definition",{"title":291,"path":292,"stem":293,"icon":294},"Ports","\u002Freference\u002Fports","8.reference\u002F4.ports","i-ph-network",{"title":296,"path":297,"stem":298,"icon":299},"Environment variables","\u002Freference\u002Fenvironment","8.reference\u002F5.environment","i-ph-brackets-curly",{"title":301,"path":302,"stem":303,"icon":304},"Files and directories","\u002Freference\u002Ffiles","8.reference\u002F6.files","i-ph-tree-structure",{"title":306,"icon":6,"path":307,"stem":308,"children":309,"page":6},"About","\u002Fabout","9.about",[310,315],{"title":311,"path":312,"stem":313,"icon":314},"Licensing","\u002Fabout\u002Flicensing","9.about\u002F1.licensing","i-ph-scales",{"title":316,"path":317,"stem":318,"icon":319},"About these docs","\u002Fabout\u002Fcontributing-docs","9.about\u002F2.contributing-docs","i-ph-pencil-simple",{"id":321,"title":144,"body":322,"description":1012,"extension":1013,"links":1014,"meta":1015,"navigation":1016,"path":145,"seo":1017,"stem":146,"__hash__":1018},"docs\u002F5.build-plugins\u002F10.harnesses.md",{"type":323,"value":324,"toc":1006},"minimark",[325,334,339,347,435,442,650,657,661,689,693,708,742,795,798,831,834,838,841,902,909,988,999,1002],[326,327,328,329,333],"p",{},"Some agents are better run by an existing harness than by a framework. The Claude Agent SDK brings its own tools (reading and editing files, searching, running commands), skills and subagents. A ",[330,331,332],"strong",{},"harness plugin"," adapts a harness to Orchestrator Zero: each job runs as one session of it, in its own process on the node.",[335,336,338],"h2",{"id":337},"use-the-claude-agent-sdk","Use the Claude Agent SDK",[326,340,341,342,346],{},"The official harness plugin is ",[343,344,345],"code",{},"harness-claude",". Install it on the nodes that should run harness agents, and set the tenant's Anthropic key once:",[348,349,355],"pre",{"className":350,"code":351,"filename":352,"language":353,"meta":354,"style":354},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","orchestrator-zero plugin install \u003Cgit url of the harness-claude plugin>\nprintf %s \"$ANTHROPIC_API_KEY\" | orchestrator-zero secret set ANTHROPIC_API_KEY\n","Terminal","bash","",[343,356,357,401],{"__ignoreMap":354},[358,359,362,365,369,372,376,379,382,385,388,391,394,398],"span",{"class":360,"line":361},"line",1,[358,363,274],{"class":364},"sBMFI",[358,366,368],{"class":367},"sfazB"," plugin",[358,370,371],{"class":367}," install",[358,373,375],{"class":374},"sMK4o"," \u003C",[358,377,378],{"class":367},"git",[358,380,381],{"class":367}," url",[358,383,384],{"class":367}," of",[358,386,387],{"class":367}," the",[358,389,390],{"class":367}," harness-claude",[358,392,393],{"class":367}," plugi",[358,395,397],{"class":396},"sTEyZ","n",[358,399,400],{"class":374},">\n",[358,402,404,408,411,414,417,420,423,426,429,432],{"class":360,"line":403},2,[358,405,407],{"class":406},"s2Zo4","printf",[358,409,410],{"class":367}," %s",[358,412,413],{"class":374}," \"",[358,415,416],{"class":396},"$ANTHROPIC_API_KEY",[358,418,419],{"class":374},"\"",[358,421,422],{"class":374}," |",[358,424,425],{"class":364}," orchestrator-zero",[358,427,428],{"class":367}," secret",[358,430,431],{"class":367}," set",[358,433,434],{"class":367}," ANTHROPIC_API_KEY\n",[326,436,437,438,441],{},"Then give an agent, in any plugin, ",[343,439,440],{},"runtime: harness:claude-agent-sdk",":",[348,443,448],{"className":444,"code":445,"filename":446,"language":447,"meta":354,"style":354},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","name: coder\ndescription: Makes small changes to code and runs the tests.\nruntime: harness:claude-agent-sdk\nmodel:\n  primary: anthropic\u002Fclaude-sonnet-5-5\ninstructions: prompts\u002Fcoder.md        # added to the SDK's own system prompt\nlimits:\n  max_steps: 30                       # turns\n  timeout: 30m\nharness:                              # options for the harness, passed on as they are\n  tools: [Read, Write, Edit, Glob, Grep, Bash]   # the default; anything else is refused\n  permission_mode: acceptEdits        # default, acceptEdits, plan or bypassPermissions\n  system_prompt: append               # or replace, to use only the instructions\n  max_budget_usd: 2.0                 # the SDK stops the session at this cost\n","agents\u002Fcoder.yaml","yaml",[343,449,450,461,471,482,491,502,517,525,540,551,562,608,622,636],{"__ignoreMap":354},[358,451,452,456,458],{"class":360,"line":361},[358,453,455],{"class":454},"swJcz","name",[358,457,441],{"class":374},[358,459,460],{"class":367}," coder\n",[358,462,463,466,468],{"class":360,"line":403},[358,464,465],{"class":454},"description",[358,467,441],{"class":374},[358,469,470],{"class":367}," Makes small changes to code and runs the tests.\n",[358,472,474,477,479],{"class":360,"line":473},3,[358,475,476],{"class":454},"runtime",[358,478,441],{"class":374},[358,480,481],{"class":367}," harness:claude-agent-sdk\n",[358,483,485,488],{"class":360,"line":484},4,[358,486,487],{"class":454},"model",[358,489,490],{"class":374},":\n",[358,492,494,497,499],{"class":360,"line":493},5,[358,495,496],{"class":454},"  primary",[358,498,441],{"class":374},[358,500,501],{"class":367}," anthropic\u002Fclaude-sonnet-5-5\n",[358,503,505,508,510,513],{"class":360,"line":504},6,[358,506,507],{"class":454},"instructions",[358,509,441],{"class":374},[358,511,512],{"class":367}," prompts\u002Fcoder.md",[358,514,516],{"class":515},"sHwdD","        # added to the SDK's own system prompt\n",[358,518,520,523],{"class":360,"line":519},7,[358,521,522],{"class":454},"limits",[358,524,490],{"class":374},[358,526,528,531,533,537],{"class":360,"line":527},8,[358,529,530],{"class":454},"  max_steps",[358,532,441],{"class":374},[358,534,536],{"class":535},"sbssI"," 30",[358,538,539],{"class":515},"                       # turns\n",[358,541,543,546,548],{"class":360,"line":542},9,[358,544,545],{"class":454},"  timeout",[358,547,441],{"class":374},[358,549,550],{"class":367}," 30m\n",[358,552,554,557,559],{"class":360,"line":553},10,[358,555,556],{"class":454},"harness",[358,558,441],{"class":374},[358,560,561],{"class":515},"                              # options for the harness, passed on as they are\n",[358,563,565,568,570,573,576,579,582,584,587,589,592,594,597,599,602,605],{"class":360,"line":564},11,[358,566,567],{"class":454},"  tools",[358,569,441],{"class":374},[358,571,572],{"class":374}," [",[358,574,575],{"class":367},"Read",[358,577,578],{"class":374},",",[358,580,581],{"class":367}," Write",[358,583,578],{"class":374},[358,585,586],{"class":367}," Edit",[358,588,578],{"class":374},[358,590,591],{"class":367}," Glob",[358,593,578],{"class":374},[358,595,596],{"class":367}," Grep",[358,598,578],{"class":374},[358,600,601],{"class":367}," Bash",[358,603,604],{"class":374},"]",[358,606,607],{"class":515},"   # the default; anything else is refused\n",[358,609,611,614,616,619],{"class":360,"line":610},12,[358,612,613],{"class":454},"  permission_mode",[358,615,441],{"class":374},[358,617,618],{"class":367}," acceptEdits",[358,620,621],{"class":515},"        # default, acceptEdits, plan or bypassPermissions\n",[358,623,625,628,630,633],{"class":360,"line":624},13,[358,626,627],{"class":454},"  system_prompt",[358,629,441],{"class":374},[358,631,632],{"class":367}," append",[358,634,635],{"class":515},"               # or replace, to use only the instructions\n",[358,637,639,642,644,647],{"class":360,"line":638},14,[358,640,641],{"class":454},"  max_budget_usd",[358,643,441],{"class":374},[358,645,646],{"class":535}," 2.0",[358,648,649],{"class":515},"                 # the SDK stops the session at this cost\n",[326,651,652,653,656],{},"Run it like any agent: ",[343,654,655],{},"orchestrator-zero run coder \"Fix the failing test in tests\u002Ftest_dates.py\"",". Its text and tool calls appear in the live stream, and its model calls are metered under the job.",[335,658,660],{"id":659},"what-a-session-gets","What a session gets",[662,663,664,671,677,683],"ul",{},[665,666,667,670],"li",{},[330,668,669],{},"An empty working directory"," of its own, removed when the session ends, and a private state directory for the harness's configuration.",[665,672,673,676],{},[330,674,675],{},"No user, project or local settings,"," no memory between sessions, no telemetry and no auto-update.",[665,678,679,682],{},[330,680,681],{},"The node's LLM proxy"," as its API, so the tenant's key stays in the edge, with the job and agent on every call so the gateway meters the session.",[665,684,685,688],{},[330,686,687],{},"A minimal environment:"," never the Temporal proxy's token or a provider key.",[335,690,692],{"id":691},"hooks-and-approvals-for-the-sessions-tools","Hooks and approvals for the session's tools",[326,694,695,696,703,704,707],{},"Every tool call in a Claude harness session asks first (",[697,698,702],"a",{"href":699,"rel":700},"https:\u002F\u002Fgithub.com\u002Fmoon-ventures-se\u002Forchestrator-zero\u002Fblob\u002Fdevelop\u002Fdocs\u002Fadr\u002F0031-harness-permissions-and-acp.md",[701],"nofollow","ADR 0031","). The session can use only the tools in ",[343,705,706],{},"harness.tools",", and each call runs only when the job allows it:",[662,709,710,731],{},[665,711,712,714,715,718,719,722,723,726,727,730],{},[697,713,179],{"href":180}," see it as a ",[343,716,717],{},"pre_tool_call"," named ",[343,720,721],{},"\u003Charness>.\u003Ctool>",", such as ",[343,724,725],{},"claude-agent-sdk.Bash",", with the tool's input as ",[343,728,729],{},"arguments",". They allow it, deny it, change its input or ask a person, as for any tool call.",[665,732,733,734,737,738,741],{},"Tools in ",[343,735,736],{},"harness.requires_approval"," wait for a person's ",[697,739,740],{"href":225},"approval"," of each call, once the hooks have let it through:",[348,743,745],{"className":444,"code":744,"filename":446,"language":447,"meta":354,"style":354},"harness:\n  tools: [Read, Glob, Grep, Bash]\n  requires_approval: [Bash]          # someone approves every command\n",[343,746,747,753,778],{"__ignoreMap":354},[358,748,749,751],{"class":360,"line":361},[358,750,556],{"class":454},[358,752,490],{"class":374},[358,754,755,757,759,761,763,765,767,769,771,773,775],{"class":360,"line":403},[358,756,567],{"class":454},[358,758,441],{"class":374},[358,760,572],{"class":374},[358,762,575],{"class":367},[358,764,578],{"class":374},[358,766,591],{"class":367},[358,768,578],{"class":374},[358,770,596],{"class":367},[358,772,578],{"class":374},[358,774,601],{"class":367},[358,776,777],{"class":374},"]\n",[358,779,780,783,785,787,790,792],{"class":360,"line":473},[358,781,782],{"class":454},"  requires_approval",[358,784,441],{"class":374},[358,786,572],{"class":374},[358,788,789],{"class":367},"Bash",[358,791,604],{"class":374},[358,793,794],{"class":515},"          # someone approves every command\n",[326,796,797],{},"A call that no hook matches and that needs no approval runs at once. The others go to the job's workflow, through the edge, so a call can wait days for a person without the session losing its place. A refused call is not made: the agent reads why, as the SDK reports a denied tool.",[799,800,801,804,805,807,808,811,812,815,816,819,820,824,825,830],"warning",{},[330,802,803],{},"A sandbox for sessions comes later."," Hooks and approvals decide whether a call runs, not what it can reach once it does. Give an agent only the tools its task needs, and keep agents with ",[343,806,789],{},", ",[343,809,810],{},"Write"," or ",[343,813,814],{},"Edit"," away from input you do not trust: ",[343,817,818],{},"plugin install"," refuses a ",[697,821,823],{"href":822},"\u002Fbuild-plugins\u002Fflows#start-one-from-a-webhook","flow a webhook starts"," that can reach one (",[697,826,829],{"href":827,"rel":828},"https:\u002F\u002Fgithub.com\u002Fmoon-ventures-se\u002Forchestrator-zero\u002Fblob\u002Fdevelop\u002Fdocs\u002Fadr\u002F0030-sandboxes-for-triggered-jobs-and-harness-sessions.md",[701],"ADR 0030",").",[326,832,833],{},"A session that fails fails the job; it is not retried. Inside the session, the Claude Agent SDK retries a failed model call itself, up to four times, so a call reaches the provider at most five times, as for Pydantic AI agents. Resuming a session on another node needs the harness's session store and comes later.",[335,835,837],{"id":836},"write-a-harness-for-another-tool","Write a harness for another tool",[326,839,840],{},"A harness is a command in the plugin's manifest:",[348,842,844],{"className":444,"code":843,"filename":282,"language":447,"meta":354,"style":354},"harnesses:\n  - name: my-harness\n    command: [\"python\", \"-m\", \"my_harness\"]\n",[343,845,846,853,866],{"__ignoreMap":354},[358,847,848,851],{"class":360,"line":361},[358,849,850],{"class":454},"harnesses",[358,852,490],{"class":374},[358,854,855,858,861,863],{"class":360,"line":403},[358,856,857],{"class":374},"  -",[358,859,860],{"class":454}," name",[358,862,441],{"class":374},[358,864,865],{"class":367}," my-harness\n",[358,867,868,871,873,875,877,880,882,884,886,889,891,893,895,898,900],{"class":360,"line":473},[358,869,870],{"class":454},"    command",[358,872,441],{"class":374},[358,874,572],{"class":374},[358,876,419],{"class":374},[358,878,879],{"class":367},"python",[358,881,419],{"class":374},[358,883,578],{"class":374},[358,885,413],{"class":374},[358,887,888],{"class":367},"-m",[358,890,419],{"class":374},[358,892,578],{"class":374},[358,894,413],{"class":374},[358,896,897],{"class":367},"my_harness",[358,899,419],{"class":374},[358,901,777],{"class":374},[326,903,904,905,908],{},"Agents use it with ",[343,906,907],{},"runtime: harness:my-harness",". The node starts the command once per session and talks to it in JSON lines over stdin and stdout:",[910,911,912,923,934,945,985],"ol",{},[665,913,914,915,918,919,922],{},"The runtime writes one ",[330,916,917],{},"session request"," to stdin: the job and agent, the model, the instructions, the input, the working and state directories, the turn limit and the agent's ",[343,920,921],{},"harness:"," options.",[665,924,925,926,929,930,933],{},"The harness writes ",[330,927,928],{},"session events"," to stdout, one JSON object per line: text, tool calls and tool results, and a ",[330,931,932],{},"result"," last. Logs go to stderr.",[665,935,936,937,940,941,944],{},"The harness sends the request's job and agent as the headers ",[343,938,939],{},"Oz0-Job"," and ",[343,942,943],{},"Oz0-Agent"," on its model calls.",[665,946,947,948,951,952,955,956,959,960,807,963,807,966,969,970,973,974,807,976,807,979,807,981,984],{},"A harness with ",[343,949,950],{},"permissions: true"," in the manifest asks before each tool call. When the request has ",[343,953,954],{},"permissions"," set, the harness writes a ",[330,957,958],{},"permission request"," event (",[343,961,962],{},"id",[343,964,965],{},"tool",[343,967,968],{},"input",") and waits: the runtime answers on stdin with a ",[330,971,972],{},"permission answer"," (",[343,975,962],{},[343,977,978],{},"allow",[343,980,968],{},[343,982,983],{},"reason","), and the call runs only if it is allowed, with the answer's input when it has one. The runtime closes stdin when the session's result is out.",[665,986,987],{},"Cancelling a job sends SIGTERM to the session's process group, then SIGKILL after ten seconds.",[326,989,990,991,994,995,998],{},"The messages are defined in ",[343,992,993],{},"proto\u002Foz0\u002Fharness\u002Fv1\u002Fharness.proto"," and written in their proto3 JSON form. A harness can be written in any language and tested with a pipe; ",[343,996,997],{},"node\u002Fruntime\u002Ftests\u002Ffake_harness.py"," in the repository is a complete example in about 50 lines, permission requests included.",[326,1000,1001],{},"One harness for the Agent Client Protocol (ACP) is planned for v1.1, in place of separate Codex, OpenCode and goose harnesses: it reaches them and Gemini CLI, Cline and others through one protocol, and sends their permission requests to your hooks and approvals.",[1003,1004,1005],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}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 .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":354,"searchDepth":403,"depth":403,"links":1007},[1008,1009,1010,1011],{"id":337,"depth":403,"text":338},{"id":659,"depth":403,"text":660},{"id":691,"depth":403,"text":692},{"id":836,"depth":403,"text":837},"Run a whole session of an existing agent harness, such as the Claude Agent SDK, as a job.","md",null,{},{"icon":147},{"title":144,"description":1012},"BprtbBVTLpL-9G9KRkzfSXSke_Q7HX2dYA6hY62g_vc",[1020,1022],{"title":139,"path":140,"stem":141,"description":1021,"icon":142,"children":-1},"Write a tool that reports on the machine it runs on, give it to an agent, and publish it.",{"title":149,"path":150,"stem":151,"description":1023,"icon":152,"children":-1},"A plugin that routes support tickets with typed decisions, a hook that holds risky refunds, and a gate that stops a worse version.",1791135410556]