Engine-neutral durable backlog loop for Claude Code CLI and Codex CLI. One canonical workflow and state contract; thin per-engine skill adapters. No OpenClaw dependency at runtime or install time.
goal-loop is the outer durable orchestrator (selection, contract, ledger,
lock, recovery, authority, reconciliation, resume). Since v0.2.0 the
installed agent-pipeline skill is the mandatory inner executor: every
selected issue is owned by the pipeline from planning through
pipeline:ready-to-deploy (Claude: /pipeline, Codex: $pipeline). If
the pipeline skill or its preflight is unavailable, the run fails closed.
state.py— stdlib-only CLI owning all durable run state (contracts, ledger, exclusive lock, append-onlyevents.jsonl, decisions, merge barrier, pipeline preflight). State lives under${XDG_STATE_HOME:-~/.local/state}/goal-loop(override withGOAL_LOOP_STATE_HOME).workflow/LOOP.md— the canonical workflow both engines follow.adapters/claude/,adapters/codex/— thin skill projections; the Codex one carriesagents/openai.yamlper Codex skill conventions.schemas/— JSON Schema for the contract and ledger (@2).fixtures/discovery.json— example discovery input (also installed asreferences/discovery.example.json).install.py— idempotent installer/uninstaller with an ownership manifest and sha256 checksums.
python3 install.py install # both engines, into $HOME
python3 install.py install --engine claude
python3 install.py install --upgrade # safe upgrade of a managed install
python3 install.py verify
python3 install.py uninstallTargets: ~/.claude/skills/goal-loop and ~/.codex/skills/goal-loop.
Use --prefix DIR or GOAL_LOOP_INSTALL_PREFIX to redirect (tests do).
The installer refuses to touch unmanaged directories and never overwrites
files its manifest does not own.
- Atomic writes (temp file + fsync + rename) and an append-only event log.
- One exclusive lock per run; stale locks are inspectable and recoverable, live locks are never silently stolen.
- Mandatory agent-pipeline execution: contracts compile with a fixed
execution.mode = agent-pipelineblock (engine-neutral:/pipelineand$pipelineinvocations, deterministicpipeline.mjsentrypoints, preflight and merge-surface commands).state.py pipeline-preflightfails closed (exit 7) when the installed skill is missing; enteringin_progressrequires preflight-pass evidence, andreadyrequires verifiedpipeline:ready-to-deploystage evidence. - Authority gates (push/PR, merge, release, deploy) require explicit contract grants plus direct evidence; broad objectives grant nothing. Without the merge grant, items stop at ready-to-deploy.
- Serialized merge → refresh → next: with the merge grant, merges go
only through the pipeline merge surface; a
mergedtransition sets a ledger merge barrier that refuses to start the next item (exit 6) until a reconcile proves the merged SHA is reachable from a refreshed base. - Recovery budgets per blocker theme and terminal stop conditions.
- Resume from disk + live repo truth; both engines compile byte-identical canonical contracts from the same discovery.
python3 -m unittest discover -s tests -v