/harness
Harness Engineering minimal practice. Use three constraints (Inspector, Worker, Reviewer) to channel AI's creativity onto the right track, driven by a shared TODO.md kanban for continuous improvement. Inspired by the Harness Engineering methodology: a lightweight but deterministic process framework that turns an AI Agent from "free exploration" into "predictably delivering high-quality results."
Trigger Conditions
Immediate Execution
- User types
/harness— full cycle (Inspector + Worker + Reviewer loop) - User types
/harness inspect— run Inspector only - User types
/harness work— run Worker + Reviewer once - User types
/harness loop— continuously run Worker + Reviewer until no tasks remain
Users can append natural language instructions after the command as extra context for the current cycle. For example:
/harness focus on silent data loss this time/harness work fix P0 environment variable check first/harness inspect only calibrate current skeleton goals, do not execute Worker
Scheduled (Cron)
Uses Claude Code's built-in CronCreate/CronDelete/CronList tools, which are naturally session-isolated — crons from different sessions do not interfere.
| Command | Description |
|---|---|
/harness cron "*/30 * * * *" | Run full cycle every 30 minutes |
/harness cron "*/30 * * * *" inspect | Run Inspector only every 30 minutes |
/harness cron "0 */2 * * *" work | Run Worker + Reviewer every 2 hours |
/harness cron "*/15 * * * *" loop | Continuously digest tasks every 15 minutes |
/harness cron list | List all harness crons in the current session |
/harness cron stop <job_id> | Delete a specific cron |
/harness cron stop | Delete all harness crons in the current session (interactive confirmation, then one by one) |
Limitations:
- Cron jobs are only active while the Claude Code session is alive; they expire when the terminal is closed.
- Recurring jobs automatically expire after 7 days.
- Fires only when REPL is idle; will not interrupt an ongoing conversation.
Three-Role Protocol
Core Principle: Verify Outputs
Each role must verify its own outputs; it is not enough to just "be done."
- Inspector: After creating tasks, verify that descriptions are clear enough and hints are actionable.
- Worker: After fixing code, run relevant checks as defined in project documentation (
AGENTS.md/CLAUDE.md/TODO.md/ README, etc.); if the project defines end-to-end or real-flow validation, it must be executed and the results recorded. - Reviewer: During review, confirm that the Worker has executed the verification commands related to the changes; if the project defines end-to-end or real-flow validation and the change affects that path, reject or request a re-test if not done.
End-to-end validation is not optional. If the project has no specific E2E/real-flow validation, or it cannot be executed due to unavailable external dependencies, the reason must be explicitly documented.
Inspector (Planner) — Decide direction, discover tasks
↓ Write to TODO.md
TODO.md (Shared Kanban)
↓
Worker (Fixer) — Claim tasks, change code
[Available] → [In Progress] → [Pending Review]
↓
Reviewer (Auditor) — Review code, decide to commit or reject based on project rules
Pass → Done Log + (only if allowed) git commit
Fail → [Rejected] + fix instructions
↓
Worker re-claims [Rejected]...
Task State Machine
| Marker | Meaning | Who Can Change |
|---|---|---|
[Available] | Not claimed | Inspector can add/modify, Worker can claim |
[In Progress] | Worker is working | Set by Worker when claiming; others do not touch |
[Pending Review] | Worker finished | Set by Worker when done; Reviewer reviews |
[Rejected] | Reviewer sent back | Set by Reviewer on rejection; Worker can reclaim |
Execution Steps
Step 1 — Parse User Instruction
Extract from user input:
- Is it cron mode?: Input contains
cronkeyword - Mode: cron / inspect / work / loop / full (default)
- Extra context: Natural language text after the command (if any)
If cron mode, jump to Step 5. Otherwise continue with Step 2.
Save extra context to a temporary file:
echo "User Extra Instructions: <user's natural language input>" > /tmp/harness-context.txt
# Lifetime: full mode next cycle = both inspector and worker-reviewer will read it;
# worker-reviewer deletes it after the current round's final delivery to claude (preserved if early exit due to no tasks)
If no extra context, create an empty file (child process will skip injection when detecting empty file).
Step 2 — Verify Project Environment
# Verify in project root
test -f TODO.md || echo "NOT_HARNESS_PROJECT"
# Verify skill scripts exist (relative to skill directory)
test -f ../harness/inspector.sh && test -f ../harness/worker-reviewer.sh || echo "SCRIPTS_MISSING"
If environment is wrong, stop and inform the user.
Example invocation:
cd <project> && bash ~/.codex/skills/harness/inspector.sh
cd <project> && bash ~/.codex/skills/harness/worker-reviewer.sh --loop
HARNESS_PROJECT_DIR=/abs/path/to/project bash ~/.codex/skills/harness/inspector.sh
If TODO.md does not exist, create a minimal template:
# Project Improvement Board
## Current Phase: Initialization
## Goals
- [ ] To be filled after Inspector's first inspection
## Done Log
Step 3 — Execute According to Mode
Mode: inspect
cd <project directory> && bash <skill directory>/inspector.sh
Mode: work
cd <project directory> && bash <skill directory>/worker-reviewer.sh
Mode: loop
cd <project directory> && bash <skill directory>/worker-reviewer.sh --loop
Mode: full (default)
# Phase 1: Inspector inspection
cd <project directory> && bash <skill directory>/inspector.sh
# Phase 2: Worker+Reviewer loop
cd <project directory> && bash <skill directory>/worker-reviewer.sh --loop
Step 4 — Output Results
After completion, report to the user:
Harness cycle complete
Inspector:
- Current goal: ...
- Architecture assessment: ...
- New/adjusted tasks: N
Worker+Reviewer:
- Completed tasks: N
- Rejected tasks: N
- Remaining available: N
Next round: type /harness to continue
Step 5 — Cron Mode (using built-in CronCreate/CronDelete/CronList)
5.1 Create scheduled task: /harness cron "<cron expression>" [mode]
- Parse cron expression and optional mode (inspect / work / loop / full)
- Build prompt content based on mode:
- full:
"Execute harness full cycle. Run sequentially: 1. cd <project path> && bash <skill path>/inspector.sh 2. bash <skill path>/worker-reviewer.sh --loop Report results after completion." - inspect:
"Execute harness inspect. Run cd <project path> && bash <skill path>/inspector.sh. Report results after completion." - work:
"Execute harness work. Run cd <project path> && bash <skill path>/worker-reviewer.sh. Report results after completion." - loop:
"Execute harness loop. Run cd <project path> && bash <skill path>/worker-reviewer.sh --loop. Report results after completion."
- full:
- Call CronCreate with parameters:
cron: user-provided cron expressionprompt: the prompt built aboverecurring: true
- Confirm creation to user, return job_id
5.2 List scheduled tasks: /harness cron list
- Call CronList to get all cron jobs in the current session
- Filter jobs whose prompt contains the "harness" keyword
- Display as a table: job_id | cron expression | mode | creation time (if available)
- If no harness crons exist, prompt "No harness scheduled tasks in the current session"
5.3 Delete scheduled task: /harness cron stop [job_id]
- With job_id: Call CronDelete to delete the specified job, confirm successful deletion
- Without job_id:
- Call CronList, filter harness-related jobs
- Show the user all jobs that will be deleted
- After user confirmation, delete each job one by one with CronDelete
- Report deletion results
Child Process Input Mechanism
Each child process (Inspector / Worker / Reviewer) is started via claude -p, with input composed of three parts:
- Role prompt —
<skill directory>/prompts/inspector.mdetc. - Project documents — Script automatically concatenates content from AGENTS.md, CLAUDE.md, README, TODO.md, etc.
- User extra context — Read from
/tmp/harness-context.txt, injected at the end of the prompt
The three parts are concatenated and passed to claude -p, ensuring the child process has both the project's full picture and the user's specific intent for this cycle.
By default, the script treats the current working directory (pwd -P) at the time of invocation as the project directory; to call from elsewhere, override with HARNESS_PROJECT_DIR=/abs/path/to/project. The skill installation directory is only used to locate scripts and prompts, and is never treated as the project directory.
File Inventory
| File | Responsibility |
|---|---|
prompts/inspector.md | Inspector role prompt |
prompts/worker.md | Worker role prompt |
prompts/reviewer.md | Reviewer role prompt |
inspector.sh | Inspector execution script |
worker-reviewer.sh | Worker+Reviewer execution script |
TODO.md | Shared task kanban (project root) |