A provider-agnostic harness for bounded, human-in-the-loop agent work. The agent can plan, edit, and test. Its state lives in Git-tracked markdown, and it must stop when requirements are ambiguous. That keeps the workflow auditable with ordinary engineering practice instead of burying it in a chat transcript or a vendor memory layer.
Each run is one discrete unit of work. The agent wakes up, reads local markdown, executes a single backlog item, serializes state, commits, and exits. The human steers between runs.
graph TD
H[Human Operator] -->|1. Steer| B[backlog.md]
H -->|2. Resolve| TBD[tbd-response.md]
B -->|3. Pop Task| A[CLI Agent]
TBD -->|3. Intake| A
A -->|4. TDD Cycle| FS[Filesystem]
A -->|5. Handover| HO[handover.md]
A -->|6. Commit| Git[Git History]
HO -->|7. Review| H
If planning and standards conflict, the agent does not guess:
- It stops.
- It writes
docs/state/tbd.md. - It exits cleanly.
The next run proceeds only after you add tbd-response.md. See the visual demo.
Use the same prompt with any capable CLI. The provider is not part of the harness state model.
Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state.
| Provider | Headless command |
|---|---|
| Grok Build | grok -p "…" --always-approve --max-turns 15 |
| Claude Code | claude -p "…" --dangerously-skip-permissions --max-turns 15 |
| Gemini CLI | gemini -m gemini-2.5-pro --approval-mode yolo -p "…" |
| OpenAI Codex | codex exec --dangerously-bypass-approvals-and-sandbox "…" |
| Aider | aider -m "…" --yes --no-gitignore --model <provider>/<model> |
| OpenCode | opencode run --dangerously-skip-permissions --log-level WARN "…" |
Copy-paste examples:
# Grok Build
grok -p "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state." --always-approve --max-turns 15
# Claude Code
claude -p "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state." --dangerously-skip-permissions --max-turns 15
# Gemini CLI
gemini -m gemini-2.5-pro --approval-mode yolo -p "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state."
# OpenAI Codex
codex exec --dangerously-bypass-approvals-and-sandbox "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state."
# Aider
aider -m "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state." --yes --no-gitignore --model <provider>/<model>
# OpenCode
opencode run --dangerously-skip-permissions --log-level WARN "Read .agents/skills/agent-loop.md and execute the next run strictly from the repository's local markdown state."Prefer a turn cap (--max-turns 15 or equivalent) when the provider offers one. Full notes, model strings, and endpoint caveats live in the outer-loop playbook.
Node (any OS):
npx @nikcholer/agentic-loop-harness initFrom a clone:
# Windows / PowerShell Core (recommended operator path)
pwsh -File .\init-trial.ps1
# Linux / macOS
./init-trial.shThen populate docs/planning.md and docs/state/backlog.md, run the pre-run ritual below, and invoke one of the commands above from the trial repo root.
- Copy
docs/agent-loop/skill.mdto.agents/skills/agent-loop.md. - Seed
docs/state/from the templates. - Write project-specific rules in
docs/agent-loop/standards.md. That file is a per-project slot, not a universal rulebook.
See the deployment guide for the full bootstrap checklist.
Start every loop from a tree you understand:
git status
# clean tree preferred
# portable
npx @nikcholer/agentic-loop-harness health
# or, from a clone
pwsh -File scripts/check-health.ps1
# bash scripts/check-health.shIf docs/state/tbd.md exists without a matching tbd-response.md, do not start another run.
| Command | What it does |
|---|---|
npx @nikcholer/agentic-loop-harness init |
Scaffold a trial repo or inject the harness into an existing one |
npx @nikcholer/agentic-loop-harness health |
Fail closed on unresolved TBD or a dirty worktree |
npx @nikcholer/agentic-loop-harness run --provider grok --max-runs 15 |
Keep invoking while runs succeed; stop on TBD, error, dirty tree, or the cap |
scripts/check-health.ps1 / scripts/check-health.sh |
Same health gate without Node |
scripts/run-loop.ps1 / scripts/run-loop.sh |
Same bounded outer loop without Node |
scripts/archive-backlog.ps1 |
Archive completed backlog sections (human-only) |
scripts/inject-skill.ps1 |
Copy optional skills listed under ## Skills in planning.md |
PowerShell Core is the richest operator path. init, health, and run are also first-class on bash and via the Node CLI.
Sample-NYCTraffic-Refresh was delivered entirely through this harness.
- Auditability: every commit maps to a verified backlog item.
- Reliability: an agent refactored a legacy API and left 15 passing tests.
- Control: the agent paused three times for human clarification and never produced a hallucinated commit.
The loop enforces Red -> Green -> Refactor. A typical docs/state/progress.md slice looks like this:
## [2026-04-17] Sprint 1: API Refactor
- [x] Create failing test for `GET /api/v1/traffic` (Red)
- [x] Implement basic controller logic (Green)
- [ ] Refactor middleware for performance (Refactor - In Progress)Agent CLIs are better than they were a year ago. They still hide state in sessions, vendor memory, and JSON event streams. That is fine for pairing. It is a liability when you need a reviewable trail, a stop point a junior engineer can understand, and the freedom to swap Grok, Claude, Gemini, or a cheaper OpenAI-compatible model between runs.
This harness treats markdown in Git as the source of truth. ACP / stream-json output is telemetry. The commit is the record.
- Runtime contract:
docs/agent-loop/skill.md - Human operator playbook:
docs/agent-loop/outer-loop-playbook.md - Visual demo and case studies:
docs/portfolio/visual-demo.md - Compliance checklist:
tests/compliance/README.md
MIT. Built for the evolving agentic coding landscape.
