loop-orchestration · git:20260613.a22966d · 2026-06-13 · sha256 e4c8f1db49a78d59
loop-orchestration git:20260613.a22966dA
Immutable. This exact content is served forever at /api/v1/blob/e4c8f1db49a78d59.
--- name: loop-orchestration description: Reference loop-orchestration example; a local loop host chains governed runx turns through receipts, budgets, context, and stop policy. --- # Loop Orchestration This example shows the runx pattern for long-running agent work: 1. An outer loop host decides whether work should continue. 2. Each iteration submits one normal governed runx turn. 3. Each turn seals a receipt before the loop can advance. 4. The next turn consumes only explicit inputs, projection state, and receipt summaries. Nothing in this example adds a loop engine to `runx-core`. The loop host is just an application script. In production it could be a hosted service, Temporal workflow, LangGraph app, n8n workflow, or another orchestrator. ## Run It ```sh sh examples/loop-orchestration/run.sh ``` The script runs three demonstrations: - **success:** two governed turns complete a tiny build-review loop; - **refusal:** a requested tool is outside the loop policy, so the loop stops before another turn is submitted; - **context gate:** an agent-task turn pauses with digest-bound skill context and explicit `allowed_tools`, showing what a host or managed provider would receive without requiring a model key. The output prints each run id, receipt id, decision, and next-turn reason. ## What This Proves The important boundary is not the Node script. It is the contract: - A **loop** owns scheduling, durable loop state, projection, and stop policy. - A **turn** is one runx skill/graph run with explicit authority and one sealed receipt. - A **handoff** is an artifact/result the loop host can inspect; it is not hidden prompt continuation. - A **projection** is derived from receipts and admitted signals, not from ambient memory. ## Security Rules - The loop has a max-turn budget. - The turn runner receives only declared inputs. - Tool choices are checked against loop policy before another turn is allowed. - Context skills are advisory, digest-bound, and untrusted. - A pause or refusal is a healthy result; the loop does not keep prompting until it gets the answer it wants. ## Adapting The Example Replace `loop/loop-host.mjs` with your real orchestrator and keep the same shape: ```text load projection -> submit runx turn -> read receipt/result -> check stop policy ``` Do not move product-specific scheduling or state into the kernel. If a loop needs to wake up later, persist the loop state in the host and submit another runx turn when policy allows.