[{"data":1,"prerenderedAt":1009},["ShallowReactive",2],{"navigation_docs":3,"-reference-harnesses-harness-files":270,"-reference-harnesses-harness-files-surround":1004},[4,28,51,110,243],{"title":5,"path":6,"stem":7,"children":8},"Get started","\u002Fget-started","1.get-started",[9,12,16,20,24],{"title":10,"path":6,"stem":11},"Overview","1.get-started\u002Findex",{"title":13,"path":14,"stem":15},"Why Kraft","\u002Fget-started\u002Fwhy-kraft","1.get-started\u002F0.why-kraft",{"title":17,"path":18,"stem":19},"Install","\u002Fget-started\u002Finstall","1.get-started\u002F1.install",{"title":21,"path":22,"stem":23},"Your first work item","\u002Fget-started\u002Ffirst-work-item","1.get-started\u002F2.first-work-item",{"title":25,"path":26,"stem":27},"Troubleshooting and FAQ","\u002Fget-started\u002Ftroubleshooting","1.get-started\u002F3.troubleshooting",{"title":29,"path":30,"stem":31,"children":32},"Concepts","\u002Fconcepts","2.concepts",[33,35,39,43,47],{"title":10,"path":30,"stem":34},"2.concepts\u002Findex",{"title":36,"path":37,"stem":38},"Vocabulary","\u002Fconcepts\u002Fvocabulary","2.concepts\u002F1.vocabulary",{"title":40,"path":41,"stem":42},"How a work item runs","\u002Fconcepts\u002Fhow-a-work-item-runs","2.concepts\u002F2.how-a-work-item-runs",{"title":44,"path":45,"stem":46},"Caps and budgets","\u002Fconcepts\u002Fcaps-and-budgets","2.concepts\u002F3.caps-and-budgets",{"title":48,"path":49,"stem":50},"Why a permission gate","\u002Fconcepts\u002Fpermission-gate","2.concepts\u002F4.permission-gate",{"title":52,"path":53,"stem":54,"children":55},"Guides","\u002Fguides","3.guides",[56,58,62,66,70,74,78,82,86,90,94,98,102,106],{"title":10,"path":53,"stem":57},"3.guides\u002Findex",{"title":59,"path":60,"stem":61},"Use Kraft from your agent","\u002Fguides\u002Fagent-integration","3.guides\u002F01.agent-integration",{"title":63,"path":64,"stem":65},"Kraft Lite","\u002Fguides\u002Fkraft-lite","3.guides\u002F02.kraft-lite",{"title":67,"path":68,"stem":69},"Remote access","\u002Fguides\u002Fremote-access","3.guides\u002F03.remote-access",{"title":71,"path":72,"stem":73},"Add or override a harness","\u002Fguides\u002Fadding-a-harness","3.guides\u002F04.adding-a-harness",{"title":75,"path":76,"stem":77},"Schedule or webhook work","\u002Fguides\u002Fschedule-and-webhook-work","3.guides\u002F05.schedule-and-webhook-work",{"title":79,"path":80,"stem":81},"Add a security review or a gate reviewer","\u002Fguides\u002Fadd-review-agents","3.guides\u002F06.add-review-agents",{"title":83,"path":84,"stem":85},"Kraft for VS Code","\u002Fguides\u002Fvscode","3.guides\u002F07.vscode",{"title":87,"path":88,"stem":89},"Reviewing a change","\u002Fguides\u002Freview-a-change","3.guides\u002F08.review-a-change",{"title":91,"path":92,"stem":93},"Write your own chain","\u002Fguides\u002Fwrite-your-own-chain","3.guides\u002F09.write-your-own-chain",{"title":95,"path":96,"stem":97},"Switch a harness","\u002Fguides\u002Fswitch-harness","3.guides\u002F10.switch-harness",{"title":99,"path":100,"stem":101},"Upgrade your templates","\u002Fguides\u002Fupgrading-templates","3.guides\u002F11.upgrading-templates",{"title":103,"path":104,"stem":105},"Operations","\u002Fguides\u002Foperations","3.guides\u002F12.operations",{"title":107,"path":108,"stem":109},"Worker Kit","\u002Fguides\u002Fworker-kit","3.guides\u002F13.worker-kit",{"title":111,"path":112,"stem":113,"children":114},"Reference","\u002Freference","4.reference",[115,117,139,183,201,205,227,231,235,239],{"title":10,"path":112,"stem":116},"4.reference\u002Findex",{"title":118,"path":119,"stem":120,"children":121},"CLI","\u002Freference\u002Fcli","4.reference\u002F1.cli\u002Findex",[122,123,127,131,135],{"title":10,"path":119,"stem":120},{"title":124,"path":125,"stem":126},"Item verbs","\u002Freference\u002Fcli\u002Fitem","4.reference\u002F1.cli\u002F2.item",{"title":128,"path":129,"stem":130},"View verbs","\u002Freference\u002Fcli\u002Fview","4.reference\u002F1.cli\u002F3.view",{"title":132,"path":133,"stem":134},"Repo verbs","\u002Freference\u002Fcli\u002Frepo","4.reference\u002F1.cli\u002F4.repo",{"title":136,"path":137,"stem":138},"Admin verbs","\u002Freference\u002Fcli\u002Fadmin","4.reference\u002F1.cli\u002F5.admin",{"title":140,"path":141,"stem":142,"children":143},"Configuration","\u002Freference\u002Fconfiguration","4.reference\u002F2.configuration\u002Findex",[144,145,155,159,163,167,171,175,179],{"title":10,"path":141,"stem":142},{"title":146,"path":147,"stem":148,"children":149},"Repos","\u002Freference\u002Fconfiguration\u002Frepos","4.reference\u002F2.configuration\u002F2.repos\u002Findex",[150,151],{"title":10,"path":147,"stem":148},{"title":152,"path":153,"stem":154},"Workspaces","\u002Freference\u002Fconfiguration\u002Frepos\u002Fworkspaces","4.reference\u002F2.configuration\u002F2.repos\u002F3.workspaces",{"title":156,"path":157,"stem":158},"Policy","\u002Freference\u002Fconfiguration\u002Fpolicy","4.reference\u002F2.configuration\u002F3.policy",{"title":160,"path":161,"stem":162},"Library and chains","\u002Freference\u002Fconfiguration\u002Flibrary-and-chains","4.reference\u002F2.configuration\u002F4.library-and-chains",{"title":164,"path":165,"stem":166},"Harnesses file","\u002Freference\u002Fconfiguration\u002Fharnesses-file","4.reference\u002F2.configuration\u002F5.harnesses-file",{"title":168,"path":169,"stem":170},"Access","\u002Freference\u002Fconfiguration\u002Faccess","4.reference\u002F2.configuration\u002F6.access",{"title":172,"path":173,"stem":174},"Intake","\u002Freference\u002Fconfiguration\u002Fintake","4.reference\u002F2.configuration\u002F7.intake",{"title":176,"path":177,"stem":178},"Sandbox host","\u002Freference\u002Fconfiguration\u002Fsandbox","4.reference\u002F2.configuration\u002F8.sandbox",{"title":180,"path":181,"stem":182},"Environment variables","\u002Freference\u002Fconfiguration\u002Fenvironment-variables","4.reference\u002F2.configuration\u002F9.environment-variables",{"title":184,"path":185,"stem":186,"children":187},"Chain nodes","\u002Freference\u002Fchain-nodes","4.reference\u002F3.chain-nodes\u002Findex",[188,189,193,197],{"title":10,"path":185,"stem":186},{"title":190,"path":191,"stem":192},"Subprocess tasks","\u002Freference\u002Fchain-nodes\u002Fsubprocess-tasks","4.reference\u002F3.chain-nodes\u002F2.subprocess-tasks",{"title":194,"path":195,"stem":196},"Fix loop and judge","\u002Freference\u002Fchain-nodes\u002Ffix-loop","4.reference\u002F3.chain-nodes\u002F3.fix-loop",{"title":198,"path":199,"stem":200},"Result file","\u002Freference\u002Fchain-nodes\u002Fresult-file","4.reference\u002F3.chain-nodes\u002F4.result-file",{"title":202,"path":203,"stem":204},"Permission gate","\u002Freference\u002Fpermissions","4.reference\u002F4.permissions",{"title":206,"path":207,"stem":208,"children":209},"Agent harnesses","\u002Freference\u002Fharnesses","4.reference\u002F5.harnesses\u002Findex",[210,211,215,219,223],{"title":10,"path":207,"stem":208},{"title":212,"path":213,"stem":214},"Unattended runs","\u002Freference\u002Fharnesses\u002Funattended-runs","4.reference\u002F5.harnesses\u002F2.unattended-runs",{"title":216,"path":217,"stem":218},"Agent profiles","\u002Freference\u002Fharnesses\u002Fagent-profiles","4.reference\u002F5.harnesses\u002F3.agent-profiles",{"title":220,"path":221,"stem":222},"Harness files","\u002Freference\u002Fharnesses\u002Fharness-files","4.reference\u002F5.harnesses\u002F4.harness-files",{"title":224,"path":225,"stem":226},"Fallback and escalation","\u002Freference\u002Fharnesses\u002Ffallback-and-escalation","4.reference\u002F5.harnesses\u002F5.fallback-and-escalation",{"title":228,"path":229,"stem":230},"Inbound triggers","\u002Freference\u002Ftriggers","4.reference\u002F6.triggers",{"title":232,"path":233,"stem":234},"HTTP API","\u002Freference\u002Fhttp-api","4.reference\u002F7.http-api",{"title":236,"path":237,"stem":238},"MCP tools","\u002Freference\u002Fmcp-tools","4.reference\u002F8.mcp-tools",{"title":240,"path":241,"stem":242},"Events","\u002Freference\u002Fevents","4.reference\u002F9.events",{"title":244,"path":245,"stem":246,"children":247},"Project","\u002Fproject","5.project",[248,250,254,258,262,266],{"title":10,"path":245,"stem":249},"5.project\u002Findex",{"title":251,"path":252,"stem":253},"Architecture","\u002Fproject\u002Farchitecture","5.project\u002F1.architecture",{"title":255,"path":256,"stem":257},"Contributing","\u002Fproject\u002Fcontributing","5.project\u002F2.contributing",{"title":259,"path":260,"stem":261},"Security","\u002Fproject\u002Fsecurity","5.project\u002F3.security",{"title":263,"path":264,"stem":265},"Data and privacy","\u002Fproject\u002Fdata-and-privacy","5.project\u002F4.data-and-privacy",{"title":267,"path":268,"stem":269},"Status and support","\u002Fproject\u002Fstatus-and-support","5.project\u002F5.status-and-support",{"id":271,"title":220,"body":272,"description":997,"extension":998,"links":999,"meta":1000,"navigation":1001,"path":221,"seo":1002,"stem":222,"__hash__":1003},"docs\u002F4.reference\u002F5.harnesses\u002F4.harness-files.md",{"type":273,"value":274,"toc":987},"minimark",[275,288,293,402,447,451,777,806,810,842,846,925,929,935,973,977],[276,277,278,279,283,284,287],"p",{},"A harness is a YAML file that maps Kraft's capabilities onto one CLI's flags. A file in ",[280,281,282],"code",{},"$KRAFT_HOME\u002Ftemplates\u002Fharnesses\u002F"," with\nthe same name as a shipped harness overrides it, and a file with a new name\nadds a harness. That directory is not seeded on first run, so it exists only\nonce you put a file in it. To write one, see\n",[285,286,71],"a",{"href":72},".",[289,290,292],"h2",{"id":291},"required-fields","Required fields",[294,295,296,309],"table",{},[297,298,299],"thead",{},[300,301,302,306],"tr",{},[303,304,305],"th",{},"Field",[303,307,308],{},"Meaning",[310,311,312,323,335,348,362,383],"tbody",{},[300,313,314,320],{},[315,316,317],"td",{},[280,318,319],{},"id",[315,321,322],{},"Must match the file name's stem.",[300,324,325,330],{},[315,326,327],{},[280,328,329],{},"kind",[315,331,332,287],{},[280,333,334],{},"cli",[300,336,337,342],{},[315,338,339],{},[280,340,341],{},"command",[315,343,344,345,287],{},"The argv prefix, such as ",[280,346,347],{},"[mytool]",[300,349,350,355],{},[315,351,352],{},[280,353,354],{},"capabilities.prompt",[315,356,357,358,361],{},"Required. A ",[280,359,360],{},"cli:"," argv fragment.",[300,363,364,369],{},[315,365,366],{},[280,367,368],{},"capabilities.context",[315,370,371,372,375,376,379,380,382],{},"Required. ",[280,373,374],{},"channel: prompt",", or ",[280,377,378],{},"channel: system_prompt"," with a ",[280,381,360],{}," fragment.",[300,384,385,390],{},[315,386,387],{},[280,388,389],{},"capabilities.usage",[315,391,371,392,375,395,398,399,287],{},[280,393,394],{},"source: result_file",[280,396,397],{},"source: envelope"," with the name of a ",[280,400,401],{},"reader:",[276,403,404,405,408,409,408,412,408,415,418,419,408,422,408,425,408,428,408,431,418,434,408,437,408,440,408,443,446],{},"Every other capability (",[280,406,407],{},"model",", ",[280,410,411],{},"effort",[280,413,414],{},"permission_mode",[280,416,417],{},"deny_tools",",\n",[280,420,421],{},"allowed_tools",[280,423,424],{},"restrict_tools",[280,426,427],{},"approval_channel",[280,429,430],{},"resume",[280,432,433],{},"autocompact",[280,435,436],{},"structured_log",[280,438,439],{},"rate_limit_signal",[280,441,442],{},"writable_dirs",[280,444,445],{},"mcp_config",") is optional. A binding\nthat names a capability the file omits is rejected at load, pointing at the\nfile.",[289,448,450],{"id":449},"optional-top-level-keys","Optional top-level keys",[294,452,453,462],{},[297,454,455],{},[300,456,457,460],{},[303,458,459],{},"Key",[303,461,308],{},[310,463,464,482,503,516,530,549,566,589,609,705,744],{},[300,465,466,471],{},[315,467,468],{},[280,469,470],{},"command_resume",[315,472,473,474,476,477,481],{},"The argv prefix for a resume, when it differs from ",[280,475,341],{}," (see ",[285,478,480],{"href":479},"#constraints-and-alternate-bindings","below",").",[300,483,484,489],{},[315,485,486],{},[280,487,488],{},"permission_hook",[315,490,491,492,495,496,499,500,287],{},"The translator (",[280,493,494],{},"cursor"," or ",[280,497,498],{},"codex",") for a capability bound ",[280,501,502],{},"via: permission_hook",[300,504,505,510],{},[315,506,507],{},[280,508,509],{},"tool_names",[315,511,512,513,481],{},"Maps the CLI's tool names to Kraft's (",[280,514,515],{},"Shell: Bash",[300,517,518,523],{},[315,519,520],{},[280,521,522],{},"unhooked_tools",[315,524,525,526,529],{},"Kraft tool names that never reach the hook (",[280,527,528],{},"[WebFetch, WebSearch]","). A launch whose policy would have to deny one is refused.",[300,531,532,537],{},[315,533,534],{},[280,535,536],{},"permission_rules",[315,538,539,540,495,543,499,546,287],{},"The renderer (",[280,541,542],{},"opencode",[280,544,545],{},"amp",[280,547,548],{},"via: permission_rules",[300,550,551,556],{},[315,552,553],{},[280,554,555],{},"config_dir",[315,557,558,559,562,563,481],{},"The CLI's config-directory variable (",[280,560,561],{},"env:",") and the JSON files Kraft writes into that directory before each launch (",[280,564,565],{},"files:",[300,567,568,573],{},[315,569,570],{},[280,571,572],{},"network.requires",[315,574,575,576,579,580,583,584,588],{},"The hosts the CLI itself reaches (",[280,577,578],{},"[api.anthropic.com]","), added to the ",[280,581,582],{},"runtime"," allow list of a sandbox with a ",[285,585,587],{"href":586},"\u002Freference\u002Fconfiguration\u002Frepos#network-policy","network policy",". Checked as network-policy hosts when the file loads.",[300,590,591,596],{},[315,592,593],{},[280,594,595],{},"proxy_aware",[315,597,598,601,602,605,606,287],{},[280,599,600],{},"false"," for a CLI that ignores ",[280,603,604],{},"HTTP(S)_PROXY",". Under a network policy its only route is Kraft's proxy, so such a harness is refused before launch. Default ",[280,607,608],{},"true",[300,610,611,616],{},[315,612,613],{},[280,614,615],{},"credentials",[315,617,618,619,408,622,625,626,629,630,633,634,408,637,640,641,644,645,648,649,651,652,654,655,658,659,662,663,669,670,644,673,676,677,644,679,682,683,644,686,689,690,693,694,644,697,700,701,704],{},"How Kraft's egress proxy can hold each credential the CLI reads: ",[280,620,621],{},"env",[280,623,624],{},"service",", the ",[280,627,628],{},"sentinel"," the container sees instead (shaped like a real key where the CLI may check), and ",[280,631,632],{},"inject",", a list of ",[280,635,636],{},"domain",[280,638,639],{},"header"," and optional ",[280,642,643],{},"format"," (",[280,646,647],{},"Bearer %s","). Each ",[280,650,636],{}," must be one of ",[280,653,572],{},". ",[280,656,657],{},"phase"," and ",[280,660,661],{},"source"," are a repository's to set, and refused here. Used only for a variable a repository lists under ",[285,664,666],{"href":665},"\u002Freference\u002Fconfiguration\u002Frepos#credentials",[280,667,668],{},"sandbox.credentials",". The shipped ",[280,671,672],{},"claude",[280,674,675],{},"ANTHROPIC_API_KEY",", Claude Code 2.1.284), ",[280,678,498],{},[280,680,681],{},"CODEX_API_KEY",", codex-cli 0.158.0) and ",[280,684,685],{},"gemini",[280,687,688],{},"GEMINI_API_KEY",", Gemini CLI 0.61.0) declarations are verified by ",[280,691,692],{},"e2e(\u003Ccli>)"," in ",[280,695,696],{},"tests\u002Fworker\u002Ftest_credentials_docker.py",[280,698,699],{},"KRAFT_E2E=1","); claude's ",[280,702,703],{},"CLAUDE_CODE_OAUTH_TOKEN"," is not.",[300,706,707,712],{},[315,708,709],{},[280,710,711],{},"min_version",[315,713,714,715,718,719,722,723,725,726,729,730,733,734,658,737,740,741,287],{},"The oldest release (",[280,716,717],{},"N.N.N",") of the CLI this file's argv works with. Each launch runs ",[280,720,721],{},"\u003Ccommand> --version"," (in the image, when sandboxed) and refuses an older one by name; an answer with no version in it lets the launch go ahead. The shipped ",[280,724,542],{}," needs ",[280,727,728],{},"2.0.0",": npm's ",[280,731,732],{},"opencode-ai"," 1.x refuses ",[280,735,736],{},"--standalone",[280,738,739],{},"--log-level error",", so install 2.x from opencode.ai or Homebrew's ",[280,742,743],{},"anomalyco\u002Ftap\u002Fopencode-v2",[300,745,746,751],{},[315,747,748],{},[280,749,750],{},"container_permission_mode",[315,752,753,754,756,757,761,762,765,766,769,770,772,773,776],{},"The ",[280,755,414],{}," a launch gets under Kraft's ",[285,758,760],{"href":759},"\u002Freference\u002Fconfiguration\u002Frepos#sandboxed-workers","docker sandbox"," when nothing chose a mode other than the capability's ",[280,763,764],{},"always:",", for a CLI whose own sandbox cannot start inside a container (codex: ",[280,767,768],{},"danger-full-access","). Checked against ",[280,771,414],{},"'s ",[280,774,775],{},"values:"," when the file loads.",[276,778,753,779,781,782,495,785,787,788,408,791,408,794,418,797,408,800,495,803,287],{},[280,780,401],{}," in a ",[280,783,784],{},"usage",[280,786,439],{}," capability names one of\nKraft's log readers: ",[280,789,790],{},"claude-stream-json",[280,792,793],{},"codex-json",[280,795,796],{},"cursor-stream-json",[280,798,799],{},"opencode-json",[280,801,802],{},"amp-stream-json",[280,804,805],{},"antigravity-stream-json",[289,807,809],{"id":808},"argv-fragments-and-placeholders","Argv fragments and placeholders",[276,811,812,813,815,816,818,819,821,822,825,826,828,829,658,832,835,836,838,839,841],{},"A capability needs a ",[280,814,360],{}," argv fragment unless it is ",[280,817,784],{}," or\n",[280,820,439],{}," (read back out, not invoked) or ",[280,823,824],{},"context"," with\n",[280,827,374],{}," (folded into the prompt text). ",[280,830,831],{},"{value}",[280,833,834],{},"{csv}"," are the\nwhole placeholder language: ",[280,837,831],{}," is one substituted string and ",[280,840,834],{}," a\ncomma-joined list.",[289,843,845],{"id":844},"constraints-and-alternate-bindings","Constraints and alternate bindings",[847,848,849,859,867,886,910],"ul",{},[850,851,852,854,855,858],"li",{},[280,853,775],{}," is a list of ",[280,856,857],{},"re.fullmatch"," patterns. A value outside them fails at\nload, not at launch.",[850,860,861,863,864,866],{},[280,862,764],{}," is the value Kraft uses when a binding supplies none. For a list\ncapability, it is merged with what a binding supplies. It is checked against\n",[280,865,775],{}," too.",[850,868,869,871,872,875,876,878,879,882,883,287],{},[280,870,430],{}," can bind ",[280,873,874],{},"via: command_resume"," instead of ",[280,877,360],{},", when a resume\nneeds its own command prefix. ",[280,880,881],{},"codex.yaml"," uses\n",[280,884,885],{},"command_resume: [codex, exec, resume, \"{value}\"]",[850,887,888,658,890,871,892,894,895,898,899,495,901,903,904,907,908,481],{},[280,889,417],{},[280,891,421],{},[280,893,502],{},": no flag,\nthe tool lists enforced by Kraft's pre-tool hook. This needs a top-level\n",[280,896,897],{},"permission_hook:"," naming the translator (",[280,900,494],{},[280,902,498],{},"), and\n",[280,905,906],{},"tool_names:"," mapping the CLI's tool names to Kraft's (",[280,909,515],{},[850,911,912,913,915,916,919,920,818,922,924],{},"The same two capabilities can bind ",[280,914,548],{},", for a CLI with no\nhook. A top-level ",[280,917,918],{},"permission_rules:"," names the renderer (",[280,921,542],{},[280,923,545],{},") that writes the tool lists into the CLI's own permission config at\nlaunch. A policy name that no CLI tool maps to refuses the launch.",[289,926,928],{"id":927},"allowlists","Allowlists",[276,930,931,932,934],{},"A launch whose policy sets ",[280,933,421],{}," (an empty list included) must not\nlet a tool outside the list run. A harness meets that in one of three ways:",[847,936,937,961,967],{},[850,938,939,940,942,943,946,947,949,950,953,954,957,958,960],{},"It declares ",[280,941,424],{}," (the CLI's own flag for which built-in tools\nexist, such as Claude's ",[280,944,945],{},"--tools",") and a ",[280,948,414],{}," with an\n",[280,951,952],{},"under_allowlist:"," mode that asks the approval channel about everything else\n(Claude's ",[280,955,956],{},"manual","). A harness missing either refuses to launch under an\nallowlist, and so does a launch whose own ",[280,959,414],{}," differs from that\nmode.",[850,962,963,964,966],{},"It has a ",[280,965,488],{},", which denies every tool the list doesn't name,\nfail-closed.",[850,968,969,970,972],{},"It has ",[280,971,536],{},", which deny every tool the list doesn't name.",[289,974,976],{"id":975},"checking-harness-files","Checking harness files",[276,978,979,982,983,986],{},[280,980,981],{},"kraft admin doctor"," runs one ",[280,984,985],{},"PATH"," check per harness profile that the live\nlibrary's chains select, not every declared one. It adds a failure row for any\nharness file that failed to load.",{"title":988,"searchDepth":989,"depth":989,"links":990},"",2,[991,992,993,994,995,996],{"id":291,"depth":989,"text":292},{"id":449,"depth":989,"text":450},{"id":808,"depth":989,"text":809},{"id":844,"depth":989,"text":845},{"id":927,"depth":989,"text":928},{"id":975,"depth":989,"text":976},"The YAML file that describes one harness: required fields, argv fragments, constraints, and allowlists.","md",null,{},true,{"title":220,"description":997},"JCczfw8kE1czPX9uIUrNkQut6JBoR__jHJCN9I2dtP8",[1005,1007],{"title":216,"path":217,"stem":218,"description":1006,"children":-1},"Named model tiers a task selects with profile: instead of model and effort.",{"title":224,"path":225,"stem":226,"description":1008,"children":-1},"Where a launch goes next when a harness is limited or unavailable, and which harness runs an escalation turn.",1790824510481]