Three round trips for zero decisions
A pipeline of lint → test → build → deploy has exactly one decision in it: whether to deploy. The first three steps either pass or fail. But a naive agent reads each result, reasons about a “choice” that doesn’t exist, and burns a full round trip each time — latency and tokens spent rubber-stamping outcomes.
Tag the computable steps; the kernel chains them
Every transition carries an actor — it says who performs the step: code (actor: deterministic), the model (actor: agent), or a person (actor: human). Mark the computable steps deterministic and the kernel runs them back-to-back on its own, threading each result into the next, and only surfaces to the model when it reaches a step that needs judgment.
states:
lint:
transitions:
run_lint: { target: test, actor: deterministic }
test:
transitions:
run_tests: { target: build, actor: deterministic }
build:
transitions:
package: { target: ready, actor: deterministic }
ready:
transitions:
deploy: { target: live, actor: agent } # the chain stops here
The model calls praxec.command once and the response arrives at ready — three real commands run, zero LLM round trips, with a chain trace attached. The model is only consulted where a decision actually lives: whether to deploy.