Agister · runs

Agister's run architecture

A run is what agister run leaves: a request that resolved, every step called on its runtime in a worktree Agister holds, and a record of who did what with what. Settings say what may run; this page says how it runs. The settings architecture is the half before it.

From a command to a record

cli settings/resolve composition plan · what is not run core/workflow items, in order runstore record · events core/call · admit runtime wrappers bash · claude-code · codex supervisor git · the worktree items, plans record events a workflow item: a child run, in its own boundary a step's call hold, HEAD, content
An arrow is a call through a port; the composition, in cmd/agister, wires every one. Core knows no settings file, no git and no runtime: it is given a workflow of items and a caller, and tells what happens to an events port.

A run starts from a request: a workflow with its params, or a process on an agent, with --continue or --reuse naming an earlier run. Resolve turns it into definitions or a refusal. The composition plans every step, those in branch arms a run may not take included, and lists what this Agister does not run yet. A refusal of either kind ends the command before anything runs and before any record.

agister check shares that list, so it refuses exactly what a run would.

What a workflow's items do

ItemRunsIts outputs
stepone call of its process on its agentthe call's output, checked against the process's schema
parallelits steps and workflows at once, or max at a time; one that fails does not stop the next; at least one must completea list, in declared order, of each one's status, class and output
branchthe first arm whose if holds, else the arm with nonethe arm's output mapping
repeatits body, then binds next over its state, then reads until; again until it holds or max passes have run; never reads until before the first pass{"state", "stopped", "passes"}: the last state, until or max, and how many passes ran
workflowanother workflow, as a child run: its inputs resolve when it starts, over the params the item binds, in its own boundary; its steps are called as <item>/<step>, with the pass where the item is in a repeatits outputs; one output named output is given whole

Items sit anywhere an item may: in the workflow's steps, an arm, a repeat's body; a parallel holds steps and workflows. A condition is pure: it reads params, inputs, a repeat's state and the outputs of items already ended, with equals, present, all, any, and, or and not. A number never equals a string, and params and inputs are strings. A repeat's body sees the state of the repeats around it, its own over theirs; a name next does not bind keeps its value.

fix/2/1A step in a repeat is named by its pass, <step>/<pass>, outer passes first where repeats nest. The call, its record entry, its progress line, its events and reuse all use that name; its plan is found by the name it is declared by.
tests/revise/1A step inside a workflow item is named under the item, with its pass where it is in a repeat. The child's steps are planned as <item>/<step> before anything runs.

A call

A call is one step executed. core/admit holds its worktree first, as a reader or a writer, checks a pinned revision and a clean worktree where the process asks, and keeps the call to its limits and the day's budget. core/call then makes turns on the runtime through its wrapper and the supervisor, which starts the program, keeps the ends of its output and ends its whole group.

  • capacityA turn at capacity is made again, after 30 s, 1, 3 and 5 minutes, each telling the session to go on; then the call starts fresh on its agent's fallback, if it names one.
  • staleA turn that goes stale is followed by a recovery turn in its session, where the process allows a resume.
  • sessionA call may continue an earlier step's session, by a binding; it goes on from where that session's latest call left the worktree.
  • costEach turn counts its own cost, claude-code's as reported, codex's priced through ccusage, against the process's limit and the daily budget.

At its end a call keeps the HEAD and content it left, and, where it pinned a revision, its changes as a patch.

What a run leaves

Each run is a folder under ~/.agister/runs, named by its id: its start's UTC time and six random hex characters.

record.jsonThe request, status and result. Every call ended, as <run id>/<step>, with its process, agent, inputs, permission plan, environment, definition files by digest, HEAD and content, cost and result. Under children, each child run, as <run id>/<item>, with its workflow, params, inputs and their identities, status and output. Written whole as each call ends; lost until the run ends.
events.jsonlA line per event as it happens: a step started, reused, a tool call, a stale turn, a turn at capacity, a fallback, a step ended; a branch's arm with each condition read, its values and whether it held; a repeat's pass with its state, and why it stopped; a child run started, with its params and inputs, and ended, with its status and output.
definitions/The bytes of every settings file a call was made from, by digest.
patches/Each pinned call's changes, by its name.

Progress goes to stderr as it happens: a line per step started and ended, · <branch>: took <arm>, · <repeat>: ended pass <n> and · <repeat>: stopped <why> after <n> passes. The result, on stdout, is JSON. agister runs export copies a run out.

Running again

--reuse <run id>runs a request again and takes an earlier call of the same name, and pass, in place of making it, where its process, agent, inputs, definitions and environment are the same and the worktree is as that call left it. A call that continues a session, or whose session is continued, is made again.
--continue <run id>goes on in the session of a one-step run's call.

What Agister does not do

Agister runs what settings define and records it. Committing, pushing, deciding what a review's findings mean and asking the owner stay with whoever calls it. It does not yet run a branch or repeat inside a parallel, or a turn on pi; check and run refuse them alike.

The parts

PackageOwnsPorts
clithe command line to a requestnone
core/workflowitems in order: steps, parallels, branches, repeats, workflow items; conditions, bindings, pass namesresolver; caller; events; clock
core/calla call's turns: capacity, recovery, fallback, cost, schemaruntime turn; clock
core/admitholding a worktree, a pin, a clean worktree, limits and the daily budgetgit facts; spend
core/inputsa process's inputs from their sources: a file, a revision, changed files, a brieffiles; git
core/watchwhether a turn has gone stale: a tool call repeated, a tool command or the whole turn silent too longclock; timer
runtime/*one turn on bash, claude-code or codexsupervisor
supervisora program's group: start, output, endstarter; timer
runstoreruns on disk: record, events, definitions, patches, exportfilesystem
gita worktree's root, HEAD, content, revisions and diffsgit
cmd/agisterthe composition: settings to core's items, plans, what is not run, the caller, the recordall of the above