Skip to content
Loops
AGH RuntimeLoops

Authoring loop

The safe path to change a Loop — describe, validate, dry-run, then publish with a compare-and-swap version — with no LLM spend before you run.

Audience
Operators running durable agent work
Focus
Loops guidance shaped for scanability, day-two clarity, and operator context.

Changing a Loop follows one loop, whether you drive it by hand, from an agent, or through the visual editor: describe → validate → dry-run → publish → run. Every step before run is structured and spends no model tokens, so you learn a definition is wrong before it ever costs anything.

Describe

Read the current definition — its declared inputs, contract, start bindings, and version. agh loop inspect --name <loop>, GET /loops/:name, or agh__loop_inspect. This is where you learn the version you will need to publish safely.

Validate

Lint and compile a candidate definition without saving it. agh loop validate --file loop.yaml, POST /loops/:name/validate, or agh__loop_validate. You get per-node errors with deterministic codes — unknown_reference, node_id_invalid, verdict_policy_requires_judge, fan_out_ceiling_exceeded, and the rest. Nothing is persisted.

Dry-run

Resolve inputs and render the first generation's plan without starting a run. agh loop run --name <loop> --dry-run, POST /loops/:name/run?dry=true, or agh__loop_run with dry: true. It spends no budget, creates no run row, and returns a plan preview — resolved inputs, the generation-1 nodes, the contract, and the effective config.

Publish (compare-and-swap)

Persist the definition with expected_version set to the version you read in step one. PATCH /loops/:name (or agh__loop_create with expected_version). Publish is atomic — lint, compile, and save the resolved form the runtime consumes. If the stored version has moved since you read it, the write is rejected 409 with the current version, so two authors never silently clobber each other.

Run

Start it — agh loop run --name <loop>, POST /loops/:name/run, or agh__loop_run. Now, and only now, the Loop spends tokens.

Two write paths

A definition lives on the filesystem ($AGH_HOME/loops, a workspace's .agh/loops, plus read-only extension resources such as dev-cycle). There are two ways to change one:

  • HTTP PATCH / native tool — the atomic, compare-and-swap path. expected_version guards it, so concurrent or multi-agent editing is safe. Use this for anything programmatic.
  • Filesystem write — write the YAML file directly and the syncer re-projects it on save. This is the single-operator, local-editor path. It is last-write-wins at the file level: the syncer surfaces a version-regression diagnostic when a projected version moves backward, but it cannot reject a write that already happened.

Publish always compiles a resolved definition and pins (version, checksum, published_at, actor). The coordinator and executors hydrate only from that resolved projection — they never re-parse the author YAML mid-run — so a run's behavior is fixed at publish time.

Fork, then edit

New Loops start as a fork of an existing one — there is no blank-canvas builder. Fork a read-only or workspace Loop with agh loop create --fork-from-name <name> (or the editor's Fork & edit), then change its body and publish. All three authoring surfaces — file, agent, and the visual editor — write the same canonical definition; there is no parallel authoring path.

Where each step lives

StepCLIHTTPNative tool
Describeagh loop inspectGET /loops/:nameagh__loop_inspect
Validateagh loop validatePOST /loops/:name/validateagh__loop_validate
Dry-runagh loop run --dry-runPOST /loops/:name/run?dry=trueagh__loop_run (dry: true)
Publishagh loop create --file … --expected-version …PATCH /loops/:nameagh__loop_create (expected_version)
Runagh loop runPOST /loops/:name/runagh__loop_run

See the CLI reference and the Loops API for exact flags and payloads.

On this page