Skip to content

Implementor with a local step

An agent that reports success is not evidence of success. This workflow puts a shell command between the implementor and the terminal, so the run routes on what the machine observed rather than on what the agent said.

An authenticated harness and a local Git project folder.

implement → observe. The command routes an unchanged folder into repair and a changed one into a successful terminal.

implement → observe. The command routes an unchanged folder into repair and a changed one into a successful terminal.

observe is a parallelogram with a script. The script runs once through bash -c in the primary working folder, inherits the server environment, and prints one JSON object as its final stdout line. facts="change.present:bool,change.summary:text" declares exactly the keys that object contains, and Orbital rejects a final line that does not match.

The check here asks git whether the working folder has uncommitted changes. Replace it with your project’s own check, such as its test or lint command, and declare whatever facts that command can report. Keep the script read-only when it only inspects something, and give it a timeout shorter than the default ten minutes when the command is quick.

Four edges leave observe and each covers a different outcome. outcome == 'failed' catches the script itself failing on a timeout, a non-zero exit or a malformed final line. change.present == false starts a repair round, bounded by repair_budget="local_check" and its exhausted partner. change.present == true succeeds and resets the budget. The bare fallback is required because a command node cannot infer its own coverage the way a choice-producing agent can.

Download all files. Create a local Git practice repository. It needs no remote:

Terminal window
mkdir -p ~/orbital-local-step/.orbital
git init ~/orbital-local-step
cd ~/orbital-local-step

Extract the archive into ~/orbital-local-step/.orbital/. Keep every relative path. From ~/orbital-local-step run:

Terminal window
orbital validate .orbital/workflow.dot

Add the project folder in Orbital. On New run select the project and workflow graph, choose your authenticated harness, set work to what you want changed, and supply the goal.

An implementor that changes a file reaches the successful terminal on the first observation. An implementor that changes nothing is sent to repair and observed again, up to five rounds, before the run ends failed. A script that cannot run at all ends failed at a separate terminal, so the two causes stay distinguishable in the transcript.

Every DOT file below is a complete runnable graph. The archive contains the same files. Prompt files are companions, not separate workflows.

workflow.dot
digraph local_step {
graph [version="1", entry="implement", inputs="work", description="Implement a change and prove it with a local command before finishing", max_visits="40"]
implement [prompt="Implement the change described by {{ inputs.work }}. Change the files the work needs. Do not commit.", outputs="implementation_summary:text"]
observe [shape="parallelogram", script="if git status --porcelain | grep -q .; then echo '{\"change.present\":true,\"change.summary\":\"the working folder has uncommitted changes\"}'; else echo '{\"change.present\":false,\"change.summary\":\"the working folder is unchanged\"}'; fi", facts="change.present:bool,change.summary:text", timeout="2m"]
repair [prompt="A local command observed that {{ context.change.summary }}. The reported work was: {{ context.implementation_summary }}. Change the files the work actually needs.", outputs="repair_summary:text"]
observed [shape="Msquare", outcome="success"]
unchanged [shape="Msquare", outcome="failed", label="No change after five repairs"]
broken [shape="Msquare", outcome="failed", label="The local command itself failed"]
implement -> observe
observe -> broken [condition="outcome == 'failed'", weight="4"]
observe -> repair [condition="change.present == false", weight="3", repair_budget="local_check", repair_round="retry"]
observe -> unchanged [condition="change.present == false", weight="2", repair_budget="local_check", repair_round="exhausted"]
observe -> observed [condition="change.present == true", weight="1", repair_budget="local_check", repair_round="reset"]
observe -> broken
repair -> observe
}

Download workflow.dot

See context for fact declarations and error handling for repair budgets.