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_versionguards 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-regressiondiagnostic 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
| Step | CLI | HTTP | Native tool |
|---|---|---|---|
| Describe | agh loop inspect | GET /loops/:name | agh__loop_inspect |
| Validate | agh loop validate | POST /loops/:name/validate | agh__loop_validate |
| Dry-run | agh loop run --dry-run | POST /loops/:name/run?dry=true | agh__loop_run (dry: true) |
| Publish | agh loop create --file … --expected-version … | PATCH /loops/:name | agh__loop_create (expected_version) |
| Run | agh loop run | POST /loops/:name/run | agh__loop_run |
See the CLI reference and the Loops API for exact flags and payloads.
Configure
Adjust how a Loop runs — its checks, its human gate, its re-attempt strategy, and its stop limits — without changing its structure.
Visual editor
Fork a Loop and edit its body on a canvas — nodes, edges, a per-node inspector, an inline linter, and a Graph/DSL toggle over one canonical definition.