[{"data":1,"prerenderedAt":1860},["ShallowReactive",2],{"navigation_docs":3,"-reference-configuration-repos-connect-proposals":520,"-reference-configuration-repos-connect-proposals-surround":1855},[4,28,51,191,222,485],{"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},"FAQ","\u002Fget-started\u002Ffaq","1.get-started\u002F3.faq",{"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},"How a work item runs","\u002Fconcepts\u002Fhow-a-work-item-runs","2.concepts\u002F1.how-a-work-item-runs",{"title":40,"path":41,"stem":42},"Caps and budgets","\u002Fconcepts\u002Fcaps-and-budgets","2.concepts\u002F2.caps-and-budgets",{"title":44,"path":45,"stem":46},"Why a permission gate","\u002Fconcepts\u002Fpermission-gate","2.concepts\u002F3.permission-gate",{"title":48,"path":49,"stem":50},"Vocabulary","\u002Fconcepts\u002Fvocabulary","2.concepts\u002F4.vocabulary",{"title":52,"path":53,"stem":54,"children":55},"Guides","\u002Fguides","3.guides",[56,58,96,117,138,187],{"title":10,"path":53,"stem":57},"3.guides\u002Findex",{"title":59,"path":60,"stem":61,"children":62,"page":95},"Day to day","\u002Fguides\u002Fday-to-day","3.guides\u002F1.day-to-day",[63,67,71,75,79,83,87,91],{"title":64,"path":65,"stem":66},"The setup wizard on first start","\u002Fguides\u002Fday-to-day\u002Ffirst-run","3.guides\u002F1.day-to-day\u002F2.first-run",{"title":68,"path":69,"stem":70},"File a work item","\u002Fguides\u002Fday-to-day\u002Ffile-a-work-item","3.guides\u002F1.day-to-day\u002F3.file-a-work-item",{"title":72,"path":73,"stem":74},"Use Kraft from your agent","\u002Fguides\u002Fday-to-day\u002Fagent-integration","3.guides\u002F1.day-to-day\u002F4.agent-integration",{"title":76,"path":77,"stem":78},"Reviewing a change","\u002Fguides\u002Fday-to-day\u002Freview-a-change","3.guides\u002F1.day-to-day\u002F5.review-a-change",{"title":80,"path":81,"stem":82},"Raise a cap on a stopped item","\u002Fguides\u002Fday-to-day\u002Fraise-a-cap","3.guides\u002F1.day-to-day\u002F6.raise-a-cap",{"title":84,"path":85,"stem":86},"Kraft for VS Code","\u002Fguides\u002Fday-to-day\u002Fvscode","3.guides\u002F1.day-to-day\u002F7.vscode",{"title":88,"path":89,"stem":90},"Kraft on a phone","\u002Fguides\u002Fday-to-day\u002Fkraft-on-a-phone","3.guides\u002F1.day-to-day\u002F8.kraft-on-a-phone",{"title":92,"path":93,"stem":94},"Get notified when an item needs you","\u002Fguides\u002Fday-to-day\u002Fnotifications","3.guides\u002F1.day-to-day\u002F9.notifications",false,{"title":97,"path":98,"stem":99,"children":100,"page":95},"Customize and automate","\u002Fguides\u002Fcustomize","3.guides\u002F2.customize",[101,105,109,113],{"title":102,"path":103,"stem":104},"Write your own chain","\u002Fguides\u002Fcustomize\u002Fwrite-your-own-chain","3.guides\u002F2.customize\u002F1.write-your-own-chain",{"title":106,"path":107,"stem":108},"Add a security review or a gate reviewer","\u002Fguides\u002Fcustomize\u002Fadd-review-agents","3.guides\u002F2.customize\u002F2.add-review-agents",{"title":110,"path":111,"stem":112},"Schedule or webhook work","\u002Fguides\u002Fcustomize\u002Fschedule-and-webhook-work","3.guides\u002F2.customize\u002F3.schedule-and-webhook-work",{"title":114,"path":115,"stem":116},"Share chains with add-ons","\u002Fguides\u002Fcustomize\u002Fshare-chains-with-addons","3.guides\u002F2.customize\u002F4.share-chains-with-addons",{"title":118,"path":119,"stem":120,"children":121,"page":95},"Agents and harnesses","\u002Fguides\u002Fharnesses","3.guides\u002F3.harnesses",[122,126,130,134],{"title":123,"path":124,"stem":125},"Switch a task to another harness","\u002Fguides\u002Fharnesses\u002Fswitch-harness","3.guides\u002F3.harnesses\u002F1.switch-harness",{"title":127,"path":128,"stem":129},"Add or override a harness","\u002Fguides\u002Fharnesses\u002Fadding-a-harness","3.guides\u002F3.harnesses\u002F2.adding-a-harness",{"title":131,"path":132,"stem":133},"Build a worker Kit","\u002Fguides\u002Fharnesses\u002Fworker-kit","3.guides\u002F3.harnesses\u002F3.worker-kit",{"title":135,"path":136,"stem":137},"Give a worker its login","\u002Fguides\u002Fharnesses\u002Fgive-a-worker-its-login","3.guides\u002F3.harnesses\u002F4.give-a-worker-its-login",{"title":139,"path":140,"stem":141,"children":142,"page":95},"Run the server","\u002Fguides\u002Frun","3.guides\u002F4.run",[143,147,151,155,159,163,167,171,175,179,183],{"title":144,"path":145,"stem":146},"Remote access","\u002Fguides\u002Frun\u002Fremote-access","3.guides\u002F4.run\u002F01.remote-access",{"title":148,"path":149,"stem":150},"Put a proxy in front of Kraft","\u002Fguides\u002Frun\u002Fput-a-proxy-in-front-of-kraft","3.guides\u002F4.run\u002F02.put-a-proxy-in-front-of-kraft",{"title":152,"path":153,"stem":154},"Restart Kraft without ending running agents","\u002Fguides\u002Frun\u002Frestart-kraft","3.guides\u002F4.run\u002F03.restart-kraft",{"title":156,"path":157,"stem":158},"Back up and restore the database","\u002Fguides\u002Frun\u002Fback-up-and-restore","3.guides\u002F4.run\u002F04.back-up-and-restore",{"title":160,"path":161,"stem":162},"Logs and disk space","\u002Fguides\u002Frun\u002Flogs-and-disk-space","3.guides\u002F4.run\u002F05.logs-and-disk-space",{"title":164,"path":165,"stem":166},"Run Kraft as a service","\u002Fguides\u002Frun\u002Frun-as-a-service","3.guides\u002F4.run\u002F06.run-as-a-service",{"title":168,"path":169,"stem":170},"Upgrade Kraft","\u002Fguides\u002Frun\u002Fupgrade-kraft","3.guides\u002F4.run\u002F07.upgrade-kraft",{"title":172,"path":173,"stem":174},"Upgrade your configuration","\u002Fguides\u002Frun\u002Fupgrade-your-configuration","3.guides\u002F4.run\u002F08.upgrade-your-configuration",{"title":176,"path":177,"stem":178},"Upgrade from 1.4","\u002Fguides\u002Frun\u002Fupgrade-from-1-4","3.guides\u002F4.run\u002F09.upgrade-from-1-4",{"title":180,"path":181,"stem":182},"Upgrade from 0.x or a release candidate","\u002Fguides\u002Frun\u002Fupgrade-from-0-x-or-a-release-candidate","3.guides\u002F4.run\u002F10.upgrade-from-0-x-or-a-release-candidate",{"title":184,"path":185,"stem":186},"Roll back to 1.4","\u002Fguides\u002Frun\u002Froll-back","3.guides\u002F4.run\u002F11.roll-back",{"title":188,"path":189,"stem":190},"Kraft Lite","\u002Fguides\u002Fkraft-lite","3.guides\u002F5.kraft-lite",{"title":192,"path":193,"stem":194,"children":195},"Troubleshooting","\u002Ftroubleshooting","4.troubleshooting",[196,198,202,206,210,214,218],{"title":10,"path":193,"stem":197},"4.troubleshooting\u002Findex",{"title":199,"path":200,"stem":201},"Why did my item stop?","\u002Ftroubleshooting\u002Fwhy-did-my-item-stop","4.troubleshooting\u002F1.why-did-my-item-stop",{"title":203,"path":204,"stem":205},"Stop reasons in detail","\u002Ftroubleshooting\u002Fstop-reasons-in-detail","4.troubleshooting\u002F2.stop-reasons-in-detail",{"title":207,"path":208,"stem":209},"Starting and reaching Kraft","\u002Ftroubleshooting\u002Fstarting-and-reaching-kraft","4.troubleshooting\u002F3.starting-and-reaching-kraft",{"title":211,"path":212,"stem":213},"Doctor failures","\u002Ftroubleshooting\u002Fdoctor-failures","4.troubleshooting\u002F4.doctor-failures",{"title":215,"path":216,"stem":217},"Sandbox and Kit stops","\u002Ftroubleshooting\u002Fsandbox-and-kit-stops","4.troubleshooting\u002F5.sandbox-and-kit-stops",{"title":219,"path":220,"stem":221},"Add-on problems","\u002Ftroubleshooting\u002Faddon-problems","4.troubleshooting\u002F6.addon-problems",{"title":223,"path":224,"stem":225,"children":226},"Reference","\u002Freference","5.reference",[227,229,267,289,293,391,409,435,439,443,477,481],{"title":10,"path":224,"stem":228},"5.reference\u002Findex",{"title":230,"path":231,"stem":232,"children":233},"Web UI","\u002Freference\u002Fweb-ui","5.reference\u002F00.web-ui\u002Findex",[234,235,239,243,247,251,255,259,263],{"title":10,"path":231,"stem":232},{"title":236,"path":237,"stem":238},"Sidebar, search, and keyboard","\u002Freference\u002Fweb-ui\u002Fsidebar-search-and-keyboard","5.reference\u002F00.web-ui\u002F0.sidebar-search-and-keyboard",{"title":240,"path":241,"stem":242},"The board","\u002Freference\u002Fweb-ui\u002Fboard","5.reference\u002F00.web-ui\u002F1.board",{"title":244,"path":245,"stem":246},"An item's page","\u002Freference\u002Fweb-ui\u002Fitem-page","5.reference\u002F00.web-ui\u002F2.item-page",{"title":248,"path":249,"stem":250},"Fix loops and test scopes","\u002Freference\u002Fweb-ui\u002Ffix-loops-and-test-scopes","5.reference\u002F00.web-ui\u002F3.fix-loops-and-test-scopes",{"title":252,"path":253,"stem":254},"Config before an item starts","\u002Freference\u002Fweb-ui\u002Fconfig-before-start","5.reference\u002F00.web-ui\u002F4.config-before-start",{"title":256,"path":257,"stem":258},"The review page","\u002Freference\u002Fweb-ui\u002Freview-page","5.reference\u002F00.web-ui\u002F5.review-page",{"title":260,"path":261,"stem":262},"Templates and Settings","\u002Freference\u002Fweb-ui\u002Ftemplates-and-settings","5.reference\u002F00.web-ui\u002F6.templates-and-settings",{"title":264,"path":265,"stem":266},"Analytics","\u002Freference\u002Fweb-ui\u002Fanalytics","5.reference\u002F00.web-ui\u002F7.analytics",{"title":268,"path":269,"stem":270,"children":271},"CLI","\u002Freference\u002Fcli","5.reference\u002F01.cli\u002Findex",[272,273,277,281,285],{"title":10,"path":269,"stem":270},{"title":274,"path":275,"stem":276},"Item verbs","\u002Freference\u002Fcli\u002Fitem","5.reference\u002F01.cli\u002F2.item",{"title":278,"path":279,"stem":280},"View verbs","\u002Freference\u002Fcli\u002Fview","5.reference\u002F01.cli\u002F3.view",{"title":282,"path":283,"stem":284},"Repo verbs","\u002Freference\u002Fcli\u002Frepo","5.reference\u002F01.cli\u002F4.repo",{"title":286,"path":287,"stem":288},"Admin verbs","\u002Freference\u002Fcli\u002Fadmin","5.reference\u002F01.cli\u002F5.admin",{"title":290,"path":291,"stem":292},"Work item statuses","\u002Freference\u002Fstatuses","5.reference\u002F02.statuses",{"title":294,"path":295,"stem":296,"children":297},"Configuration","\u002Freference\u002Fconfiguration","5.reference\u002F03.configuration\u002Findex",[298,299,317,321,325,329,333,337,341,345,379,383,387],{"title":10,"path":295,"stem":296},{"title":300,"path":301,"stem":302,"children":303},"repos.yaml","\u002Freference\u002Fconfiguration\u002Frepos","5.reference\u002F03.configuration\u002F02.repos\u002Findex",[304,305,309,313],{"title":10,"path":301,"stem":302},{"title":306,"path":307,"stem":308},"How connect proposes commands","\u002Freference\u002Fconfiguration\u002Frepos\u002Fconnect-proposals","5.reference\u002F03.configuration\u002F02.repos\u002F1.connect-proposals",{"title":310,"path":311,"stem":312},"detectors.yaml","\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors","5.reference\u002F03.configuration\u002F02.repos\u002F2.detectors",{"title":314,"path":315,"stem":316},"Workspaces","\u002Freference\u002Fconfiguration\u002Frepos\u002Fworkspaces","5.reference\u002F03.configuration\u002F02.repos\u002F3.workspaces",{"title":318,"path":319,"stem":320},"policy.yaml","\u002Freference\u002Fconfiguration\u002Fpolicy","5.reference\u002F03.configuration\u002F03.policy",{"title":322,"path":323,"stem":324},"Library and chains","\u002Freference\u002Fconfiguration\u002Flibrary-and-chains","5.reference\u002F03.configuration\u002F04.library-and-chains",{"title":326,"path":327,"stem":328},"harnesses.yaml","\u002Freference\u002Fconfiguration\u002Fharnesses-file","5.reference\u002F03.configuration\u002F05.harnesses-file",{"title":330,"path":331,"stem":332},"access.yaml","\u002Freference\u002Fconfiguration\u002Faccess","5.reference\u002F03.configuration\u002F06.access",{"title":334,"path":335,"stem":336},"intake.yaml","\u002Freference\u002Fconfiguration\u002Fintake","5.reference\u002F03.configuration\u002F07.intake",{"title":338,"path":339,"stem":340},"notify.yaml","\u002Freference\u002Fconfiguration\u002Fnotify","5.reference\u002F03.configuration\u002F08.notify",{"title":342,"path":343,"stem":344},"theme.yaml","\u002Freference\u002Fconfiguration\u002Ftheme","5.reference\u002F03.configuration\u002F09.theme",{"title":346,"path":347,"stem":348,"children":349},"Sandboxed workers","\u002Freference\u002Fconfiguration\u002Fsandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002Findex",[350,351,355,359,363,367,371,375],{"title":10,"path":347,"stem":348},{"title":352,"path":353,"stem":354},"Resource limits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fresource-limits","5.reference\u002F03.configuration\u002F10.sandbox\u002F1.resource-limits",{"title":356,"path":357,"stem":358},"Callbacks from a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcallbacks","5.reference\u002F03.configuration\u002F10.sandbox\u002F2.callbacks",{"title":360,"path":361,"stem":362},"Network policy","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fnetwork-policy","5.reference\u002F03.configuration\u002F10.sandbox\u002F3.network-policy",{"title":364,"path":365,"stem":366},"Credentials","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fcredentials","5.reference\u002F03.configuration\u002F10.sandbox\u002F4.credentials",{"title":368,"path":369,"stem":370},"Kits","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fkits","5.reference\u002F03.configuration\u002F10.sandbox\u002F5.kits",{"title":372,"path":373,"stem":374},"sandbox.yaml","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fsandbox-yaml","5.reference\u002F03.configuration\u002F10.sandbox\u002F6.sandbox-yaml",{"title":376,"path":377,"stem":378},"Git in a sandbox","\u002Freference\u002Fconfiguration\u002Fsandbox\u002Fgit-in-a-sandbox","5.reference\u002F03.configuration\u002F10.sandbox\u002F7.git-in-a-sandbox",{"title":380,"path":381,"stem":382},"Environment variables","\u002Freference\u002Fconfiguration\u002Fenvironment-variables","5.reference\u002F03.configuration\u002F11.environment-variables",{"title":384,"path":385,"stem":386},"Add-ons and collections","\u002Freference\u002Fconfiguration\u002Faddons","5.reference\u002F03.configuration\u002F12.addons",{"title":388,"path":389,"stem":390},"Repo libraries","\u002Freference\u002Fconfiguration\u002Frepo-libraries","5.reference\u002F03.configuration\u002F13.repo-libraries",{"title":392,"path":393,"stem":394,"children":395},"Chain file keys","\u002Freference\u002Fchain-nodes","5.reference\u002F04.chain-nodes\u002Findex",[396,397,401,405],{"title":10,"path":393,"stem":394},{"title":398,"path":399,"stem":400},"Subprocess tasks","\u002Freference\u002Fchain-nodes\u002Fsubprocess-tasks","5.reference\u002F04.chain-nodes\u002F2.subprocess-tasks",{"title":402,"path":403,"stem":404},"Fix loop and judge","\u002Freference\u002Fchain-nodes\u002Ffix-loop","5.reference\u002F04.chain-nodes\u002F3.fix-loop",{"title":406,"path":407,"stem":408},"Result file","\u002Freference\u002Fchain-nodes\u002Fresult-file","5.reference\u002F04.chain-nodes\u002F4.result-file",{"title":410,"path":411,"stem":412,"children":413},"Agent harnesses","\u002Freference\u002Fharnesses","5.reference\u002F05.harnesses\u002Findex",[414,415,419,423,427,431],{"title":10,"path":411,"stem":412},{"title":416,"path":417,"stem":418},"Unattended runs","\u002Freference\u002Fharnesses\u002Funattended-runs","5.reference\u002F05.harnesses\u002F2.unattended-runs",{"title":420,"path":421,"stem":422},"Agent profiles","\u002Freference\u002Fharnesses\u002Fagent-profiles","5.reference\u002F05.harnesses\u002F3.agent-profiles",{"title":424,"path":425,"stem":426},"Harness definition files","\u002Freference\u002Fharnesses\u002Fharness-files","5.reference\u002F05.harnesses\u002F4.harness-files",{"title":428,"path":429,"stem":430},"Fallback and escalation","\u002Freference\u002Fharnesses\u002Ffallback-and-escalation","5.reference\u002F05.harnesses\u002F5.fallback-and-escalation",{"title":432,"path":433,"stem":434},"Cost reporting","\u002Freference\u002Fharnesses\u002Fcost-reporting","5.reference\u002F05.harnesses\u002F6.cost-reporting",{"title":436,"path":437,"stem":438},"Permission gate","\u002Freference\u002Fpermissions","5.reference\u002F06.permissions",{"title":440,"path":441,"stem":442},"Inbound triggers","\u002Freference\u002Ftriggers","5.reference\u002F07.triggers",{"title":444,"path":445,"stem":446,"children":447},"HTTP API","\u002Freference\u002Fhttp-api","5.reference\u002F08.http-api\u002Findex",[448,449,453,457,461,465,469,473],{"title":10,"path":445,"stem":446},{"title":450,"path":451,"stem":452},"Filing, reading and changing work items","\u002Freference\u002Fhttp-api\u002Fwork-items","5.reference\u002F08.http-api\u002F2.work-items",{"title":454,"path":455,"stem":456},"Gates, run control, ending and retry","\u002Freference\u002Fhttp-api\u002Fgates-run-control-and-ending","5.reference\u002F08.http-api\u002F3.gates-run-control-and-ending",{"title":458,"path":459,"stem":460},"The work item object","\u002Freference\u002Fhttp-api\u002Fwork-item-object","5.reference\u002F08.http-api\u002F4.work-item-object",{"title":462,"path":463,"stem":464},"Budget, events, diff and documents","\u002Freference\u002Fhttp-api\u002Fbudget-and-events","5.reference\u002F08.http-api\u002F5.budget-and-events",{"title":466,"path":467,"stem":468},"Repos, chains, harnesses and the server","\u002Freference\u002Fhttp-api\u002Frepos-chains-harnesses-and-server","5.reference\u002F08.http-api\u002F6.repos-chains-harnesses-and-server",{"title":470,"path":471,"stem":472},"Drafts","\u002Freference\u002Fhttp-api\u002Fdrafts","5.reference\u002F08.http-api\u002F7.drafts",{"title":474,"path":475,"stem":476},"Ops for each draft area","\u002Freference\u002Fhttp-api\u002Fdraft-ops","5.reference\u002F08.http-api\u002F8.draft-ops",{"title":478,"path":479,"stem":480},"MCP tools","\u002Freference\u002Fmcp-tools","5.reference\u002F09.mcp-tools",{"title":482,"path":483,"stem":484},"Events","\u002Freference\u002Fevents","5.reference\u002F10.events",{"title":486,"path":487,"stem":488,"children":489},"Security and project","\u002Fproject","6.project",[490,492,496,500,504,508,512,516],{"title":10,"path":487,"stem":491},"6.project\u002Findex",{"title":493,"path":494,"stem":495},"Security","\u002Fproject\u002Fsecurity","6.project\u002F1.security",{"title":497,"path":498,"stem":499},"Data and privacy","\u002Fproject\u002Fdata-and-privacy","6.project\u002F2.data-and-privacy",{"title":501,"path":502,"stem":503},"What's new in 2.0","\u002Fproject\u002Fwhats-new","6.project\u002F3.whats-new",{"title":505,"path":506,"stem":507},"Status and support","\u002Fproject\u002Fstatus-and-support","6.project\u002F4.status-and-support",{"title":509,"path":510,"stem":511},"Architecture","\u002Fproject\u002Farchitecture","6.project\u002F5.architecture",{"title":513,"path":514,"stem":515},"Source map","\u002Fproject\u002Fsource-map","6.project\u002F6.source-map",{"title":517,"path":518,"stem":519},"Contributing","\u002Fproject\u002Fcontributing","6.project\u002F7.contributing",{"id":521,"title":306,"body":522,"description":1848,"extension":1849,"links":1850,"meta":1851,"navigation":1852,"path":307,"seo":1853,"stem":308,"__hash__":1854},"docs\u002F5.reference\u002F03.configuration\u002F02.repos\u002F1.connect-proposals.md",{"type":523,"value":524,"toc":1826},"minimark",[525,545,560,573,577,597,628,638,641,667,691,694,699,711,718,721,790,794,802,821,824,831,839,843,846,987,997,1001,1004,1129,1133,1136,1202,1231,1235,1262,1266,1274,1323,1327,1353,1363,1378,1396,1400,1422,1474,1477,1495,1498,1514,1518,1524,1546,1550,1560,1603,1616,1619,1653,1664,1673,1687,1699,1703,1706,1794,1798],[526,527,528,532,533,536,537,540,541,544],"p",{},[529,530,531],"code",{},"kraft repo connect"," proposes a ",[529,534,535],{},"setup_command"," and a ",[529,538,539],{},"test_command"," (and ",[529,542,543],{},"test_scopes"," for a repo with more than one project in it) by reading the repo's own files. It prints each command with the file it came from and lists what else it found.",[526,546,547,548,553,554,556,557,559],{},"The result is a proposal for you to check. Nothing at run time guesses: a ",[549,550,552],"a",{"href":551},"\u002Fconcepts\u002Fvocabulary#work-item","work item"," runs only what ",[529,555,300],{}," declares. To teach connect your own conventions, see ",[549,558,310],{"href":311},".",[526,561,562,563,567,568,572],{},"If connect proposed nothing or the wrong thing, start with ",[549,564,566],{"href":565},"#when-connect-finds-no-command","When connect finds no command"," and ",[549,569,571],{"href":570},"#choosing-something-else","Choosing something else",". The sections after them say how a proposal is made.",[574,575,566],"h2",{"id":576},"when-connect-finds-no-command",[526,578,579,580,582,583,589,590,593,594,596],{},"Connect says when it found no command. With no ",[529,581,539],{}," it saves the repo disabled (see ",[549,584,586],{"href":585},"\u002Freference\u002Fconfiguration\u002Frepos#enabled",[529,587,588],{},"enabled","). ",[529,591,592],{},"kraft admin doctor"," reports any connected repo still missing a ",[529,595,535],{},". Either:",[598,599,600,622],"ul",{},[601,602,603,604,606,607,610,611,615,616,618,619,559],"li",{},"Set ",[529,605,535],{}," yourself, or ",[529,608,609],{},"\"\""," (the ",[612,613,614],"strong",{},"No setup needed"," checkbox in Settings › Repos) if the repo needs no preparation, and set ",[529,617,539],{},", then ",[529,620,621],{},"enabled: true",[601,623,624,625,627],{},"Or fix the cause, such as committing the missing lockfile, and run ",[529,626,531],{}," again: on a connected repo it fills in only what the entry left undecided, and enables a repo that was disabled for want of a test command.",[526,629,630,631,634,635,637],{},"A repo that has no tests at all is the third case: connect it with ",[529,632,633],{},"--no-tests"," (see ",[549,636,571],{"href":570},"). A setup it found still has to be confirmed or replaced.",[574,639,571],{"id":640},"choosing-something-else",[526,642,643,644,650,651,654,655,654,658,654,660,567,663,666],{},"The proposal is a starting point. The ",[549,645,647,649],{"href":646},"\u002Freference\u002Fcli\u002Frepo#connect-a-repo",[529,648,531],{}," flags"," (",[529,652,653],{},"--test-command",", ",[529,656,657],{},"--setup-command",[529,659,633],{},[529,661,662],{},"--verify",[529,664,665],{},"--timeout",") replace or check it. What they do to a proposal, beyond what that page says:",[598,668,669,674,685],{},[601,670,671,673],{},[529,672,653],{}," replaces the root's test command. Nested scopes are still probed.",[601,675,676,678,679,681,682,684],{},[529,677,657],{}," is the repo's whole ",[529,680,535],{},", nested directories included, since that is the one field ",[529,683,300],{}," has.",[601,686,687,688,690],{},"With ",[529,689,633],{},", verify passes, saying so. Nested and area scopes still run, and a change outside them selects every scope, as it always does.",[526,692,693],{},"In a terminal, connect lists the root's candidates and asks which to use.",[695,696,698],"h3",{"id":697},"verify-a-proposal","Verify a proposal",[526,700,701,706,707,710],{},[549,702,704],{"href":703},"\u002Freference\u002Fcli\u002Frepo#verify-a-repos-commands",[529,705,662],{}," fails when a command leaves files every work item would commit, such as a lockfile an unlocked install writes, or an unignored ",[529,708,709],{},"build\u002F",". It also fails when a command does not finish in time, usually a test runner in watch mode.",[526,712,713,714,717],{},"Each test runs with the environment a work item gives it, so the ",[529,715,716],{},"__pycache__\u002F"," a Python test would otherwise write is not reported.",[526,719,720],{},"What verify does with files a command writes:",[598,722,723,739,757,773],{},[601,724,725,731,732,735,736,559],{},[612,726,727,728],{},"A virtualenv or ",[529,729,730],{},"node_modules"," a setup installs does not fail verify, since Kraft's own commits leave it out. If the repo does not ignore it, verify still names it: the agent commits on its own too, and its ",[529,733,734],{},"git add -A"," would take it. Add it to ",[529,737,738],{},".gitignore",[601,740,741,748,749,752,753,756],{},[612,742,743,744,747],{},"A ",[529,745,746],{},"uv.lock"," the setup command writes",", as ",[529,750,751],{},"uv sync"," does in a repo that commits none, does not fail verify either (an entry connected before 2.0 can still run it). Kraft's commits leave that file out, the item's events name it (",[529,754,755],{},"sweep_left_out","), and verify names it too.",[601,758,759,764,765,768,769,772],{},[612,760,743,761,763],{},[529,762,746],{}," the agent writes"," is its work and is committed, and so is an edit the agent makes to the setup's. One a test command writes (",[529,766,767],{},"uv run",") is committed as well, so verify fails on it. Commit one (",[529,770,771],{},"uv lock",") so every work item installs the same versions.",[601,774,775,785,786,789],{},[612,776,743,777,780,781,784],{},[529,778,779],{},"Cargo.lock"," that ",[529,782,783],{},"cargo fetch"," writes"," in a crate that commits none is treated the same way, with ",[529,787,788],{},"cargo generate-lockfile"," as the advice.",[574,791,793],{"id":792},"what-is-read","What is read",[526,795,796,797,801],{},"The probe reads the commit a work item's ",[549,798,800],{"href":799},"\u002Fconcepts\u002Fvocabulary#worktree","worktree"," is cut from, not your working copy:",[598,803,804,815],{},[601,805,806,807,810,811,814],{},"origin's default branch when the clone has it (",[529,808,809],{},"origin\u002FHEAD",", else ",[529,812,813],{},"origin\u002Fmain",")",[601,816,817,818],{},"otherwise the checkout's ",[529,819,820],{},"HEAD",[526,822,823],{},"An untracked file, an uncommitted edit, or a commit you have not pushed yet changes nothing. Connect says which commit it read.",[526,825,826,827,830],{},"A repo with no commit yet is refused: a work item's branch starts from a commit, so the proposal would be read from files the branch does not have. Commit its files, then connect it. (The probe alone, ",[529,828,829],{},"POST \u002Frepos\u002Fprobe",", which only inspects, reads such a repo from its working copy: its own regular files, nothing gitignored, no symlinks.)",[526,832,833,834,567,836,838],{},"A file is read up to 4 MB, and a Git LFS file reads as its pointer. A repo that git cannot list within two minutes fails the probe rather than reading as empty; connect it with ",[529,835,653],{},[529,837,657],{}," instead. If you give both, a repo the probe cannot read still connects with them, and connect says why the probe failed.",[574,840,842],{"id":841},"where-a-proposal-comes-from","Where a proposal comes from",[526,844,845],{},"Evidence is ranked. The first kind found wins, and everything else it found is listed as an alternative:",[847,848,849,865],"table",{},[850,851,852],"thead",{},[853,854,855,859,862],"tr",{},[856,857,858],"th",{},"Rank",[856,860,861],{},"Evidence",[856,863,864],{},"Examples",[866,867,868,931,962],"tbody",{},[853,869,870,874,901],{},[871,872,873],"td",{},"1",[871,875,876,879,880,883,884,654,887,890,891,883,894,654,897,900],{},[612,877,878],{},"A task runner the repo wrote."," A ",[529,881,882],{},"test"," (or ",[529,885,886],{},"tests",[529,888,889],{},"check",") task, and a ",[529,892,893],{},"setup",[529,895,896],{},"bootstrap",[529,898,899],{},"deps",") task.",[871,902,903,906,907,910,911,914,915,918,919,567,922,654,925,567,928],{},[529,904,905],{},"justfile"," recipes, ",[529,908,909],{},"Makefile"," targets, ",[529,912,913],{},"Taskfile.yml"," tasks, ",[529,916,917],{},"mise.toml"," tasks, executable ",[529,920,921],{},"script\u002Ftest",[529,923,924],{},"script\u002Fbootstrap",[529,926,927],{},"bin\u002Ftest",[529,929,930],{},"bin\u002Fsetup",[853,932,933,936,941],{},[871,934,935],{},"2",[871,937,938],{},[612,939,940],{},"A toolchain's default, picked by its lockfile.",[871,942,943,946,947,654,950,946,953,654,956,946,959],{},[529,944,945],{},"pnpm-lock.yaml"," gives ",[529,948,949],{},"pnpm",[529,951,952],{},"poetry.lock",[529,954,955],{},"poetry",[529,957,958],{},"gradlew",[529,960,961],{},".\u002Fgradlew",[853,963,964,967,973],{},[871,965,966],{},"3",[871,968,969,972],{},[612,970,971],{},"What CI runs."," Test commands only, and only where neither of the above has one.",[871,974,975,978,979,982,983,986],{},[529,976,977],{},".github\u002Fworkflows\u002F*.yml"," (with each step's ",[529,980,981],{},"working-directory","), ",[529,984,985],{},".gitlab-ci.yml",", CircleCI, Azure Pipelines, Bitbucket, Buildkite, Drone, Woodpecker, Travis",[526,988,989,990,993,994,996],{},"CI ranks last because a CI job is often one slice of the suite: one matrix entry, one module, a type check named ",[529,991,992],{},"typecheck:tests",". The repo's own ",[529,995,882],{}," task or toolchain default runs all of it.",[695,998,1000],{"id":999},"ci-rules","CI rules",[526,1002,1003],{},"Within CI:",[598,1005,1006,1009,1023,1026,1037,1093,1111],{},[601,1007,1008],{},"A command that a runner or toolchain also proposes is shown with \"CI runs it too\". Between two candidates of the same rank, the one CI runs wins.",[601,1010,1011,1012,654,1015,1018,1019,1022],{},"A line that runs a bare tool (",[529,1013,1014],{},"pytest -x",[529,1016,1017],{},"jest",") ranks below every other candidate. CI installed that tool on its own ",[529,1020,1021],{},"PATH",", which a worktree does not have.",[601,1024,1025],{},"The repo's test workflows are read before its e2e, Playwright, Cypress, nightly, release, deploy and docs ones.",[601,1027,1028,1029,1032,1033,1036],{},"A line that only means something inside its script is dropped. That covers a variable, a pipe or redirect, a ",[529,1030,1031],{},"case"," arm, ",[529,1034,1035],{},"echo",", an OS package install, or a global tool install.",[601,1038,1039,1040,654,1043,654,1045,654,1048,654,1051,654,1054,654,1057,654,1060,1063,1064,654,1067,654,1070,1073,1074,654,1077,654,1080,654,1083,654,1086,654,1089,1092],{},"A tool that also runs other things (",[529,1041,1042],{},"npm",[529,1044,949],{},[529,1046,1047],{},"yarn",[529,1049,1050],{},"bun",[529,1052,1053],{},"deno",[529,1055,1056],{},"cargo",[529,1058,1059],{},"go",[529,1061,1062],{},"dotnet",") counts only on its test verb (",[529,1065,1066],{},"npm test",[529,1068,1069],{},"npm run test:unit",[529,1071,1072],{},"go test","). No runner counts when the line has it run something else (",[529,1075,1076],{},"exec",[529,1078,1079],{},"dlx",[529,1081,1082],{},"--call",[529,1084,1085],{},"--shell-mode",[529,1087,1088],{},"--config",[529,1090,1091],{},"-exec",").",[601,1094,1095,1097,1098,1100,1101,1104,1105,654,1108,1092],{},[529,1096,882],{}," as part of a task name (",[529,1099,992],{},") or after Gradle's ",[529,1102,1103],{},"-x",", which excludes the tests, does not make a line a test command. Nor does it in a tool's own install (",[529,1106,1107],{},"mix deps.get --only test",[529,1109,1110],{},"uv sync --group tests",[601,1112,1113,1114,1116,1117,1123,1124,1126,1127,559],{},"A step's ",[529,1115,981],{}," is held to the same rules as any other directory: by default at most two levels down (",[549,1118,1120],{"href":1119},"\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors#top-level-keys",[529,1121,1122],{},"max_depth"," in ",[529,1125,310],{}," changes it), and under no non-project name such as ",[529,1128,882],{},[695,1130,1132],{"id":1131},"a-ci-line-that-hands-a-script-to-a-shell","A CI line that hands a script to a shell",[526,1134,1135],{},"Connect lists such a line with the CI candidates, marked as a script, and never chooses it. What runs is in the quoted text, which Kraft does not read. A line is one of these when it is:",[598,1137,1138,1151,1171],{},[601,1139,1140,1141,1144,1145,654,1148],{},"a shell or interpreter run with ",[529,1142,1143],{},"-c",": ",[529,1146,1147],{},"bash -c \"…\"",[529,1149,1150],{},"python -c \"…\"",[601,1152,1153,1154,654,1157,654,1160,654,1163,1166,1167,1170],{},"an interpreter given a script by its own script flag, whatever the script holds: ",[529,1155,1156],{},"perl -e '…'",[529,1158,1159],{},"ruby -I lib -e '…'",[529,1161,1162],{},"node -e '…'",[529,1164,1165],{},"php -r '…'",". ",[529,1168,1169],{},"python -E -m pytest"," is not one.",[601,1172,1173,1174,654,1177,654,1180,654,1183,654,1186,1189,1190,654,1193,654,1196,654,1199],{},"any line whose quoted text holds shell syntax (",[529,1175,1176],{},"|",[529,1178,1179],{},";",[529,1181,1182],{},"&",[529,1184,1185],{},"\u003C",[529,1187,1188],{},">",", parentheses or braces): ",[529,1191,1192],{},"env -S '…'",[529,1194,1195],{},"nix-shell --run \"…\"",[529,1197,1198],{},"pwsh -Command \"…\"",[529,1200,1201],{},"awk 'BEGIN { system(…) }'",[526,1203,1204,1205,654,1208,654,1211,1214,1215,654,1217,654,1220,654,1223,1226,1227,1230],{},"The exception is a known test runner reading that text as its own argument, run with no shell: ",[529,1206,1207],{},"pytest -k \"not (a or b)\"",[529,1209,1210],{},"go test -run 'Test(Foo|Bar)'",[529,1212,1213],{},"jest --testPathPattern \"(unit|int)\"",". It stays a candidate, also behind ",[529,1216,767],{},[529,1218,1219],{},"poetry run",[529,1221,1222],{},"python -m",[529,1224,1225],{},"npx"," or ",[529,1228,1229],{},"xvfb-run"," and their options.",[695,1232,1234],{"id":1233},"evidence-that-is-listed-and-never-chosen","Evidence that is listed and never chosen",[598,1236,1237,1243,1256],{},[601,1238,1239,1242],{},[612,1240,1241],{},"CI setup lines."," CI installs global tools a worktree must not.",[601,1244,1245,1248,1249,654,1252,1255],{},[612,1246,1247],{},"A dev container's create commands."," They are written for a container, and often install into its global interpreter. One that provisions the container itself (",[529,1250,1251],{},"sudo",[529,1253,1254],{},"apt-get",") is not listed at all.",[601,1257,1258,1261],{},[612,1259,1260],{},"A CI line that hands a script to a shell."," See the section above.",[695,1263,1265],{"id":1264},"evidence-a-toolchain-needs","Evidence a toolchain needs",[526,1267,1268,1269,1273],{},"A toolchain (the ",[549,1270,1272],{"href":1271},"\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors#toolchains-in-the-shipped-table","shipped table"," lists them) needs evidence for its test command, as well as its marker file:",[598,1275,1276,1289,1307,1313],{},[601,1277,743,1278,1281,1282,1284,1285,1288],{},[529,1279,1280],{},"package.json"," counts only with a real ",[529,1283,882],{}," script. npm's ",[529,1286,1287],{},"\"no test specified\""," placeholder does not count.",[601,1290,1291,1292,1295,1296,1295,1299,1302,1303,1306],{},"pytest is proposed only when something names it: ",[529,1293,1294],{},"pytest.ini",", a ",[529,1297,1298],{},"conftest.py",[529,1300,1301],{},"[tool.pytest]"," table, a dependency, or a lockfile entry. A plugin like ",[529,1304,1305],{},"flake8-pytest-style"," does not count.",[601,1308,743,1309,1312],{},[529,1310,1311],{},"pyproject.toml"," holding only tool settings (ruff, black) does not make a repo a Python project.",[601,1314,1315,1318,1319,1322],{},[529,1316,1317],{},"go test .\u002F..."," is proposed only when a ",[529,1320,1321],{},"_test.go"," file is there or below. With none, it compiles every package and passes with \"no test files\", which tests nothing.",[695,1324,1326],{"id":1325},"how-a-command-is-run","How a command is run",[526,1328,1329,1330,1332,1333,654,1336,1226,1339,1342,1343,654,1346,1349,1350,1352],{},"A task runner's ",[529,1331,882],{}," task that runs ",[529,1334,1335],{},"pytest",[529,1337,1338],{},"python",[529,1340,1341],{},"coverage"," bare, in a directory a Python lockfile locks, is run through that lockfile's tool: ",[529,1344,1345],{},"uv run .\u002Fscripts\u002Ftest.sh",[529,1347,1348],{},"poetry run make test",". Bare, it would run whatever Python a worker's ",[529,1351,1021],{}," has, without the project's dependencies.",[526,1354,1355,1356,1359,1360,1362],{},"A toolchain's install takes the flags CI gives the same command in the same directory: a CI step ",[529,1357,1358],{},"uv sync --extra all --group tests"," makes the proposal that, not ",[529,1361,751],{},". Only options and their values are taken.",[526,1364,1365,1366,1369,1370,1373,1374,1377],{},"When toolchains of more than one family have a test in one directory (tauri's pnpm and Cargo, phoenix's npm and mix), its test command runs each of them, in the ",[549,1367,1368],{"href":1271},"shipped table's"," order (Python first): ",[529,1371,1372],{},"sh -c 'pnpm test && cargo test --workspace'",". One family's tests passing says nothing of the other's. Its setup is then each of those toolchains' installs. A task runner's test command (",[529,1375,1376],{},"make test",") gets every toolchain's install, since which ones it needs is not known.",[526,1379,1380,1381,1384,1385,1388,1389,1395],{},"A toolchain whose setup makes a virtualenv (a ",[529,1382,1383],{},"requirements.txt"," project's ",[529,1386,1387],{},".venv",") has a task runner's or CI's test command there run inside it. ",[549,1390,1392],{"href":1391},"\u002Freference\u002Fconfiguration\u002Frepos\u002Fdetectors#detector-fields",[529,1393,1394],{},"venv"," says how.",[695,1397,1399],{"id":1398},"a-python-project-with-no-lockfile","A Python project with no lockfile",[526,1401,1402,1403,1405,1406,654,1408,654,1410,1413,1414,567,1416,1418,1419,1421],{},"One project gets no proposal at all: a ",[529,1404,1311],{}," declaring a project with no lockfile beside it (",[529,1407,746],{},[529,1409,952],{},[529,1411,1412],{},"pdm.lock",", a Pipfile). ",[529,1415,751],{},[529,1417,767],{}," would each write a ",[529,1420,746],{}," into every work item's worktree, for the worker to commit.",[598,1423,1424,1433,1447,1450],{},[601,1425,1426,1427,1226,1430,1432],{},"Its directory proposes no test and no setup. Kraft does not fall back to a ",[529,1428,1429],{},"go.mod",[529,1431,1280],{}," beside it either.",[601,1434,1435,1436,1439,1440,1443,1444,1446],{},"Two things still stand there: a lockfile install (",[529,1437,1438],{},"npm ci"," beside a ",[529,1441,1442],{},"package-lock.json",") and a task runner's own ",[529,1445,882],{}," task, which comes first.",[601,1448,1449],{},"At the root, it means no test command for the whole repo.",[601,1451,1452,1453,1456,1457,1460,1461,1463,1464,1466,1467,1470,1471,1473],{},"Below the root, the directory gets no test command either. A change there would otherwise pass on the other scopes' tests: say ",[529,1454,1455],{},"backend\u002F"," has such a project and ",[529,1458,1459],{},"frontend\u002F"," has a ",[529,1462,1280],{},". A change to ",[529,1465,1455],{}," matches no scope, and a change that matches none runs every scope, so a ",[529,1468,1469],{},"frontend\u002F**"," scope alone would pass it on ",[529,1472,1066],{}," with the Python tests never run.",[526,1475,1476],{},"The exception is a root command that already runs those tests:",[598,1478,1479,1484,1490],{},[601,1480,1481,1482],{},"a command you give with ",[529,1483,653],{},[601,1485,1486,1487,1489],{},"the root task runner's ",[529,1488,882],{}," recipe",[601,1491,1492,1493,814],{},"a lockfile install of the same kind at the root (a uv workspace's ",[529,1494,746],{},[526,1496,1497],{},"The directory then gets no scope of its own, and the root scope covers it.",[526,1499,1500,1501,654,1504,1507,1508,1510,1511,1513],{},"Connect says which directory stopped the proposal, and what to do: a Poetry or PDM project is told to commit its own lock (",[529,1502,1503],{},"poetry lock",[529,1505,1506],{},"pdm lock","), and any other to set its test command, or commit a ",[529,1509,746],{},". Once the lockfile is committed, run ",[529,1512,531],{}," again: it fills in what the first connect left undecided.",[574,1515,1517],{"id":1516},"proposals-that-need-something-from-you","Proposals that need something from you",[526,1519,1520,1521,1523],{},"Some proposals need something only you can supply. Check these with ",[529,1522,662],{},":",[598,1525,1526,1536,1543],{},[601,1527,1528,1529,1532,1533,559],{},"An Android build needs the SDK. Pass ",[529,1530,1531],{},"ANDROID_HOME"," through with the repo's ",[529,1534,1535],{},"env_passthrough",[601,1537,1538,1539,1542],{},"A Rails app's ",[529,1540,1541],{},"bin\u002Fsetup --skip-server"," prepares the database, so the database must be running.",[601,1544,1545],{},"A test target that starts docker needs docker where the work item runs.",[574,1547,1549],{"id":1548},"directories-and-scopes","Directories and scopes",[526,1551,1552,1553,1123,1557,1559],{},"Each directory up to two levels below the root that has its own tests becomes a test scope of its own. Two levels is the default: ",[549,1554,1555],{"href":1119},[529,1556,1122],{},[529,1558,310],{}," changes it. Some directories are skipped:",[598,1561,1562,1565,1600],{},[601,1563,1564],{},"hidden directories",[601,1566,1567,1568,654,1571,654,1574,654,1577,654,1580,654,1583,654,1586,654,1588,654,1590,1593,1594,1123,1597,1599],{},"the usual non-project names, in any case: ",[529,1569,1570],{},"examples",[529,1572,1573],{},"benchmarks",[529,1575,1576],{},"support",[529,1578,1579],{},"docs",[529,1581,1582],{},"fixtures",[529,1584,1585],{},"vendor",[529,1587,899],{},[529,1589,886],{},[529,1591,1592],{},"build"," and the like (",[529,1595,1596],{},"ignore_dirs",[529,1598,310],{}," adds names)",[601,1601,1602],{},"a submodule's contents, because a submodule is a repo of its own",[526,1604,1605,1606,1609,1610,1612,1613,559],{},"A scope's command runs from the worktree root without a shell, so a nested scope's command is written ",[529,1607,1608],{},"sh -c 'cd web && npm test'",". Its setup joins the repo's ",[529,1611,535],{}," in a subshell, for example ",[529,1614,1615],{},"uv sync && (cd web && npm ci)",[526,1617,1618],{},"Two things prepare a nested project from above:",[598,1620,1621,1631],{},[601,1622,1623,1626,1627,1630],{},[612,1624,1625],{},"A workspace root."," A pnpm or npm workspace, a Cargo ",[529,1628,1629],{},"[workspace]",", a uv workspace, a multi-module Maven or Gradle build, a .NET solution, or an Elixir umbrella installs its members. When the root has a test command, its members are not scopes of their own. A member with a lockfile of its own installs on its own.",[601,1632,1633,650,1636,654,1639,1642,1643,654,1646,654,1649,1652],{},[612,1634,1635],{},"The root's own setup task",[529,1637,1638],{},"just setup",[529,1640,1641],{},"make setup","), for each directory that task, or a task it depends on, works in: ",[529,1644,1645],{},"cd web",[529,1647,1648],{},"--prefix web",[529,1650,1651],{},"web\u002F...",". Comments and other recipes do not count.",[526,1654,1655,1656,1295,1659,1295,1661,1663],{},"A root that is a project itself (a ",[529,1657,1658],{},"Gemfile",[529,1660,1280],{},[529,1662,909],{},") with no test command found, while directories below it have theirs, gets no proposal at all. A change to the root's own code would select only the nested scopes, and pass on them. Connect says which file made the root a project.",[526,1665,1666,1667,1669,1670,1672],{},"Pass ",[529,1668,653],{}," for the root, or ",[529,1671,633],{}," if the root really has none; the nested scopes are then proposed.",[526,1674,1675,1676,1678,1679,1681,1682,567,1684,1686],{},"A proposed command whose program this machine's ",[529,1677,1021],{}," does not have (a ",[529,1680,1053],{}," scope on a machine with no deno) is named at connect, with its directory: a work item would fail on it until it is installed. The scope stays, since its tests are real; connect with your own ",[529,1683,653],{},[529,1685,657],{}," to leave it out.",[526,1688,1689,1690,1692,1693,1695,1696,1698],{},"If a directory has a test command and nothing prepares it, ",[529,1691,535],{}," is left undeclared. ",[529,1694,531],{}," names the directory. The repo's first work item then stops until you declare a setup command, which can be ",[529,1697,609],{}," for none.",[574,1700,1702],{"id":1701},"limits-on-what-the-probe-reads","Limits on what the probe reads",[526,1704,1705],{},"A repository's files are whatever someone committed, so the probe treats them as hostile. These limits keep a file from stalling the Kraft server or leaking its secrets:",[847,1707,1708,1718],{},[850,1709,1710],{},[853,1711,1712,1715],{},[856,1713,1714],{},"Limit",[856,1716,1717],{},"Value",[866,1719,1720,1728,1742,1750,1758,1766,1774,1782],{},[853,1721,1722,1725],{},[871,1723,1724],{},"Time",[871,1726,1727],{},"The probe runs in a process of its own, killed after two minutes.",[853,1729,1730,1733],{},[871,1731,1732],{},"Environment",[871,1734,1735,1736,654,1738,1741],{},"That process gets none of the server's environment beyond ",[529,1737,1021],{},[529,1739,1740],{},"HOME"," and the locale, so none of its API keys or tokens. It never imports from the directory the server was started in.",[853,1743,1744,1747],{},[871,1745,1746],{},"One CI file or Taskfile",[871,1748,1749],{},"Up to 50,000 YAML nodes and script lines, counted before the YAML is built, with every use of an alias counting again. One past the limit is skipped.",[853,1751,1752,1755],{},[871,1753,1754],{},"All CI files and Taskfiles together",[871,1756,1757],{},"Up to 200,000 nodes and script lines. One past the limit is skipped.",[853,1759,1760,1763],{},[871,1761,1762],{},"All files in one probe",[871,1764,1765],{},"64 MB.",[853,1767,1768,1771],{},[871,1769,1770],{},"A file that cannot be parsed, or is nested deeper than the parser goes",[871,1772,1773],{},"Not evidence. The rest of the repo still is.",[853,1775,1776,1779],{},[871,1777,1778],{},"A CI or dev container command with a control character in it (an ANSI escape, a bidi override)",[871,1780,1781],{},"Not a candidate: it could show you one command while another runs.",[853,1783,1784,1787],{},[871,1785,1786],{},"The repo's own git settings",[871,1788,1789,1790,1793],{},"They never run a program: ",[529,1791,1792],{},"core.fsmonitor"," is turned off for the probe's git calls.",[574,1795,1797],{"id":1796},"related","Related",[598,1799,1800,1808,1819],{},[601,1801,1802,1804,1805,1807],{},[549,1803,310],{"href":311},": the ",[529,1806,310],{}," keys that teach connect your own conventions, and the toolchains Kraft ships.",[601,1809,1810,1804,1812,654,1814,567,1816,1818],{},[549,1811,300],{"href":301},[529,1813,535],{},[529,1815,539],{},[529,1817,543],{}," fields a proposal fills in.",[601,1820,1821,1804,1823,1825],{},[549,1822,282],{"href":283},[529,1824,531],{}," flags.",{"title":1827,"searchDepth":1828,"depth":1828,"links":1829},"",2,[1830,1831,1835,1836,1844,1845,1846,1847],{"id":576,"depth":1828,"text":566},{"id":640,"depth":1828,"text":571,"children":1832},[1833],{"id":697,"depth":1834,"text":698},3,{"id":792,"depth":1828,"text":793},{"id":841,"depth":1828,"text":842,"children":1837},[1838,1839,1840,1841,1842,1843],{"id":999,"depth":1834,"text":1000},{"id":1131,"depth":1834,"text":1132},{"id":1233,"depth":1834,"text":1234},{"id":1264,"depth":1834,"text":1265},{"id":1325,"depth":1834,"text":1326},{"id":1398,"depth":1834,"text":1399},{"id":1516,"depth":1828,"text":1517},{"id":1548,"depth":1828,"text":1549},{"id":1701,"depth":1828,"text":1702},{"id":1796,"depth":1828,"text":1797},"What kraft repo connect reads in a repo, where each proposed setup and test command comes from, and what it does when it finds none.","md",null,{},true,{"title":306,"description":1848},"iOSzcqdz12siwBusNpRwI76mF7lGsFovmErTSLEbG_Q",[1856,1858],{"title":10,"path":301,"stem":302,"description":1857,"children":-1},"Every field in repos.yaml, where a repo's value comes from, and the pages for how connect proposes commands, detectors, workspaces and sandboxes.",{"title":310,"path":311,"stem":312,"description":1859,"children":-1},"The keys of detectors.yaml, the file that teaches kraft repo connect your own setup and test conventions, and the toolchains Kraft ships.",1791801179609]