Runner Contract
AYNIG Runner Contract (v0)
This document defines the minimum responsibilities of the AYNIG runner. AYNIG does not implement workflows or policies; it provides a deterministic, Git-based execution mechanism that other tools can build on.
The canonical contract lives at the repository root in CONTRACT.md.
The source of truth is always the Git branch (local or remote in remote mode).
1. Model
AYNIG interprets each commit as a state event.
A commit contains:
- title → human-only (ignored by the system)
- body → prompt delivered to the command
- trailers → structured metadata
The mandatory trailer is:
dwp-state: <state>The <state> value is the key used to select the command to execute.
AYNIG:
- reads
HEAD - extracts trailers
- selects the command
- executes it
- checks the result by looking only at the new
HEAD
AYNIG never interprets business semantics.
2. Command selection
dwp-state: <state> → executable command.
AYNIG does not define what a state means; it only uses it to select a command. Meaning belongs to your workflow.
3. Execution
The command receives:
- body (prompt)
- trailers
- commit hash
- runner configuration
Metadata is delivered as environment variables.
AYNIG:
- does not modify the repository during execution
- does not infer the next state
- does not interpret business semantics
The command declares the next state by emitting a line on stdout:
SET_STATE {"state":"review","subject":"review: ready","body":"..."}AYNIG watches stdout, keeps the last valid SET_STATE line it sees, and
creates the final commit after the command exits successfully.
The payload may include "keep_trailers": true to preserve existing
non-reserved dwp-* trailers from the current working commit.
If the command exits non-zero, AYNIG ignores any observed SET_STATE line and
marks the branch as stalled with diagnostic context from stdout/stderr.
If the command exits zero without emitting a valid SET_STATE, AYNIG writes a
fresh working commit with the same trailers to keep the lease alive while
waiting for any spawned follow-up process.
4. Working lease (one runner at a time)
AYNIG prevents two runners from working on the same branch at the same time by using Git commits.
Before executing, the runner creates a commit:
dwp-state: workingand pushes it to the branch.
If the push fails (the branch advanced), another runner won the execution → abort.
This behaves like a remote compare-and-swap without external coordination.
Reserved working trailers
dwp-state: workingdwp-origin-state: <state>dwp-run-id: <uuid>dwp-runner-id: <host-id>dwp-lease-seconds: <ttl>Reason: enable distributed runners without local locks.
5. Lease and liveness
While executing, the command must renew the lease:
- all intermediate commits →
dwp-state: working - same
dwp-run-id - implicit heartbeat update (committer date)
AYNIG uses the committer timestamp of HEAD as the liveness signal.
Takeover is allowed when:
HEAD == workingandnow > committer_date + lease-seconds (+grace)Reason:
- prevent permanent blocking
- avoid dependence on local processes
- tolerate machine crashes
History is never scanned.
6. Valid completion
A step is valid when, after execution:
HEADcontainsdwp-state: <state>state != working
That commit is the step output.
AYNIG does not search previous commits nor attempt to reconstruct history. It only observes the latest state.
Reason: avoid duplication, loops, and temporal ambiguity.
7. Takeover
If a runner finds:
dwp-state: workinglease expiredit may recover the branch by creating:
dwp-state: stalleddwp-stalled-run: <run-id>dwp-origin-state: <state>and continue evaluation.
Reason: self-healing system without external coordination or mandatory human intervention.
8. What AYNIG does not do
AYNIG does not:
- retry commands
- define workflows
- interpret states
- scan history
- decide merges
- resolve semantic conflicts
- guarantee task success
Those belong to tools and workflows built on top.
Reason: keep AYNIG small, deterministic, and universal.
9. System guarantees
AYNIG guarantees:
- A single active executor per branch
- Auditable execution (everything is a commit)
- Recovery after crashes
- HEAD-based determinism
- Distributed compatibility without external services
Summary
AYNIG turns Git into:
- a place to store workflow events
- a distributed lock
- a state machine
The runner acts as a simple loop: execute → check → observe.
All intelligence lives above it.