[{"data":1,"prerenderedAt":2304},["ShallowReactive",2],{"navigation":3,"/advanced/drift-detection-self-healing":879,"/advanced/drift-detection-self-healing-surround":2299},[4,22,45,115,156,187,214,235,264,295,318,361,389,418,436,470,491,534,548,571,632,670,693,757,850],{"title":5,"path":6,"stem":7,"children":8,"icon":11},"Introduction","/introduction","01.introduction/1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"What is Orkestia?","i-lucide-sparkles",{"title":13,"path":14,"stem":15,"icon":16},"Core Philosophy","/introduction/core-philosophy","01.introduction/2.core-philosophy","i-lucide-shield-check",{"title":18,"path":19,"stem":20,"icon":21},"Key Benefits","/introduction/key-benefits","01.introduction/3.key-benefits","i-lucide-trophy",{"title":23,"path":24,"stem":25,"children":26,"icon":29},"Getting Started","/getting-started","02.getting-started/1.index",[27,30,35,40],{"title":28,"path":24,"stem":25,"icon":29},"Quick Start","i-lucide-rocket",{"title":31,"path":32,"stem":33,"icon":34},"Architecture Overview","/getting-started/architecture-overview","02.getting-started/2.architecture-overview","i-lucide-layout-dashboard",{"title":36,"path":37,"stem":38,"icon":39},"Concepts at a Glance","/getting-started/concepts","02.getting-started/3.concepts","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Connect an AI Assistant","/getting-started/connect-an-ai-assistant","02.getting-started/4.connect-an-ai-assistant","i-lucide-bot",{"title":46,"path":47,"stem":48,"children":49,"icon":51},"Core Concepts","/concepts","03.concepts/01.index",[50,52,57,62,67,71,76,81,86,91,96,100,105,110],{"title":46,"path":47,"stem":48,"icon":51},"i-lucide-book-open",{"title":53,"path":54,"stem":55,"icon":56},"Workflows","/concepts/workflows","03.concepts/02.workflows","i-lucide-workflow",{"title":58,"path":59,"stem":60,"icon":61},"DGI — Dialog Generative Interface","/concepts/dgi","03.concepts/03.dgi","i-lucide-brain",{"title":63,"path":64,"stem":65,"icon":66},"Staff & AI Workforce Governance","/concepts/staff-governance","03.concepts/04.staff-governance","i-lucide-users-round",{"title":68,"path":69,"stem":70,"icon":44},"Agents — the execution substrate","/concepts/agents-platform","03.concepts/05.agents-platform",{"title":72,"path":73,"stem":74,"icon":75},"Runners & Execution Environments","/concepts/runners","03.concepts/06.runners","i-lucide-server-cog",{"title":77,"path":78,"stem":79,"icon":80},"Lumen Observability","/concepts/lumen","03.concepts/07.lumen","i-lucide-activity",{"title":82,"path":83,"stem":84,"icon":85},"Identity & Multi-Tenancy","/concepts/identity-multi-tenancy","03.concepts/08.identity-multi-tenancy","i-lucide-users",{"title":87,"path":88,"stem":89,"icon":90},"Billing, Pricing & Seats","/concepts/billing-and-seats","03.concepts/09.billing-and-seats","i-lucide-credit-card",{"title":92,"path":93,"stem":94,"icon":95},"App Data","/concepts/appdata","03.concepts/10.appdata","i-lucide-database",{"title":97,"path":98,"stem":99,"icon":61},"Engram","/concepts/engram","03.concepts/11.engram",{"title":101,"path":102,"stem":103,"icon":104},"DevKit","/concepts/devkit","03.concepts/12.devkit","i-lucide-terminal",{"title":106,"path":107,"stem":108,"icon":109},"App Host","/concepts/app-host","03.concepts/13.app-host","i-lucide-globe",{"title":111,"path":112,"stem":113,"icon":114},"Agent Exchange","/concepts/agent-exchange","03.concepts/14.agent-exchange","i-lucide-landmark",{"title":116,"path":117,"stem":118,"children":119,"icon":121},"Guides","/guides","04.guides/1.index",[120,122,127,132,137,142,147,151],{"title":116,"path":117,"stem":118,"icon":121},"i-lucide-compass",{"title":123,"path":124,"stem":125,"icon":126},"Building with DGI","/guides/building-with-dgi","04.guides/2.building-with-dgi","i-lucide-brain-circuit",{"title":128,"path":129,"stem":130,"icon":131},"Creating & Exposing Virtual Workflows","/guides/virtual-workflows","04.guides/4.virtual-workflows","i-lucide-blocks",{"title":133,"path":134,"stem":135,"icon":136},"Runner Management & Provisioning","/guides/runner-management","04.guides/5.runner-management","i-lucide-server",{"title":138,"path":139,"stem":140,"icon":141},"Security & Compliance","/guides/security-and-compliance","04.guides/7.security-and-compliance","i-lucide-shield",{"title":143,"path":144,"stem":145,"icon":146},"Tickets & Software Delivery","/guides/tickets-and-software-delivery","04.guides/8.tickets-and-software-delivery","i-lucide-ticket",{"title":148,"path":149,"stem":150},"Orkestia for AI-driven cloud infrastructure automation","/guides/cloud-automation-alternatives","04.guides/9.cloud-automation-alternatives",{"title":152,"path":153,"stem":154,"icon":155},"Typed decisions with TypeSafe","/guides/typed-decisions-with-typesafe","04.guides/9.typed-decisions-with-typesafe","i-lucide-git-branch",{"title":157,"path":158,"stem":159,"children":160,"icon":162},"Reference","/reference","05.reference/1.index",[161,163,168,173,177,182],{"title":157,"path":158,"stem":159,"icon":162},"i-lucide-library",{"title":164,"path":165,"stem":166,"icon":167},"Workflow Types & Registry","/reference/workflow-types-registry","05.reference/2.workflow-types-registry","i-lucide-list-tree",{"title":169,"path":170,"stem":171,"icon":172},"MCP Integration","/reference/mcp-integration","05.reference/3.mcp-integration","i-lucide-plug-zap",{"title":174,"path":175,"stem":176,"icon":104},"API & Tooling","/reference/api-tooling","05.reference/4.api-tooling",{"title":178,"path":179,"stem":180,"icon":181},"Integrations Catalog","/reference/integrations-catalog","05.reference/6.integrations-catalog","i-lucide-plug",{"title":183,"path":184,"stem":185,"icon":186},"Platform Services","/reference/platform-services","05.reference/7.platform-services","i-lucide-boxes",{"title":188,"path":189,"stem":190,"children":191,"icon":193},"Advanced Topics","/advanced","06.advanced/1.index",[192,194,199,204,209],{"title":188,"path":189,"stem":190,"icon":193},"i-lucide-flask-conical",{"title":195,"path":196,"stem":197,"icon":198},"Hybrid AI + Deterministic Execution","/advanced/hybrid-execution-model","06.advanced/2.hybrid-execution-model","i-lucide-git-merge",{"title":200,"path":201,"stem":202,"icon":203},"Drift Detection & Self-Healing","/advanced/drift-detection-self-healing","06.advanced/3.drift-detection-self-healing","i-lucide-heart-pulse",{"title":205,"path":206,"stem":207,"icon":208},"Governance & Approvals","/advanced/governance-and-approvals","06.advanced/4.governance-and-approvals","i-lucide-scale",{"title":210,"path":211,"stem":212,"icon":213},"Cost & Performance Optimization","/advanced/cost-and-performance","06.advanced/5.cost-and-performance","i-lucide-zap",{"title":215,"path":216,"stem":217,"children":218,"icon":220},"Operations","/operations","07.operations/1.index",[219,221,225,230],{"title":215,"path":216,"stem":217,"icon":220},"i-lucide-settings-2",{"title":222,"path":223,"stem":224,"icon":186},"Deployment Models","/operations/deployment-models","07.operations/2.deployment-models",{"title":226,"path":227,"stem":228,"icon":229},"Monitoring & Debugging","/operations/monitoring-and-debugging","07.operations/3.monitoring-and-debugging","i-lucide-bug",{"title":231,"path":232,"stem":233,"icon":234},"Best Practices","/operations/best-practices","07.operations/4.best-practices","i-lucide-check-check",{"title":236,"path":237,"stem":238,"children":239,"icon":241},"AWS Connections","/aws-connections","08.aws-connections/1.index",[240,242,245,250,255,260],{"title":236,"path":237,"stem":238,"icon":241},"i-simple-icons-amazonaws",{"title":23,"path":243,"stem":244,"icon":29},"/aws-connections/getting-started","08.aws-connections/2.getting-started",{"title":246,"path":247,"stem":248,"icon":249},"Setup Methods","/aws-connections/setup-methods","08.aws-connections/3.setup-methods","i-lucide-wrench",{"title":251,"path":252,"stem":253,"icon":254},"Managing Connections","/aws-connections/managing-connections","08.aws-connections/4.managing-connections","i-lucide-settings",{"title":256,"path":257,"stem":258,"icon":259},"Security Best Practices","/aws-connections/security-best-practices","08.aws-connections/5.security-best-practices","i-lucide-lock",{"title":261,"path":262,"stem":263,"icon":229},"Troubleshooting","/aws-connections/troubleshooting","08.aws-connections/6.troubleshooting",{"title":265,"path":266,"stem":267,"children":268,"icon":270},"Cloud Connections","/cloud-connections","09.cloud-connections/1.index",[269,271,276,281,286,291],{"title":265,"path":266,"stem":267,"icon":270},"i-lucide-cable",{"title":272,"path":273,"stem":274,"icon":275},"Google Cloud (GCP)","/cloud-connections/gcp","09.cloud-connections/2.gcp","i-simple-icons-googlecloud",{"title":277,"path":278,"stem":279,"icon":280},"Microsoft Azure","/cloud-connections/azure","09.cloud-connections/3.azure","i-simple-icons-microsoftazure",{"title":282,"path":283,"stem":284,"icon":285},"Magalu Cloud","/cloud-connections/magalu","09.cloud-connections/4.magalu","i-lucide-cloud",{"title":287,"path":288,"stem":289,"icon":290},"Kubernetes","/cloud-connections/kubernetes","09.cloud-connections/5.kubernetes","i-simple-icons-kubernetes",{"title":292,"path":293,"stem":294,"icon":208},"TypeSafe","/cloud-connections/typesafe","09.cloud-connections/6.typesafe",{"title":296,"path":297,"stem":298,"children":299,"icon":136},"DNS Providers","/dns-providers","10.dns-providers/1.index",[300,302,305,308,311,315],{"title":301,"path":297,"stem":298,"icon":136},"DNS Provider Connections",{"title":23,"path":303,"stem":304,"icon":29},"/dns-providers/getting-started","10.dns-providers/2.getting-started",{"title":246,"path":306,"stem":307,"icon":249},"/dns-providers/setup-methods","10.dns-providers/3.setup-methods",{"title":251,"path":309,"stem":310,"icon":254},"/dns-providers/managing-connections","10.dns-providers/4.managing-connections",{"title":312,"path":313,"stem":314,"icon":39},"Zones and Records","/dns-providers/zones-and-records","10.dns-providers/5.zones-and-records",{"title":261,"path":316,"stem":317,"icon":229},"/dns-providers/troubleshooting","10.dns-providers/6.troubleshooting",{"title":319,"path":320,"stem":321,"children":322,"icon":29},"Cloud Deploy","/cloud-deploy","11.cloud-deploy/01.index",[323,324,327,332,336,341,345,349,354,358],{"title":319,"path":320,"stem":321,"icon":29},{"title":23,"path":325,"stem":326,"icon":29},"/cloud-deploy/getting-started","11.cloud-deploy/02.getting-started",{"title":328,"path":329,"stem":330,"icon":331},"Creating a Site","/cloud-deploy/creating-a-site","11.cloud-deploy/03.creating-a-site","i-lucide-plus-circle",{"title":333,"path":334,"stem":335,"icon":34},"Site Overview and Deployments","/cloud-deploy/site-overview","11.cloud-deploy/04.site-overview",{"title":337,"path":338,"stem":339,"icon":340},"Deployment Progress and Success","/cloud-deploy/deployment-progress","11.cloud-deploy/05.deployment-progress","i-lucide-loader",{"title":342,"path":343,"stem":344,"icon":254},"Settings","/cloud-deploy/settings","11.cloud-deploy/06.settings",{"title":346,"path":347,"stem":348,"icon":109},"Custom Domains","/cloud-deploy/custom-domains","11.cloud-deploy/07.custom-domains",{"title":350,"path":351,"stem":352,"icon":353},"Resources, Releases, and Danger Zone","/cloud-deploy/resources-releases","11.cloud-deploy/08.resources-releases","i-lucide-package",{"title":355,"path":356,"stem":357,"icon":141},"Admin Dashboard","/cloud-deploy/admin-dashboard","11.cloud-deploy/09.admin-dashboard",{"title":261,"path":359,"stem":360,"icon":229},"/cloud-deploy/troubleshooting","11.cloud-deploy/10.troubleshooting",{"title":362,"path":363,"stem":364,"children":365,"icon":368},"User Onboarding","/user-onboarding","12.user-onboarding/1.index",[366,369,372,377,382,386],{"title":367,"path":363,"stem":364,"icon":368},"User Creation and Onboarding","i-lucide-user-plus",{"title":23,"path":370,"stem":371,"icon":29},"/user-onboarding/getting-started","12.user-onboarding/2.getting-started",{"title":373,"path":374,"stem":375,"icon":376},"Creating Your Organization","/user-onboarding/onboarding","12.user-onboarding/3.onboarding","i-lucide-building-2",{"title":378,"path":379,"stem":380,"icon":381},"Invitations","/user-onboarding/invitations","12.user-onboarding/4.invitations","i-lucide-mail",{"title":383,"path":384,"stem":385,"icon":254},"Managing Your Account","/user-onboarding/managing-account","12.user-onboarding/5.managing-account",{"title":261,"path":387,"stem":388,"icon":229},"/user-onboarding/troubleshooting","12.user-onboarding/6.troubleshooting",{"title":342,"path":390,"stem":391,"children":392,"icon":394},"/settings","13.settings/1.index",[393,395,400,404,409,413],{"title":342,"path":390,"stem":391,"icon":394},"i-lucide-sliders-horizontal",{"title":396,"path":397,"stem":398,"icon":399},"General Settings","/settings/general","13.settings/2.general","i-lucide-user",{"title":401,"path":402,"stem":403,"icon":85},"Members Settings","/settings/members","13.settings/3.members",{"title":405,"path":406,"stem":407,"icon":408},"Notifications Settings","/settings/notifications","13.settings/4.notifications","i-lucide-bell",{"title":410,"path":411,"stem":412,"icon":141},"Security Settings","/settings/security","13.settings/5.security",{"title":414,"path":415,"stem":416,"icon":417},"Signing Keys","/settings/keys","13.settings/6.keys","i-lucide-key-round",{"title":419,"path":420,"stem":421,"children":422,"icon":29},"App Enablement","/app-enablement","14.app-enablement/1.index",[423,424,428,432],{"title":419,"path":420,"stem":421,"icon":29},{"title":425,"path":426,"stem":427,"icon":417},"Sign in with Orkestia","/app-enablement/sign-in-with-orkestia","14.app-enablement/2.sign-in-with-orkestia",{"title":429,"path":430,"stem":431,"icon":95},"End-user data","/app-enablement/end-user-data","14.app-enablement/3.end-user-data",{"title":433,"path":434,"stem":435,"icon":131},"Compositions — use, invoke, share","/app-enablement/compositions","14.app-enablement/4.compositions",{"title":437,"path":438,"stem":439,"children":440,"icon":80},"Lumen","/lumen","15.lumen/1.index",[441,442,447,452,457,461,465],{"title":437,"path":438,"stem":439,"icon":80},{"title":443,"path":444,"stem":445,"icon":446},"Enable Lumen","/lumen/enable","15.lumen/2.enable","i-lucide-power",{"title":448,"path":449,"stem":450,"icon":451},"Send data","/lumen/send-data","15.lumen/3.send-data","i-lucide-upload",{"title":453,"path":454,"stem":455,"icon":456},"Collector","/lumen/collector","15.lumen/4.collector","i-lucide-container",{"title":458,"path":459,"stem":460,"icon":34},"Use Lumen","/lumen/observe","15.lumen/5.observe",{"title":462,"path":463,"stem":464,"icon":44},"Lumen MCP","/lumen/mcp","15.lumen/6.mcp",{"title":466,"path":467,"stem":468,"icon":469},"Query API","/lumen/query-api","15.lumen/7.query-api","i-lucide-search",{"title":471,"path":472,"stem":473,"children":474,"icon":476},"SDKs","/sdks","16.sdks/1.index",[475,477,482,487],{"title":471,"path":472,"stem":473,"icon":476},"i-lucide-code",{"title":478,"path":479,"stem":480,"icon":481},"Workflows SDK — Node / TypeScript","/sdks/workflows-nodejs","16.sdks/2.workflows-nodejs","i-lucide-file-ts",{"title":483,"path":484,"stem":485,"icon":486},"Workflows SDK — Python","/sdks/workflows-python","16.sdks/3.workflows-python","i-simple-icons-python",{"title":488,"path":489,"stem":490,"icon":417},"Auth SDK — Sign in with Orkestia","/sdks/auth","16.sdks/4.auth",{"title":92,"path":492,"stem":493,"children":494,"icon":95},"/appdata","17.appdata/1.index",[495,496,501,506,510,515,520,525,530],{"title":92,"path":492,"stem":493,"icon":95},{"title":497,"path":498,"stem":499,"icon":500},"Declare structures","/appdata/declare","17.appdata/2.declare","i-lucide-table",{"title":502,"path":503,"stem":504,"icon":505},"Records & Data API","/appdata/data-api","17.appdata/3.data-api","i-lucide-rows-3",{"title":507,"path":508,"stem":509,"icon":376},"Ownership & workspaces","/appdata/ownership","17.appdata/4.ownership",{"title":511,"path":512,"stem":513,"icon":514},"Expose App Data to end-users","/appdata/expose","17.appdata/5.expose","i-lucide-app-window",{"title":516,"path":517,"stem":518,"icon":519},"PostgREST HTTP","/appdata/postgrest","17.appdata/6.postgrest","i-lucide-unplug",{"title":521,"path":522,"stem":523,"icon":524},"Ordered append","/appdata/append","17.appdata/7.append","i-lucide-list-ordered",{"title":526,"path":527,"stem":528,"icon":529},"Databases and instances","/appdata/instances","17.appdata/8.instances","i-lucide-hard-drive",{"title":531,"path":532,"stem":533,"icon":104},"Query console and SQL","/appdata/query","17.appdata/9.query",{"title":97,"path":535,"stem":536,"children":537,"icon":61},"/engram","18.engram/1.index",[538,539,543],{"title":97,"path":535,"stem":536,"icon":61},{"title":540,"path":541,"stem":542,"icon":155},"Write & recall","/engram/write-recall","18.engram/2.write-recall",{"title":544,"path":545,"stem":546,"icon":547},"Field & feed","/engram/agent-memory","18.engram/3.agent-memory","i-lucide-radio",{"title":101,"path":549,"stem":550,"children":551,"icon":104},"/devkit","19.devkit/1.index",[552,553,558,562,567],{"title":101,"path":549,"stem":550,"icon":104},{"title":554,"path":555,"stem":556,"icon":557},"Install DevKit","/devkit/install","19.devkit/2.install","i-lucide-download",{"title":559,"path":560,"stem":561,"icon":519},"Hook redirect","/devkit/hooks","19.devkit/3.hooks",{"title":563,"path":564,"stem":565,"icon":566},"Local coding runner","/devkit/local-runner","19.devkit/4.local-runner","i-lucide-cpu",{"title":568,"path":569,"stem":570,"icon":131},"Compositions from DevKit","/devkit/compositions","19.devkit/5.compositions",{"title":572,"path":573,"stem":574,"children":575,"icon":44},"Staff & Agents","/staff-and-agents","20.staff-and-agents/01.index",[576,577,582,586,590,594,598,602,606,611,615,620,625,629],{"title":572,"path":573,"stem":574,"icon":44},{"title":578,"path":579,"stem":580,"icon":581},"Prerequisites","/staff-and-agents/prerequisites","20.staff-and-agents/02.prerequisites","i-lucide-list-checks",{"title":583,"path":584,"stem":585,"icon":368},"Hire an actor","/staff-and-agents/hire-an-actor","20.staff-and-agents/03.hire-an-actor",{"title":587,"path":588,"stem":589,"icon":34},"Console","/staff-and-agents/console","20.staff-and-agents/04.console",{"title":591,"path":592,"stem":593,"icon":11},"Configs, skills, and MCP","/staff-and-agents/configs-skills-mcp","20.staff-and-agents/05.configs-skills-mcp",{"title":595,"path":596,"stem":597,"icon":136},"Agent runner groups","/staff-and-agents/runner-groups","20.staff-and-agents/06.runner-groups",{"title":599,"path":600,"stem":601,"icon":16},"Governance","/staff-and-agents/governance","20.staff-and-agents/07.governance",{"title":603,"path":604,"stem":605,"icon":417},"Identity and tokens","/staff-and-agents/identity","20.staff-and-agents/08.identity",{"title":607,"path":608,"stem":609,"icon":610},"Memory and cost","/staff-and-agents/memory-and-cost","20.staff-and-agents/09.memory-and-cost","i-lucide-wallet",{"title":612,"path":613,"stem":614,"icon":155},"Coding agents","/staff-and-agents/coding-agents","20.staff-and-agents/10.coding-agents",{"title":616,"path":617,"stem":618,"icon":619},"Wire a repository for coding agents","/staff-and-agents/wire-a-repository","20.staff-and-agents/11.wire-a-repository","i-lucide-link",{"title":621,"path":622,"stem":623,"icon":624},"Run a ticket end to end","/staff-and-agents/run-a-ticket","20.staff-and-agents/12.run-a-ticket","i-lucide-play",{"title":626,"path":627,"stem":628,"icon":66},"Build a product team of actors","/staff-and-agents/build-a-product-team","20.staff-and-agents/13.build-a-product-team",{"title":261,"path":630,"stem":631,"icon":249},"/staff-and-agents/troubleshooting","20.staff-and-agents/14.troubleshooting",{"title":106,"path":633,"stem":634,"children":635,"icon":109},"/app-host","21.app-host/1.index",[636,637,641,644,649,653,658,662,666],{"title":106,"path":633,"stem":634,"icon":109},{"title":638,"path":639,"stem":640,"icon":514},"Your app and site","/app-host/your-app","21.app-host/2.your-app",{"title":92,"path":642,"stem":643,"icon":95},"/app-host/app-data","21.app-host/3.app-data",{"title":645,"path":646,"stem":647,"icon":648},"Website and process","/app-host/hosting","21.app-host/4.hosting","i-lucide-cloud-upload",{"title":650,"path":651,"stem":652,"icon":547},"Buzz","/app-host/buzz","21.app-host/5.buzz",{"title":654,"path":655,"stem":656,"icon":657},"Files","/app-host/files","21.app-host/6.files","i-lucide-folder",{"title":659,"path":660,"stem":661,"icon":109},"Your own domain","/app-host/your-domain","21.app-host/7.your-domain",{"title":663,"path":664,"stem":665,"icon":229},"Troubleshooting App Host","/app-host/troubleshooting","21.app-host/8.troubleshooting",{"title":667,"path":668,"stem":669,"icon":417},"Signing keys","/app-host/signing-keys","21.app-host/9.signing-keys",{"title":111,"path":671,"stem":672,"children":673,"icon":114},"/agent-exchange","22.agent-exchange/01.index",[674,675,678,682,686,690],{"title":111,"path":671,"stem":672,"icon":114},{"title":583,"path":676,"stem":677,"icon":368},"/agent-exchange/hire","22.agent-exchange/02.hire",{"title":679,"path":680,"stem":681,"icon":208},"List an actor","/agent-exchange/list","22.agent-exchange/03.list",{"title":683,"path":684,"stem":685,"icon":104},"Invoke & leases","/agent-exchange/invoke","22.agent-exchange/04.invoke",{"title":687,"path":688,"stem":689,"icon":141},"Settlement & trust","/agent-exchange/settlement","22.agent-exchange/05.settlement",{"title":53,"path":691,"stem":692,"icon":56},"/agent-exchange/workflows","22.agent-exchange/06.workflows",{"title":694,"path":695,"stem":696,"children":697,"icon":75},"Runners","/runners","23.runners/1.index",[698,700,704,709,713,717,721,726,730,734,738,741,745,749,753],{"title":699,"path":695,"stem":696,"icon":75},"Runner groups",{"title":701,"path":702,"stem":703,"icon":275},"Cloud Run","/runners/cloud-run","23.runners/10.cloud-run",{"title":705,"path":706,"stem":707,"icon":708},"DigitalOcean App Job","/runners/do-app-job","23.runners/11.do-app-job","i-simple-icons-digitalocean",{"title":710,"path":711,"stem":712,"icon":708},"DigitalOcean Droplet","/runners/do-droplet","23.runners/12.do-droplet",{"title":714,"path":715,"stem":716,"icon":285},"Magalu Cloud VM","/runners/magalu-vm","23.runners/13.magalu-vm",{"title":101,"path":718,"stem":719,"icon":720},"/runners/devkit","23.runners/14.devkit","i-lucide-laptop",{"title":722,"path":723,"stem":724,"icon":725},"Purposes & integrations","/runners/purposes","23.runners/16.purposes","i-lucide-layers",{"title":727,"path":728,"stem":729,"icon":241},"Fargate","/runners/fargate","23.runners/2.fargate",{"title":731,"path":732,"stem":733,"icon":241},"EC2 Auto Scaling","/runners/ec2-auto-scaling","23.runners/3.ec2-auto-scaling",{"title":735,"path":736,"stem":737,"icon":241},"EC2 VM","/runners/ec2-vm","23.runners/4.ec2-vm",{"title":287,"path":739,"stem":740,"icon":290},"/runners/kubernetes","23.runners/5.kubernetes",{"title":742,"path":743,"stem":744,"icon":280},"Azure Container Apps","/runners/azure-container-apps","23.runners/6.azure-container-apps",{"title":746,"path":747,"stem":748,"icon":280},"Azure VMSS","/runners/azure-vmss","23.runners/7.azure-vmss",{"title":750,"path":751,"stem":752,"icon":280},"Azure VM","/runners/azure-vm","23.runners/8.azure-vm",{"title":754,"path":755,"stem":756,"icon":275},"GCE","/runners/gce","23.runners/9.gce",{"title":758,"path":759,"stem":760,"children":761,"icon":763},"Chat","/chat","24.chat/01.index",[762,764,768,773,777,782,787,791,796,800,805,810,814,819,824,828,832,836,840,845],{"title":758,"path":759,"stem":760,"icon":763},"i-lucide-messages-square",{"title":765,"path":766,"stem":767,"icon":446},"Enable and publish","/chat/enable-and-publish","24.chat/02.enable-and-publish",{"title":769,"path":770,"stem":771,"icon":772},"Theme and customization","/chat/theme-and-customization","24.chat/03.theme-and-customization","i-lucide-palette",{"title":774,"path":775,"stem":776,"icon":85},"Members and moderation","/chat/members-and-moderation","24.chat/04.members-and-moderation",{"title":778,"path":779,"stem":780,"icon":781},"Channels","/chat/channels","24.chat/05.channels","i-lucide-hash",{"title":783,"path":784,"stem":785,"icon":786},"Using the chat","/chat/using-the-chat","24.chat/06.using-the-chat","i-lucide-message-circle",{"title":788,"path":789,"stem":790,"icon":44},"Actors in chat","/chat/actors-in-chat","24.chat/07.actors-in-chat",{"title":792,"path":793,"stem":794,"icon":795},"Internal support actor","/chat/internal-support-actor","24.chat/08.internal-support-actor","i-lucide-life-buoy",{"title":797,"path":798,"stem":799,"icon":104},"API and console","/chat/api-and-console","24.chat/09.api-and-console",{"title":801,"path":802,"stem":803,"icon":804},"Limits","/chat/limits","24.chat/10.limits","i-lucide-triangle-alert",{"title":806,"path":807,"stem":808,"icon":809},"Structured chat with DGI","/chat/structured-chat","24.chat/11.structured-chat","i-lucide-layout-list",{"title":811,"path":812,"stem":813,"icon":109},"Option A: hosted chat with DGI","/chat/option-a-hosted-chat","24.chat/12.option-a-hosted-chat",{"title":815,"path":816,"stem":817,"icon":818},"Option B: embed the chat component","/chat/option-b-embed-component","24.chat/13.option-b-embed-component","i-lucide-component",{"title":820,"path":821,"stem":822,"icon":823},"Option C: custom client (wire contract)","/chat/option-c-custom-client","24.chat/14.option-c-custom-client","i-lucide-braces",{"title":825,"path":826,"stem":827,"icon":394},"Responder configuration reference","/chat/responder-reference","24.chat/15.responder-reference",{"title":829,"path":830,"stem":831,"icon":547},"Cards, live updates and proactive posts","/chat/cards-live-and-proactive","24.chat/16.cards-live-and-proactive",{"title":833,"path":834,"stem":835,"icon":16},"Structured chat security model","/chat/structured-chat-security","24.chat/17.structured-chat-security",{"title":837,"path":838,"stem":839,"icon":181},"Option D: any app or API (dgi.chat)","/chat/option-d-chat-api","24.chat/18.option-d-chat-api",{"title":841,"path":842,"stem":843,"icon":844},"Card catalog","/chat/card-catalog","24.chat/19.card-catalog","i-lucide-layout-grid",{"title":846,"path":847,"stem":848,"icon":849},"Living Surfaces","/chat/living-surfaces","24.chat/20.living-surfaces","i-lucide-sprout",{"title":851,"path":852,"stem":853,"children":854,"icon":61},"DGI","/dgi","25.dgi/1.index",[855,857,862,866,870,874],{"title":856,"path":852,"stem":853,"icon":61},"What is DGI",{"title":858,"path":859,"stem":860,"icon":861},"How DGI works","/dgi/how-it-works","25.dgi/2.how-it-works","i-lucide-cog",{"title":863,"path":864,"stem":865,"icon":844},"Interfaces","/dgi/interfaces","25.dgi/3.interfaces",{"title":867,"path":868,"stem":869,"icon":29},"Quickstart","/dgi/quickstart","25.dgi/4.quickstart",{"title":871,"path":872,"stem":873,"icon":16},"Trust and safety","/dgi/trust-and-safety","25.dgi/5.trust-and-safety",{"title":875,"path":876,"stem":877,"icon":878},"FAQ","/dgi/faq","25.dgi/6.faq","i-lucide-circle-help",{"id":880,"title":200,"body":881,"description":2292,"extension":2293,"links":2294,"meta":2295,"navigation":2296,"path":201,"seo":2297,"stem":202,"__hash__":2298},"docs/06.advanced/3.drift-detection-self-healing.md",{"type":882,"value":883,"toc":2276},"minimark",[884,897,916,921,924,983,994,1014,1018,1025,1057,1388,1401,1405,1412,1418,1421,1467,1474,1478,1490,1551,1560,1569,1573,1580,1585,1608,1729,1741,1745,1756,1808,1812,1830,1839,1843,1850,1989,2003,2007,2017,2132,2149,2153,2170,2174,2185,2221,2225,2272],[885,886,887,888,892,893,896],"p",{},"Orkestia provisions runners and reads network topology inside ",[889,890,891],"strong",{},"your"," cloud account — but the cloud is a living system. Quotas change, consoles get edited by hand, runners die, webhooks get dropped, and a VPC referenced by a profile gets decommissioned. ",[889,894,895],{},"Drift"," is the gap between the state Orkestia intends and the state the provider actually reports. This page explains how that gap is detected, how readiness verdicts are computed from it, and the deliberate line between what Orkestia heals on its own and what it surfaces for a human to approve.",[898,899,900],"note",{},[885,901,902,903,907,908,911,912,915],{},"This is a control-plane reconciliation model, not an agent loop running inside your account. Per the ",[904,905,906],"a",{"href":47},"Zero Code Custody"," posture, Orkestia stores only workflow ",[889,909,910],{},"state"," and observability data — the compute being reconciled always lives in your cloud, and Orkestia observes and orchestrates it rather than holding it. See ",[904,913,914],{"href":223},"Deployment models",".",[917,918,920],"h2",{"id":919},"what-drift-means-on-orkestia","What \"drift\" means on Orkestia",[885,922,923],{},"There are two distinct surfaces where desired and actual state can diverge, and they reconcile differently:",[925,926,927,946],"table",{},[928,929,930],"thead",{},[931,932,933,937,940,943],"tr",{},[934,935,936],"th",{},"Surface",[934,938,939],{},"Desired state",[934,941,942],{},"Actual state",[934,944,945],{},"Reconciliation style",[947,948,949,965],"tbody",{},[931,950,951,956,959,962],{},[952,953,954],"td",{},[904,955,694],{"href":73},[952,957,958],{},"Group config: min/max, labels, network placement, registered runner set",[952,960,961],{},"Live cloud compute (ECS tasks / EC2 / K8s pods) + GitHub's view of registered runners",[952,963,964],{},"Active — reconcile-loop scaling, health-reap, teardown repair",[931,966,967,970,977,980],{},[952,968,969],{},"Network Management",[952,971,972,973,976],{},"Saved ",[889,974,975],{},"network profiles"," (VPC + subnets + SGs, versioned)",[952,978,979],{},"Provider network inventory mirrored by periodic sync",[952,981,982],{},"Detect-and-surface — Orkestia never mutates customer networks",[885,984,985,986,989,990,993],{},"The asymmetry is intentional. Orkestia ",[889,987,988],{},"owns the lifecycle"," of the runners it provisions, so it can act on runner drift directly. It does ",[889,991,992],{},"not"," own your networks — Network Management is pull-only inventory, so network drift is detected and flagged, never silently corrected.",[995,996,997],"warning",{},[885,998,999,1000,1003,1004,1007,1008,915],{},"Drift detection and self-healing are GA end-to-end for ",[889,1001,1002],{},"AWS"," runner groups, and ",[889,1005,1006],{},"Azure and Kubernetes groups run production fleets today",". Coverage for GCP, DigitalOcean, and Magalu ships in the provider workflow libraries with partial end-to-end paths — treat auto-reap and placement repair on those providers as (beta). See the live catalog at ",[904,1009,1013],{"href":1010,"rel":1011},"https://reference.orkestia.dev",[1012],"nofollow","reference.orkestia.dev",[917,1015,1017],{"id":1016},"how-desired-state-is-expressed","How desired state is expressed",[885,1019,1020,1021,1024],{},"Both surfaces declare desired state as ",[889,1022,1023],{},"versioned, org-local metadata"," — never as mutable in-place rows. This is what makes drift computable: there is always a stable reference to diff actual state against.",[1026,1027,1028,1044],"ul",{},[1029,1030,1031,1032,1035,1036,1040,1041,915],"li",{},"A ",[889,1033,1034],{},"runner group"," holds ",[1037,1038,1039],"code",{},"(GitHub org + target cloud env + scaling policy + network placement + labels)",". It moves through ",[1037,1042,1043],{},"draft → provisioning → active → scaling → archived",[1029,1045,1031,1046,1035,1049,1052,1053,1056],{},[889,1047,1048],{},"network profile",[1037,1050,1051],{},"(VPC, subnets, security groups, optional public/private intent)"," and is versioned: every edit bumps ",[1037,1054,1055],{},"vN → vN+1",", and an in-flight launch keeps the version it resolved. A profile edit can never retroactively break a running deploy.",[1058,1059,1064],"pre",{"className":1060,"code":1061,"language":1062,"meta":1063,"style":1063},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"id\": \"np_01HXZ...\",\n  \"name\": \"prod-usa-private\",\n  \"version\": 3,\n  \"intent\": \"private\",\n  \"targets\": [\n    {\n      \"provider\": \"aws\",\n      \"connection_id\": \"cn_aws_prod\",\n      \"region\": \"us-east-1\",\n      \"vpc_id\": \"vpc-0abc123\",\n      \"subnets\": [\"subnet-0a...\", \"subnet-0b...\"],\n      \"security_groups\": [\"sg-0ff...\"]\n    }\n  ],\n  \"readiness\": \"green\",\n  \"updated_at\": \"2026-04-15T18:22:04Z\"\n}\n","json","",[1037,1065,1066,1075,1103,1124,1142,1163,1178,1184,1207,1228,1249,1270,1305,1329,1335,1341,1362,1382],{"__ignoreMap":1063},[1067,1068,1071],"span",{"class":1069,"line":1070},"line",1,[1067,1072,1074],{"class":1073},"sMK4o","{\n",[1067,1076,1078,1081,1085,1088,1091,1094,1098,1100],{"class":1069,"line":1077},2,[1067,1079,1080],{"class":1073},"  \"",[1067,1082,1084],{"class":1083},"spNyl","id",[1067,1086,1087],{"class":1073},"\"",[1067,1089,1090],{"class":1073},":",[1067,1092,1093],{"class":1073}," \"",[1067,1095,1097],{"class":1096},"sfazB","np_01HXZ...",[1067,1099,1087],{"class":1073},[1067,1101,1102],{"class":1073},",\n",[1067,1104,1106,1108,1111,1113,1115,1117,1120,1122],{"class":1069,"line":1105},3,[1067,1107,1080],{"class":1073},[1067,1109,1110],{"class":1083},"name",[1067,1112,1087],{"class":1073},[1067,1114,1090],{"class":1073},[1067,1116,1093],{"class":1073},[1067,1118,1119],{"class":1096},"prod-usa-private",[1067,1121,1087],{"class":1073},[1067,1123,1102],{"class":1073},[1067,1125,1127,1129,1132,1134,1136,1140],{"class":1069,"line":1126},4,[1067,1128,1080],{"class":1073},[1067,1130,1131],{"class":1083},"version",[1067,1133,1087],{"class":1073},[1067,1135,1090],{"class":1073},[1067,1137,1139],{"class":1138},"sbssI"," 3",[1067,1141,1102],{"class":1073},[1067,1143,1145,1147,1150,1152,1154,1156,1159,1161],{"class":1069,"line":1144},5,[1067,1146,1080],{"class":1073},[1067,1148,1149],{"class":1083},"intent",[1067,1151,1087],{"class":1073},[1067,1153,1090],{"class":1073},[1067,1155,1093],{"class":1073},[1067,1157,1158],{"class":1096},"private",[1067,1160,1087],{"class":1073},[1067,1162,1102],{"class":1073},[1067,1164,1166,1168,1171,1173,1175],{"class":1069,"line":1165},6,[1067,1167,1080],{"class":1073},[1067,1169,1170],{"class":1083},"targets",[1067,1172,1087],{"class":1073},[1067,1174,1090],{"class":1073},[1067,1176,1177],{"class":1073}," [\n",[1067,1179,1181],{"class":1069,"line":1180},7,[1067,1182,1183],{"class":1073},"    {\n",[1067,1185,1187,1190,1194,1196,1198,1200,1203,1205],{"class":1069,"line":1186},8,[1067,1188,1189],{"class":1073},"      \"",[1067,1191,1193],{"class":1192},"sBMFI","provider",[1067,1195,1087],{"class":1073},[1067,1197,1090],{"class":1073},[1067,1199,1093],{"class":1073},[1067,1201,1202],{"class":1096},"aws",[1067,1204,1087],{"class":1073},[1067,1206,1102],{"class":1073},[1067,1208,1210,1212,1215,1217,1219,1221,1224,1226],{"class":1069,"line":1209},9,[1067,1211,1189],{"class":1073},[1067,1213,1214],{"class":1192},"connection_id",[1067,1216,1087],{"class":1073},[1067,1218,1090],{"class":1073},[1067,1220,1093],{"class":1073},[1067,1222,1223],{"class":1096},"cn_aws_prod",[1067,1225,1087],{"class":1073},[1067,1227,1102],{"class":1073},[1067,1229,1231,1233,1236,1238,1240,1242,1245,1247],{"class":1069,"line":1230},10,[1067,1232,1189],{"class":1073},[1067,1234,1235],{"class":1192},"region",[1067,1237,1087],{"class":1073},[1067,1239,1090],{"class":1073},[1067,1241,1093],{"class":1073},[1067,1243,1244],{"class":1096},"us-east-1",[1067,1246,1087],{"class":1073},[1067,1248,1102],{"class":1073},[1067,1250,1252,1254,1257,1259,1261,1263,1266,1268],{"class":1069,"line":1251},11,[1067,1253,1189],{"class":1073},[1067,1255,1256],{"class":1192},"vpc_id",[1067,1258,1087],{"class":1073},[1067,1260,1090],{"class":1073},[1067,1262,1093],{"class":1073},[1067,1264,1265],{"class":1096},"vpc-0abc123",[1067,1267,1087],{"class":1073},[1067,1269,1102],{"class":1073},[1067,1271,1273,1275,1278,1280,1282,1285,1287,1290,1292,1295,1297,1300,1302],{"class":1069,"line":1272},12,[1067,1274,1189],{"class":1073},[1067,1276,1277],{"class":1192},"subnets",[1067,1279,1087],{"class":1073},[1067,1281,1090],{"class":1073},[1067,1283,1284],{"class":1073}," [",[1067,1286,1087],{"class":1073},[1067,1288,1289],{"class":1096},"subnet-0a...",[1067,1291,1087],{"class":1073},[1067,1293,1294],{"class":1073},",",[1067,1296,1093],{"class":1073},[1067,1298,1299],{"class":1096},"subnet-0b...",[1067,1301,1087],{"class":1073},[1067,1303,1304],{"class":1073},"],\n",[1067,1306,1308,1310,1313,1315,1317,1319,1321,1324,1326],{"class":1069,"line":1307},13,[1067,1309,1189],{"class":1073},[1067,1311,1312],{"class":1192},"security_groups",[1067,1314,1087],{"class":1073},[1067,1316,1090],{"class":1073},[1067,1318,1284],{"class":1073},[1067,1320,1087],{"class":1073},[1067,1322,1323],{"class":1096},"sg-0ff...",[1067,1325,1087],{"class":1073},[1067,1327,1328],{"class":1073},"]\n",[1067,1330,1332],{"class":1069,"line":1331},14,[1067,1333,1334],{"class":1073},"    }\n",[1067,1336,1338],{"class":1069,"line":1337},15,[1067,1339,1340],{"class":1073},"  ],\n",[1067,1342,1344,1346,1349,1351,1353,1355,1358,1360],{"class":1069,"line":1343},16,[1067,1345,1080],{"class":1073},[1067,1347,1348],{"class":1083},"readiness",[1067,1350,1087],{"class":1073},[1067,1352,1090],{"class":1073},[1067,1354,1093],{"class":1073},[1067,1356,1357],{"class":1096},"green",[1067,1359,1087],{"class":1073},[1067,1361,1102],{"class":1073},[1067,1363,1365,1367,1370,1372,1374,1376,1379],{"class":1069,"line":1364},17,[1067,1366,1080],{"class":1073},[1067,1368,1369],{"class":1083},"updated_at",[1067,1371,1087],{"class":1073},[1067,1373,1090],{"class":1073},[1067,1375,1093],{"class":1073},[1067,1377,1378],{"class":1096},"2026-04-15T18:22:04Z",[1067,1380,1381],{"class":1073},"\"\n",[1067,1383,1385],{"class":1069,"line":1384},18,[1067,1386,1387],{"class":1073},"}\n",[1389,1390,1391],"tip",{},[885,1392,1393,1394,1397,1398,915],{},"Because state is event-sourced in the ",[904,1395,1396],{"href":54},"workflow engine",", every reconciliation step is an append-only transition with full history. You can replay exactly how a group reached its current shape rather than guessing from logs. See ",[904,1399,1400],{"href":54},"The workflow engine",[917,1402,1404],{"id":1403},"detecting-network-drift-pull-detect-surface","Detecting network drift (pull, detect, surface)",[885,1406,1407,1408,1411],{},"Network Management ",[889,1409,1410],{},"mirrors"," cloud topology locally so apps don't re-query each provider on every deploy. Drift is the gap between that mirror and reality, and it is detected by re-running the sync.",[1413,1414],"dag-diagram",{":edges":1415,":nodes":1416,"direction":1417},"[{\"from\":\"A\",\"to\":\"B\"},{\"from\":\"B\",\"to\":\"C\",\"label\":\"success\"},{\"from\":\"B\",\"to\":\"D\",\"label\":\"partial fail\"},{\"from\":\"C\",\"to\":\"E\"},{\"from\":\"D\",\"to\":\"E\"},{\"from\":\"E\",\"to\":\"F\"},{\"from\":\"F\",\"to\":\"G\",\"label\":\"yes\"},{\"from\":\"F\",\"to\":\"H\",\"label\":\"no\"}]","[{\"id\":\"A\",\"label\":\"Scheduled sync per connection\",\"kind\":\"start\"},{\"id\":\"B\",\"label\":\"Provider call\",\"kind\":\"cloud\"},{\"id\":\"C\",\"label\":\"Update inventory + discovered_at\",\"kind\":\"data\"},{\"id\":\"D\",\"label\":\"Mark slice stale\",\"sub\":\"keep last discovered_at\",\"kind\":\"data\"},{\"id\":\"E\",\"label\":\"Recompute readiness verdict\",\"kind\":\"engine\"},{\"id\":\"F\",\"label\":\"Verdict changed?\"},{\"id\":\"G\",\"label\":\"Emit network.readiness.changed\",\"kind\":\"data\"},{\"id\":\"H\",\"label\":\"No-op\"}]","LR",[885,1419,1420],{},"Key properties of network drift detection:",[1026,1422,1423,1429,1443,1457],{},[1029,1424,1425,1428],{},[889,1426,1427],{},"Pull-only, eventually consistent."," A network created directly in a cloud console appears only after the next sync — not instantly. Downstream products must tolerate \"not yet known.\"",[1029,1430,1431,1434,1435,1438,1439,1442],{},[889,1432,1433],{},"Per-region freshness, not all-or-nothing."," A provider error in one region/account does not invalidate prior data elsewhere; the failed slice is marked stale with its last successful ",[1037,1436,1437],{},"discovered_at",", surfaced as the ",[1037,1440,1441],{},"network.sync.age_seconds"," gauge.",[1029,1444,1445,1448,1449,1452,1453,1456],{},[889,1446,1447],{},"Silent SG drift is the hard case."," Security-group rules edited in the console are only picked up on the next sync. Between syncs the policy-violation view can under-report; ",[889,1450,1451],{},"on-demand re-sync"," (UI or ",[904,1454,1455],{"href":170},"MCP",") is the mitigation.",[1029,1458,1459,1462,1463,1466],{},[889,1460,1461],{},"No mutation, ever."," Orkestia is not an IPAM. It does not allocate CIDRs, reserve IPs, or touch route tables. Detected network drift produces a ",[889,1464,1465],{},"verdict and a notification",", not a corrective write.",[885,1468,1469,1470,1473],{},"When a profile's underlying connection or network vanishes, the profile is marked ",[889,1471,1472],{},"orphaned",": existing resolutions remain readable, but new launches are blocked until it is rebound — a deliberate fail-closed choice rather than letting a deploy land somewhere unknown.",[917,1475,1477],{"id":1476},"readiness-verdicts","Readiness verdicts",[885,1479,1480,1481,1484,1485,1489],{},"Every network and profile carries a deploy-ready verdict — ",[889,1482,1483],{},"green / yellow / red"," — so users see \"don't pick this\" ",[1486,1487,1488],"em",{},"before"," they pick it. The verdict is a rollup of several signals:",[925,1491,1492,1502],{},[928,1493,1494],{},[931,1495,1496,1499],{},[934,1497,1498],{},"Input signal",[934,1500,1501],{},"Pushes toward red",[947,1503,1504,1515,1523,1531,1543],{},[931,1505,1506,1512],{},[952,1507,1508,1509,1511],{},"Sync freshness (",[1037,1510,1441],{},")",[952,1513,1514],{},"Inventory stale beyond threshold",[931,1516,1517,1520],{},[952,1518,1519],{},"Quota headroom",[952,1521,1522],{},"Subnet effectively full / no IP space",[931,1524,1525,1528],{},[952,1526,1527],{},"Required tags",[952,1529,1530],{},"Mandatory governance tags missing",[931,1532,1533,1536],{},[952,1534,1535],{},"Security-group sanity",[952,1537,1538,1539,1542],{},"Rules violating baseline (e.g. ",[1037,1540,1541],{},"0.0.0.0/0"," on sensitive ports)",[931,1544,1545,1548],{},[952,1546,1547],{},"Connection health",[952,1549,1550],{},"Source connection orphaned / decommissioned",[885,1552,1553,1554,1557,1558,915],{},"A verdict flip emits ",[1037,1555,1556],{},"network.readiness.changed",", which drives UI badges and SLO probes through ",[904,1559,437],{"href":78},[995,1561,1562],{},[885,1563,1564,1565,1568],{},"A readiness verdict is ",[889,1566,1567],{},"advisory at resolution time, not a reservation."," Profile selection does not lock IPs or capacity. A subnet that reads green can fill between the readiness check and the actual launch — that surfaces as a provider error at launch, not a profile error. Readiness reduces the odds of a bad pick; it does not guarantee the placement.",[917,1570,1572],{"id":1571},"detecting-and-healing-runner-drift","Detecting and healing runner drift",[885,1574,1575,1576,1579],{},"Runners is where Orkestia ",[889,1577,1578],{},"acts",", because it owns the runner lifecycle. Drift here shows up in three forms, each with its own reconciliation path.",[1581,1582,1584],"h3",{"id":1583},"_1-scale-drift-desired-concurrency-vs-queue-reality","1. Scale drift — desired concurrency vs. queue reality",[885,1586,1587,1588,1591,1592,1595,1596,1599,1600,1603,1604,1607],{},"Scaling is ",[889,1589,1590],{},"reconcile-driven, not webhook-driven",". A per-group reconcile loop continuously converges the pool toward the group's ",[1037,1593,1594],{},"min","/",[1037,1597,1598],{},"max","; GitHub ",[1037,1601,1602],{},"workflow_job"," webhooks (handled by ",[1037,1605,1606],{},"runner.dispatch-from-job-queued",") are a best-effort nudge that triggers an immediate reconcile, not the source of truth.",[1058,1609,1611],{"className":1060,"code":1610,"language":1062,"meta":1063,"style":1063},"{\n  \"workflow\": \"runner.dispatch-from-job-queued\",\n  \"input\": {\n    \"group_id\": \"rg_01HXZ...\",\n    \"reason\": \"workflow_job.queued\",\n    \"queued_jobs\": 3,\n    \"current_runners\": 1\n  }\n}\n",[1037,1612,1613,1617,1636,1650,1671,1691,1706,1720,1725],{"__ignoreMap":1063},[1067,1614,1615],{"class":1069,"line":1070},[1067,1616,1074],{"class":1073},[1067,1618,1619,1621,1624,1626,1628,1630,1632,1634],{"class":1069,"line":1077},[1067,1620,1080],{"class":1073},[1067,1622,1623],{"class":1083},"workflow",[1067,1625,1087],{"class":1073},[1067,1627,1090],{"class":1073},[1067,1629,1093],{"class":1073},[1067,1631,1606],{"class":1096},[1067,1633,1087],{"class":1073},[1067,1635,1102],{"class":1073},[1067,1637,1638,1640,1643,1645,1647],{"class":1069,"line":1105},[1067,1639,1080],{"class":1073},[1067,1641,1642],{"class":1083},"input",[1067,1644,1087],{"class":1073},[1067,1646,1090],{"class":1073},[1067,1648,1649],{"class":1073}," {\n",[1067,1651,1652,1655,1658,1660,1662,1664,1667,1669],{"class":1069,"line":1126},[1067,1653,1654],{"class":1073},"    \"",[1067,1656,1657],{"class":1192},"group_id",[1067,1659,1087],{"class":1073},[1067,1661,1090],{"class":1073},[1067,1663,1093],{"class":1073},[1067,1665,1666],{"class":1096},"rg_01HXZ...",[1067,1668,1087],{"class":1073},[1067,1670,1102],{"class":1073},[1067,1672,1673,1675,1678,1680,1682,1684,1687,1689],{"class":1069,"line":1144},[1067,1674,1654],{"class":1073},[1067,1676,1677],{"class":1192},"reason",[1067,1679,1087],{"class":1073},[1067,1681,1090],{"class":1073},[1067,1683,1093],{"class":1073},[1067,1685,1686],{"class":1096},"workflow_job.queued",[1067,1688,1087],{"class":1073},[1067,1690,1102],{"class":1073},[1067,1692,1693,1695,1698,1700,1702,1704],{"class":1069,"line":1165},[1067,1694,1654],{"class":1073},[1067,1696,1697],{"class":1192},"queued_jobs",[1067,1699,1087],{"class":1073},[1067,1701,1090],{"class":1073},[1067,1703,1139],{"class":1138},[1067,1705,1102],{"class":1073},[1067,1707,1708,1710,1713,1715,1717],{"class":1069,"line":1180},[1067,1709,1654],{"class":1073},[1067,1711,1712],{"class":1192},"current_runners",[1067,1714,1087],{"class":1073},[1067,1716,1090],{"class":1073},[1067,1718,1719],{"class":1138}," 1\n",[1067,1721,1722],{"class":1069,"line":1186},[1067,1723,1724],{"class":1073},"  }\n",[1067,1726,1727],{"class":1069,"line":1209},[1067,1728,1387],{"class":1073},[885,1730,1731,1732,1735,1736,1595,1738,1740],{},"If a webhook is ",[889,1733,1734],{},"lost"," (network blip, redirect down in local dev), nothing is stranded — the webhook was only a nudge. The reconcile loop converges the group toward its desired ",[1037,1737,1594],{},[1037,1739,1598],{}," on its next pass regardless. This is self-healing by convergence: each reconcile drives toward the desired set rather than mutating a fragile counter, so correctness never depends on any single event arriving.",[1581,1742,1744],{"id":1743},"_2-health-drift-runners-that-are-registered-but-dead","2. Health drift — runners that are registered but dead",[885,1746,1747,1748,1751,1752,1755],{},"Runner groups run ",[889,1749,1750],{},"periodic liveness probes",". An unhealthy runner is ",[889,1753,1754],{},"deregistered from GitHub and its compute reaped automatically",", so dead runners don't sit registered and starve the queue. This is fully automated — no approval — because the action is unambiguously corrective and bounded to compute Orkestia provisioned.",[1058,1757,1761],{"className":1758,"code":1759,"language":1760,"meta":1063,"style":1063},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sequenceDiagram\n  participant HC as Health check\n  participant GH as GitHub\n  participant Cloud as Customer cloud\n  HC->>Cloud: probe runner liveness\n  Cloud-->>HC: unhealthy / unreachable\n  HC->>GH: deregister runner\n  HC->>Cloud: reap compute\n  HC->>HC: emit runner.group.unhealthy\n","mermaid",[1037,1762,1763,1768,1773,1778,1783,1788,1793,1798,1803],{"__ignoreMap":1063},[1067,1764,1765],{"class":1069,"line":1070},[1067,1766,1767],{},"sequenceDiagram\n",[1067,1769,1770],{"class":1069,"line":1077},[1067,1771,1772],{},"  participant HC as Health check\n",[1067,1774,1775],{"class":1069,"line":1105},[1067,1776,1777],{},"  participant GH as GitHub\n",[1067,1779,1780],{"class":1069,"line":1126},[1067,1781,1782],{},"  participant Cloud as Customer cloud\n",[1067,1784,1785],{"class":1069,"line":1144},[1067,1786,1787],{},"  HC->>Cloud: probe runner liveness\n",[1067,1789,1790],{"class":1069,"line":1165},[1067,1791,1792],{},"  Cloud-->>HC: unhealthy / unreachable\n",[1067,1794,1795],{"class":1069,"line":1180},[1067,1796,1797],{},"  HC->>GH: deregister runner\n",[1067,1799,1800],{"class":1069,"line":1186},[1067,1801,1802],{},"  HC->>Cloud: reap compute\n",[1067,1804,1805],{"class":1069,"line":1209},[1067,1806,1807],{},"  HC->>HC: emit runner.group.unhealthy\n",[1581,1809,1811],{"id":1810},"_3-state-drift-orphaned-runners-after-a-partial-teardown","3. State drift — orphaned runners after a partial teardown",[885,1813,1814,1815,1818,1819,1821,1822,1825,1826,1829],{},"The hardest case: a teardown DAG fails ",[1486,1816,1817],{},"after"," some cloud resources are destroyed but ",[1486,1820,1488],{}," GitHub deregistration. GitHub is left with ",[889,1823,1824],{},"zombie offline runners",". The ",[889,1827,1828],{},"reconciler sweeps on the next group health check",", reconciling GitHub's view back to actual compute. Outside the production providers (AWS, Azure, Kubernetes), treat orphan reconciliation as (beta).",[898,1831,1832],{},[885,1833,1834,1835,1838],{},"Runner ",[889,1836,1837],{},"registration is pull, not push."," Orkestia hands the runner binary a short-lived registration token and the binary calls GitHub itself; Orkestia only observes the result. So \"healing\" a registration means re-driving the desired set and letting runners (de)register themselves — Orkestia never force-writes GitHub's runner list out of band.",[917,1840,1842],{"id":1841},"what-is-automated-vs-surfaced-for-approval","What is automated vs. surfaced for approval",[885,1844,1845,1846,1849],{},"This is the governance boundary. The rule of thumb: ",[889,1847,1848],{},"Orkestia auto-heals only state it owns and only actions that are unambiguously corrective and bounded by your declared policy."," Everything else is surfaced.",[925,1851,1852,1865],{},[928,1853,1854],{},[931,1855,1856,1859,1862],{},[934,1857,1858],{},"Drift condition",[934,1860,1861],{},"Reconciliation",[934,1863,1864],{},"Approval needed?",[947,1866,1867,1886,1897,1907,1920,1942,1953,1964,1975],{},[931,1868,1869,1877,1883],{},[952,1870,1871,1872,1874,1875],{},"Job queued / completed → scale within ",[1037,1873,1594],{},"–",[1037,1876,1598],{},[952,1878,1879,1880],{},"Auto: ",[1037,1881,1882],{},"runner.scaling*",[952,1884,1885],{},"No — bounded by group policy",[931,1887,1888,1891,1894],{},[952,1889,1890],{},"Unhealthy runner detected",[952,1892,1893],{},"Auto: deregister + reap",[952,1895,1896],{},"No",[931,1898,1899,1902,1905],{},[952,1900,1901],{},"Orphaned/zombie GitHub runner after partial teardown",[952,1903,1904],{},"Auto: reconciler sweep (AWS GA; others beta)",[952,1906,1896],{},[931,1908,1909,1915,1918],{},[952,1910,1911,1912,1914],{},"Lost ",[1037,1913,1602],{}," webhook",[952,1916,1917],{},"Auto: reconcile loop converges on its next pass",[952,1919,1896],{},[931,1921,1922,1928,1936],{},[952,1923,1924,1925,1927],{},"Queue exceeds ",[1037,1926,1598],{}," runners",[952,1929,1930,1933,1934],{},[889,1931,1932],{},"Not"," auto-scaled past ",[1037,1935,1598],{},[952,1937,1938,1939,1941],{},"Surfaced — raising ",[1037,1940,1598],{}," is a human decision (protects your cost)",[931,1943,1944,1947,1950],{},[952,1945,1946],{},"Provider quota hit at scale-up",[952,1948,1949],{},"Scale-up DAG fails, surfaced",[952,1951,1952],{},"Surfaced — raising quota is a customer cloud action",[931,1954,1955,1958,1961],{},[952,1956,1957],{},"Network profile orphaned (connection/VPC gone)",[952,1959,1960],{},"Detect + block new launches",[952,1962,1963],{},"Surfaced — rebind is a human action",[931,1965,1966,1969,1972],{},[952,1967,1968],{},"Security-group drift / policy violation",[952,1970,1971],{},"Detect + flag verdict",[952,1973,1974],{},"Surfaced — Orkestia never edits your networks",[931,1976,1977,1980,1986],{},[952,1978,1979],{},"Stale network inventory",[952,1981,1982,1983],{},"Verdict → red + ",[1037,1984,1985],{},"readiness.changed",[952,1987,1988],{},"Surfaced (on-demand re-sync available)",[995,1990,1991],{},[885,1992,1993,1996,1997,1999,2000,915],{},[889,1994,1995],{},"Bounds are hard, not best-effort."," Orkestia will not exceed a group's configured ",[1037,1998,1598],{}," even if the queue keeps growing — protecting your spend is explicit. Likewise it never mutates customer networks. When self-healing would cross either line, it stops and surfaces rather than acting. For fleets of AI agents driving these workflows, that boundary is itself governed — see ",[904,2001,2002],{"href":64},"Staff governance",[917,2004,2006],{"id":2005},"observing-reconciliation","Observing reconciliation",[885,2008,2009,2010,2013,2014,2016],{},"Every detection and healing action is emitted as a ",[1037,2011,2012],{},"workflow.transition"," payload on the platform Kafka bus — the same bus as every other Orkestia signal — so ",[904,2015,437],{"href":78}," consumes them with no runner- or network-specific log stream.",[925,2018,2019,2031],{},[928,2020,2021],{},[931,2022,2023,2026,2028],{},[934,2024,2025],{},"Signal",[934,2027,936],{},[934,2029,2030],{},"Meaning",[947,2032,2033,2045,2061,2073,2085,2097,2109,2120],{},[931,2034,2035,2040,2042],{},[952,2036,2037],{},[1037,2038,2039],{},"runner.group.unhealthy",[952,2041,694],{},[952,2043,2044],{},"Health check failed for a group → reap path",[931,2046,2047,2056,2058],{},[952,2048,2049,2052,2053],{},[1037,2050,2051],{},"runner.group.scaled_up"," / ",[1037,2054,2055],{},"scaled_down",[952,2057,694],{},[952,2059,2060],{},"Scale reconciliation completed",[931,2062,2063,2068,2070],{},[952,2064,2065],{},[1037,2066,2067],{},"runner.group.archived",[952,2069,694],{},[952,2071,2072],{},"Teardown DAG completed",[931,2074,2075,2079,2082],{},[952,2076,2077],{},[1037,2078,1556],{},[952,2080,2081],{},"Network",[952,2083,2084],{},"Verdict flipped (green↔yellow↔red)",[931,2086,2087,2092,2094],{},[952,2088,2089],{},[1037,2090,2091],{},"network.sync.failed",[952,2093,2081],{},[952,2095,2096],{},"Provider call failed non-retryably",[931,2098,2099,2104,2106],{},[952,2100,2101],{},[1037,2102,2103],{},"network.profile.orphaned",[952,2105,2081],{},[952,2107,2108],{},"Target/connection disappeared on sync",[931,2110,2111,2115,2117],{},[952,2112,2113],{},[1037,2114,1441],{},[952,2116,2081],{},[952,2118,2119],{},"Continuous staleness gauge per connection/region",[931,2121,2122,2127,2129],{},[952,2123,2124],{},[1037,2125,2126],{},"network.policy.violations",[952,2128,2081],{},[952,2130,2131],{},"Continuous count of SG rules failing baseline",[885,2133,2134,2135,2137,2138,2141,2142,2145,2146,915],{},"You can also poll reconciliation state directly over ",[904,2136,1455],{"href":170}," — ",[1037,2139,2140],{},"list_stuck_workflows"," surfaces runs (including provisioning/scaling/teardown DAGs) that have stalled and may need a ",[1037,2143,2144],{},"retry_workflow",". See ",[904,2147,2148],{"href":459},"Observability with Lumen",[917,2150,2152],{"id":2151},"concurrency-why-reconciliation-is-safe","Concurrency: why reconciliation is safe",[885,2154,2155,2156,2159,2160,2163,2164,2166,2167,2169],{},"Provisioning, scaling, and teardown of the ",[889,2157,2158],{},"same"," runner group are serialized by a ",[889,2161,2162],{},"PostgreSQL advisory lock keyed on group ID"," — two reconcilers can never drive the same group into conflicting states. Different groups reconcile fully in parallel. All long-running provisioning, drain, and cloud-wait steps go through ",[1037,2165,2012],{}," on Kafka, consumed by the workflow consumer; there is no Celery in this path. This is the same concurrency model the ",[904,2168,1396],{"href":54}," applies everywhere.",[917,2171,2173],{"id":2172},"failure-modes-to-expect","Failure modes to expect",[2175,2176,2178],"callout",{"icon":2177},"i-lucide-alert-triangle",[885,2179,2180,2181,2184],{},"These are ",[1486,2182,2183],{},"known, bounded"," failure modes — the reconciler is designed so each degrades gracefully rather than wedging a group.",[1026,2186,2187,2197,2203,2209,2215],{},[1029,2188,2189,2192,2193,2196],{},[889,2190,2191],{},"Stale inventory used for a deploy."," A profile resolves to a network deleted in-cloud between syncs → launch fails at the provider. The verdict degrades to red on the ",[1486,2194,2195],{},"next"," sync; it does not retroactively stop the in-flight launch.",[1029,2198,2199,2202],{},[889,2200,2201],{},"GitHub App token expired/revoked."," New runners can't register; existing runners keep working until their own registration expires. Surfaced at the token-mint step.",[1029,2204,2205,2208],{},[889,2206,2207],{},"Provider quota at scale-up."," ECS task / EC2 instance / Cloud Run max-instances cap hit → scale-up DAG fails with a quota error; existing runners unaffected; queue backs up until quota is raised.",[1029,2210,2211,2214],{},[889,2212,2213],{},"Runner image unreachable."," Aggregated-registry metadata exists but the provider can't pull → scale-up fails at image pull; retryable.",[1029,2216,2217,2220],{},[889,2218,2219],{},"Network profile points to a decommissioned connection."," Profile marked orphaned; reads OK, new launches blocked until rebound.",[917,2222,2224],{"id":2223},"related-reading","Related reading",[2226,2227,2228,2234,2241,2247,2252,2257],"card-group",{},[2229,2230,2231],"card",{"icon":136,"title":694,"to":73},[885,2232,2233],{},"The runner control plane: groups, warm pools, executions, and the lifecycle that drift reconciliation operates on.",[2229,2235,2238],{"icon":2236,"title":2237,"to":196},"i-lucide-split","Hybrid execution model",[885,2239,2240],{},"How AI-designed workflows compile into the deterministic compositions that drive provisioning and scaling.",[2229,2242,2244],{"icon":220,"title":2243,"to":134},"Runner management",[885,2245,2246],{},"Day-2 operations: creating groups, setting scaling bounds, and reading health.",[2229,2248,2249],{"icon":80,"title":2148,"to":459},[885,2250,2251],{},"Consume the reconciliation signals and readiness verdicts emitted on the workflow bus.",[2229,2253,2254],{"icon":285,"title":914,"to":223},[885,2255,2256],{},"Where compute lives and why Orkestia reconciles rather than hosts.",[2229,2258,2261],{"icon":2259,"title":2260,"to":165},"i-lucide-book-marked","Workflow types registry",[885,2262,2263,2264,2267,2268,2271],{},"Per-workflow detail for ",[1037,2265,2266],{},"runner.*"," and ",[1037,2269,2270],{},"network.*"," — also at reference.orkestia.dev.",[2273,2274,2275],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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);}",{"title":1063,"searchDepth":1070,"depth":1077,"links":2277},[2278,2279,2280,2281,2282,2287,2288,2289,2290,2291],{"id":919,"depth":1077,"text":920},{"id":1016,"depth":1077,"text":1017},{"id":1403,"depth":1077,"text":1404},{"id":1476,"depth":1077,"text":1477},{"id":1571,"depth":1077,"text":1572,"children":2283},[2284,2285,2286],{"id":1583,"depth":1105,"text":1584},{"id":1743,"depth":1105,"text":1744},{"id":1810,"depth":1105,"text":1811},{"id":1841,"depth":1077,"text":1842},{"id":2005,"depth":1077,"text":2006},{"id":2151,"depth":1077,"text":2152},{"id":2172,"depth":1077,"text":2173},{"id":2223,"depth":1077,"text":2224},"How Orkestia reconciles desired and actual state for runners and network infrastructure in your cloud, computes readiness verdicts, and decides what to heal automatically versus surface for approval","md",null,{},{"icon":203},{"title":200,"description":2292},"oF6IKYg2hstXfS1kCotyj6dUwE-oczuoW2L7UojXTqs",[2300,2302],{"title":195,"path":196,"stem":197,"description":2301,"icon":198,"children":-1},"How Orkestia lets AI design workflows at runtime, then compiles those plans into deterministic virtual workflows that run repeatably, cheaply, and auditably",{"title":205,"path":206,"stem":207,"description":2303,"icon":208,"children":-1},"How Orkestia enforces role-based authority, human-in-the-loop approval gates, and an immutable evidence trail over fleets of autonomous AI agents",1790354045583]