[{"data":1,"prerenderedAt":1214},["ShallowReactive",2],{"navigation_docs":3,"-guides-write-your-own-chain":270,"-guides-write-your-own-chain-surround":1209},[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":91,"body":272,"description":1202,"extension":1203,"links":1204,"meta":1205,"navigation":1206,"path":92,"seo":1207,"stem":93,"__hash__":1208},"docs\u002F3.guides\u002F09.write-your-own-chain.md",{"type":273,"value":274,"toc":1191},"minimark",[275,288,298,303,335,339,349,461,485,489,500,664,738,742,745,773,790,838,847,851,895,926,930,933,963,969,999,1003,1025,1029,1038,1107,1118,1122,1128,1152,1178,1187],[276,277,278,279,283,284,287],"p",{},"This guide builds a chain of your own from the shipped ",[280,281,282],"code",{},"default"," chain. It adds\na ",[280,285,286],{},"lint"," node after verification. The node runs your linter as a command. When\nthe linter fails, an agent fixes what it reported and the linter runs again. A\njudge decides when more attempts are not worth it. The node has a time cap, and\nnobody can skip it.",[276,289,290,291,294,295,297],{},"For every key used here, see ",[292,293,184],"a",{"href":185}," and\n",[292,296,160],{"href":161},".",[299,300,302],"h2",{"id":301},"before-you-start","Before you start",[304,305,306,310,317],"ul",{},[307,308,309],"li",{},"A running Kraft server and a connected repo.",[307,311,312,313,316],{},"A lint command that exits 0 when the code is clean. This guide uses\n",[280,314,315],{},"npm run lint && npx tsc --noEmit",". Use your own.",[307,318,319,320,323,324,327,328,331,332,297],{},"Your config lives in ",[280,321,322],{},"$KRAFT_HOME\u002Ftemplates\u002F"," (",[280,325,326],{},"~\u002F.kraft\u002Ftemplates\u002F"," by\ndefault). You edit ",[280,329,330],{},"library.yaml"," and add a file under ",[280,333,334],{},"chains\u002F",[299,336,338],{"id":337},"_1-add-the-tasks-to-the-library","1. Add the tasks to the library",[276,340,341,342,344,345,348],{},"Add two tasks to ",[280,343,330],{},", under ",[280,346,347],{},"tasks:",". One runs the linter. The other\nis the agent that repairs what it reports.",[350,351,356],"pre",{"className":352,"code":353,"language":354,"meta":355,"style":355},"language-yaml shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","tasks:\n  lint:\n    kind: subprocess\n    command: sh -c 'npm run lint && npx tsc --noEmit'\n\n  repair_lint:\n    kind: agent\n    harness: claude\n    profile: strong\n    prompt: Fix the lint and type errors the lint step reported. Change no behavior.\n","yaml","",[280,357,358,371,379,392,403,410,418,428,439,450],{"__ignoreMap":355},[359,360,363,367],"span",{"class":361,"line":362},"line",1,[359,364,366],{"class":365},"swJcz","tasks",[359,368,370],{"class":369},"sMK4o",":\n",[359,372,374,377],{"class":361,"line":373},2,[359,375,376],{"class":365},"  lint",[359,378,370],{"class":369},[359,380,382,385,388],{"class":361,"line":381},3,[359,383,384],{"class":365},"    kind",[359,386,387],{"class":369},":",[359,389,391],{"class":390},"sfazB"," subprocess\n",[359,393,395,398,400],{"class":361,"line":394},4,[359,396,397],{"class":365},"    command",[359,399,387],{"class":369},[359,401,402],{"class":390}," sh -c 'npm run lint && npx tsc --noEmit'\n",[359,404,406],{"class":361,"line":405},5,[359,407,409],{"emptyLinePlaceholder":408},true,"\n",[359,411,413,416],{"class":361,"line":412},6,[359,414,415],{"class":365},"  repair_lint",[359,417,370],{"class":369},[359,419,421,423,425],{"class":361,"line":420},7,[359,422,384],{"class":365},[359,424,387],{"class":369},[359,426,427],{"class":390}," agent\n",[359,429,431,434,436],{"class":361,"line":430},8,[359,432,433],{"class":365},"    harness",[359,435,387],{"class":369},[359,437,438],{"class":390}," claude\n",[359,440,442,445,447],{"class":361,"line":441},9,[359,443,444],{"class":365},"    profile",[359,446,387],{"class":369},[359,448,449],{"class":390}," strong\n",[359,451,453,456,458],{"class":361,"line":452},10,[359,454,455],{"class":365},"    prompt",[359,457,387],{"class":369},[359,459,460],{"class":390}," Fix the lint and type errors the lint step reported. Change no behavior.\n",[276,462,463,464,467,468,471,472,475,476,479,480,294,482,297],{},"Kraft does not run ",[280,465,466],{},"command"," through a shell, so ",[280,469,470],{},"&&"," and pipes need the\n",[280,473,474],{},"sh -c '...'"," wrapper above. Inside a fix loop, Kraft replaces the repair\ntask's ",[280,477,478],{},"prompt"," with its own instruction: which tasks failed and what they\nreported. See ",[292,481,190],{"href":191},[292,483,194],{"href":484},"\u002Freference\u002Fchain-nodes\u002Ffix-loop#what-a-repair-task-is-told",[299,486,488],{"id":487},"_2-add-the-node-to-the-library","2. Add the node to the library",[276,490,491,492,494,495,344,497,387],{},"Add a ",[280,493,286],{}," node to ",[280,496,330],{},[280,498,499],{},"nodes:",[350,501,503],{"className":352,"code":502,"language":354,"meta":355,"style":355},"nodes:\n  lint:\n    kind: exec\n    skippable: false\n    policy:\n      time_cap_minutes: 30\n    tasks:\n      - id: lint\n        extends: lint\n    fix_loop:\n      tasks:\n        - id: repair\n          extends: repair_lint\n      judge:\n        id: judge\n        extends: strict_judge\n      max_attempts: 3\n",[280,504,505,512,518,527,538,545,556,563,576,585,592,600,613,624,632,643,653],{"__ignoreMap":355},[359,506,507,510],{"class":361,"line":362},[359,508,509],{"class":365},"nodes",[359,511,370],{"class":369},[359,513,514,516],{"class":361,"line":373},[359,515,376],{"class":365},[359,517,370],{"class":369},[359,519,520,522,524],{"class":361,"line":381},[359,521,384],{"class":365},[359,523,387],{"class":369},[359,525,526],{"class":390}," exec\n",[359,528,529,532,534],{"class":361,"line":394},[359,530,531],{"class":365},"    skippable",[359,533,387],{"class":369},[359,535,537],{"class":536},"sfNiH"," false\n",[359,539,540,543],{"class":361,"line":405},[359,541,542],{"class":365},"    policy",[359,544,370],{"class":369},[359,546,547,550,552],{"class":361,"line":412},[359,548,549],{"class":365},"      time_cap_minutes",[359,551,387],{"class":369},[359,553,555],{"class":554},"sbssI"," 30\n",[359,557,558,561],{"class":361,"line":420},[359,559,560],{"class":365},"    tasks",[359,562,370],{"class":369},[359,564,565,568,571,573],{"class":361,"line":430},[359,566,567],{"class":369},"      -",[359,569,570],{"class":365}," id",[359,572,387],{"class":369},[359,574,575],{"class":390}," lint\n",[359,577,578,581,583],{"class":361,"line":441},[359,579,580],{"class":365},"        extends",[359,582,387],{"class":369},[359,584,575],{"class":390},[359,586,587,590],{"class":361,"line":452},[359,588,589],{"class":365},"    fix_loop",[359,591,370],{"class":369},[359,593,595,598],{"class":361,"line":594},11,[359,596,597],{"class":365},"      tasks",[359,599,370],{"class":369},[359,601,603,606,608,610],{"class":361,"line":602},12,[359,604,605],{"class":369},"        -",[359,607,570],{"class":365},[359,609,387],{"class":369},[359,611,612],{"class":390}," repair\n",[359,614,616,619,621],{"class":361,"line":615},13,[359,617,618],{"class":365},"          extends",[359,620,387],{"class":369},[359,622,623],{"class":390}," repair_lint\n",[359,625,627,630],{"class":361,"line":626},14,[359,628,629],{"class":365},"      judge",[359,631,370],{"class":369},[359,633,635,638,640],{"class":361,"line":634},15,[359,636,637],{"class":365},"        id",[359,639,387],{"class":369},[359,641,642],{"class":390}," judge\n",[359,644,646,648,650],{"class":361,"line":645},16,[359,647,580],{"class":365},[359,649,387],{"class":369},[359,651,652],{"class":390}," strict_judge\n",[359,654,656,659,661],{"class":361,"line":655},17,[359,657,658],{"class":365},"      max_attempts",[359,660,387],{"class":369},[359,662,663],{"class":554}," 3\n",[304,665,666,679,689,716],{},[307,667,668,671,672,675,676,297],{},[280,669,670],{},"skippable: false"," refuses ",[280,673,674],{},"kraft item skip"," on this node, a chain revision\nthat proposes skipping it, and ",[280,677,678],{},"kraft item create --skip-nodes lint",[307,680,681,684,685,297],{},[280,682,683],{},"policy.time_cap_minutes: 30"," caps the node's running time, fix loop\nincluded. Hitting it stops the item for you. It is never treated as a lint\nfailure, so no repair attempt is spent on it. See\n",[292,686,688],{"href":687},"\u002Fconcepts\u002Fcaps-and-budgets#time-caps","Time caps",[307,690,691,694,695,698,699,703,704,323,707,709,710,713,714,297],{},[280,692,693],{},"fix_loop.tasks"," runs after a failing lint, then the lint runs again. The loop\nrepeats until lint passes or ",[280,696,697],{},"max_attempts"," runs out. Then the node is stuck:\nan automatic ",[292,700,702],{"href":701},"\u002Fconcepts\u002Fhow-a-work-item-runs#inside-a-node","escalation"," turn\ntries first, then the item stops for you. The loop's wall clock comes from ",[280,705,706],{},"policy.yaml",[280,708,282],{},", or\n",[280,711,712],{},"loops.lint.fix_loop","). See ",[292,715,156],{"href":157},[307,717,718,721,722,725,726,729,730,733,734,297],{},[280,719,720],{},"judge"," is optional. ",[280,723,724],{},"strict_judge"," is the shipped judge task, the one\n",[280,727,728],{},"verification"," uses. It runs before each repair cycle after the first, and\ncan stop the loop. Its ",[280,731,732],{},"stop_downgrade"," verdict never lets a failing lint\ncommand through. See ",[292,735,737],{"href":736},"\u002Freference\u002Fchain-nodes\u002Ffix-loop#the-judge","The judge",[299,739,741],{"id":740},"_3-make-the-chain","3. Make the chain",[276,743,744],{},"Copy the default chain and give the copy its own id:",[350,746,750],{"className":747,"code":748,"language":749,"meta":355,"style":355},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","cd ~\u002F.kraft\u002Ftemplates\ncp chains\u002Fdefault.yaml chains\u002Fwith-lint.yaml\n","bash",[280,751,752,761],{"__ignoreMap":355},[359,753,754,758],{"class":361,"line":362},[359,755,757],{"class":756},"s2Zo4","cd",[359,759,760],{"class":390}," ~\u002F.kraft\u002Ftemplates\n",[359,762,763,767,770],{"class":361,"line":373},[359,764,766],{"class":765},"sBMFI","cp",[359,768,769],{"class":390}," chains\u002Fdefault.yaml",[359,771,772],{"class":390}," chains\u002Fwith-lint.yaml\n",[276,774,775,776,779,780,783,784,787,788,387],{},"In ",[280,777,778],{},"chains\u002Fwith-lint.yaml",", change ",[280,781,782],{},"id: default"," to ",[280,785,786],{},"id: with-lint",". Then add\nthe node right after ",[280,789,728],{},[350,791,793],{"className":352,"code":792,"language":354,"meta":355,"style":355},"  - id: verification\n    extends: verification\n\n  - id: lint\n    extends: lint\n",[280,794,795,807,816,820,830],{"__ignoreMap":355},[359,796,797,800,802,804],{"class":361,"line":362},[359,798,799],{"class":369},"  -",[359,801,570],{"class":365},[359,803,387],{"class":369},[359,805,806],{"class":390}," verification\n",[359,808,809,812,814],{"class":361,"line":373},[359,810,811],{"class":365},"    extends",[359,813,387],{"class":369},[359,815,806],{"class":390},[359,817,818],{"class":361,"line":381},[359,819,409],{"emptyLinePlaceholder":408},[359,821,822,824,826,828],{"class":361,"line":394},[359,823,799],{"class":369},[359,825,570],{"class":365},[359,827,387],{"class":369},[359,829,575],{"class":390},[359,831,832,834,836],{"class":361,"line":405},[359,833,811],{"class":365},[359,835,387],{"class":369},[359,837,575],{"class":390},[276,839,840,841,843,844,297],{},"A chain file cannot extend another chain, so the copy is a full copy. It no\nlonger follows changes to the shipped ",[280,842,282],{}," chain. See\n",[292,845,846],{"href":100},"Upgrading your templates",[299,848,850],{"id":849},"_4-check-it-and-load-it","4. Check it and load it",[350,852,854],{"className":747,"code":853,"language":749,"meta":355,"style":355},"kraft admin templates lint\nkraft admin templates show with-lint --resolved\nkraft admin reload\n",[280,855,856,869,886],{"__ignoreMap":355},[359,857,858,861,864,867],{"class":361,"line":362},[359,859,860],{"class":765},"kraft",[359,862,863],{"class":390}," admin",[359,865,866],{"class":390}," templates",[359,868,575],{"class":390},[359,870,871,873,875,877,880,883],{"class":361,"line":373},[359,872,860],{"class":765},[359,874,863],{"class":390},[359,876,866],{"class":390},[359,878,879],{"class":390}," show",[359,881,882],{"class":390}," with-lint",[359,884,885],{"class":390}," --resolved\n",[359,887,888,890,892],{"class":361,"line":381},[359,889,860],{"class":765},[359,891,863],{"class":390},[359,893,894],{"class":390}," reload\n",[276,896,897,899,900,903,904,907,908,910,911,914,915,918,919,921,922,925],{},[280,898,286],{}," must print ",[280,901,902],{},"no errors"," before you reload. ",[280,905,906],{},"show --resolved"," prints the\nchain with every library component expanded. Look for your ",[280,909,286],{}," node with\nits ",[280,912,913],{},"fix_loop",", its ",[280,916,917],{},"policy"," and ",[280,920,670],{},". ",[280,923,924],{},"reload"," makes the running\nserver read the files again, with no restart.",[299,927,929],{"id":928},"_5-use-it","5. Use it",[276,931,932],{},"Name the chain when you file work:",[350,934,936],{"className":747,"code":935,"language":749,"meta":355,"style":355},"kraft item create \"Add the export button\" --chain with-lint\n",[280,937,938],{"__ignoreMap":355},[359,939,940,942,945,948,951,954,957,960],{"class":361,"line":362},[359,941,860],{"class":765},[359,943,944],{"class":390}," item",[359,946,947],{"class":390}," create",[359,949,950],{"class":369}," \"",[359,952,953],{"class":390},"Add the export button",[359,955,956],{"class":369},"\"",[359,958,959],{"class":390}," --chain",[359,961,962],{"class":390}," with-lint\n",[276,964,965,968],{},[280,966,967],{},"kraft item set-chain ID --template with-lint"," switches an item that has not\nstarted yet.",[276,970,971,972,975,976,979,980,983,984,987,988,991,992,294,995,998],{},"To make it the repo's default instead, set ",[280,973,974],{},"default_chain_template: with-lint","\non the repo's entry in ",[280,977,978],{},"repos.yaml",". Every item filed on that repo without a\nchain then gets ",[280,981,982],{},"with-lint",": ",[280,985,986],{},"kraft item create",", the MCP tool, the board's\nNew work item dialog, ",[280,989,990],{},"POST \u002Fapi\u002Fwork-items",", ",[280,993,994],{},"POST \u002Fapi\u002Ftriggers",[292,996,997],{"href":173},"auto-intake",". Naming a chain still wins.",[299,1000,1002],{"id":1001},"how-the-lint-node-runs","How the lint node runs",[276,1004,1005,1006,1009,1010,1013,1014,1017,1018,1021,1022,1024],{},"The lint command runs in the item's worktree, with the worker's environment\nand ",[280,1007,1008],{},"KRAFT_RESULT_PATH",". Exit 0 is ",[280,1011,1012],{},"done",", anything else ",[280,1015,1016],{},"failed",", and a\nfailure becomes a ",[280,1019,1020],{},"critical"," finding holding the end of its output for the\nrepair agent. ",[292,1023,190],{"href":191}," has\nthe full contract.",[299,1026,1028],{"id":1027},"or-use-a-test-scope-instead","Or use a test scope instead",[276,1030,1031,1032,1035,1036,387],{},"If you only need lint to run when certain files change, you may not need a\nnode at all. Add the linter to the repo's ",[280,1033,1034],{},"test_scopes"," in ",[280,1037,978],{},[350,1039,1041],{"className":352,"code":1040,"language":354,"meta":355,"style":355},"test_scopes:\n  - paths: [\"src\u002F**\"]\n    command: npm test\n  - paths: [\"src\u002F**\u002F*.ts\"]\n    command: sh -c 'npm run lint && npx tsc --noEmit'\n",[280,1042,1043,1049,1071,1080,1099],{"__ignoreMap":355},[359,1044,1045,1047],{"class":361,"line":362},[359,1046,1034],{"class":365},[359,1048,370],{"class":369},[359,1050,1051,1053,1056,1058,1061,1063,1066,1068],{"class":361,"line":373},[359,1052,799],{"class":369},[359,1054,1055],{"class":365}," paths",[359,1057,387],{"class":369},[359,1059,1060],{"class":369}," [",[359,1062,956],{"class":369},[359,1064,1065],{"class":390},"src\u002F**",[359,1067,956],{"class":369},[359,1069,1070],{"class":369},"]\n",[359,1072,1073,1075,1077],{"class":361,"line":381},[359,1074,397],{"class":365},[359,1076,387],{"class":369},[359,1078,1079],{"class":390}," npm test\n",[359,1081,1082,1084,1086,1088,1090,1092,1095,1097],{"class":361,"line":394},[359,1083,799],{"class":369},[359,1085,1055],{"class":365},[359,1087,387],{"class":369},[359,1089,1060],{"class":369},[359,1091,956],{"class":369},[359,1093,1094],{"class":390},"src\u002F**\u002F*.ts",[359,1096,956],{"class":369},[359,1098,1070],{"class":369},[359,1100,1101,1103,1105],{"class":361,"line":405},[359,1102,397],{"class":365},[359,1104,387],{"class":369},[359,1106,402],{"class":390},[276,1108,1109,1110,1112,1113,1115,1116,297],{},"The shipped ",[280,1111,728],{}," node runs every scope whose paths the change\ntouches, and its existing fix loop repairs the failures. A scope's ",[280,1114,466],{}," is\nsplit the same way, with no shell. See ",[292,1117,146],{"href":147},[299,1119,1121],{"id":1120},"verify","Verify",[276,1123,1124,1125,1127],{},"File a small item on the new chain. Once it passes ",[280,1126,728],{},", watch the\nlint node run:",[350,1129,1131],{"className":747,"code":1130,"language":749,"meta":355,"style":355},"kraft view events ID --type findings_measured\n",[280,1132,1133],{"__ignoreMap":355},[359,1134,1135,1137,1140,1143,1146,1149],{"class":361,"line":362},[359,1136,860],{"class":765},[359,1138,1139],{"class":390}," view",[359,1141,1142],{"class":390}," events",[359,1144,1145],{"class":390}," ID",[359,1147,1148],{"class":390}," --type",[359,1150,1151],{"class":390}," findings_measured\n",[276,1153,1154,1155,1158,1159,1161,1162,1164,1165,1168,1169,1171,1172,1175,1176,297],{},"A failing lint shows a ",[280,1156,1157],{},"findings_measured"," event for node ",[280,1160,286],{}," with one\n",[280,1163,1020],{}," finding, then a ",[280,1166,1167],{},"fix_cycle_started"," event. A clean lint shows a\n",[280,1170,1157],{}," event with no findings, then ",[280,1173,1174],{},"node_completed"," for ",[280,1177,286],{},[276,1179,1180,1183,1184,297],{},[280,1181,1182],{},"kraft item skip ID"," on the lint node answers\n",[280,1185,1186],{},"path: 'lint' does not allow skipping",[1188,1189,1190],"style",{},"html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":355,"searchDepth":373,"depth":373,"links":1192},[1193,1194,1195,1196,1197,1198,1199,1200,1201],{"id":301,"depth":373,"text":302},{"id":337,"depth":373,"text":338},{"id":487,"depth":373,"text":488},{"id":740,"depth":373,"text":741},{"id":849,"depth":373,"text":850},{"id":928,"depth":373,"text":929},{"id":1001,"depth":373,"text":1002},{"id":1027,"depth":373,"text":1028},{"id":1120,"depth":373,"text":1121},"Add a lint node to a copy of the default chain, with an agent that fixes what lint reports, a time cap, and no way to skip it.","md",null,{},{"title":91},{"title":91,"description":1202},"qQQQDsiDpEr6vs2wVSoxENxGNzY_oNkErtB_YBdRhGQ",[1210,1212],{"title":87,"path":88,"stem":89,"description":1211,"children":-1},"Comment on a Kraft work item at any point in its life, not only at a gate, and see your feedback reach the next agent that touches the code.",{"title":95,"path":96,"stem":97,"description":1213,"children":-1},"Run some or all of a chain's agent tasks on Codex, Cursor, OpenCode, Gemini or Amp instead of Claude Code, and what changes when you do.",1790824541482]