harness-task
Anthropic Harness methodology: autonomous multi-sprint execution with Generator/Evaluator separation, file-based handoff, auto-retry, and multi-instance version management. Use for large implementation tasks requiring quality assurance.
Harness-Task: Generator-Evaluator Sprint Execution
<harness-task-command>You are executing the Anthropic Harness methodology — an autonomous multi-sprint system where code generation and quality evaluation are strictly separated. This version supports multi-instance execution — multiple harness runs can coexist in the same project without conflict.
Step 0: Parse Arguments
Arguments: $ARGUMENTS
Parse the following from arguments:
- spec: A file path to a spec/PRD document, OR a task description string
- --name <name>: Instance name (kebab-case, e.g.
auth-refactor). If omitted, auto-generated from spec filename or first 3 words of description - --threshold N: Evaluation pass threshold (default: 7, range: 1-10)
- --max-retries N: Max fix attempts per sprint (default: 3). Total attempts = 1 (initial) + max-retries. Example:
--max-retries 3means up to 4 total attempts (1 initial + 3 retries). - --start-from N: Start from sprint N (skip prior sprints)
- --skip-eval: Skip evaluation (debug mode)
- --sprints N: Override number of sprints (default: auto from planning)
- --eval-weights: Custom evaluation weights as JSON, e.g.
--eval-weights '{"functionality":40,"reliability":20,"compatibility":20,"quality":20}' - --list: List all harness instances and their status, then stop (no execution)
- --resume <name>: Resume a specific instance from where it left off
- --archive <name>: Move a completed instance to
_archived/, then stop
If no spec file is given and only a description is provided, you will act as Planner first (Phase 0).
Instance Name Auto-Generation
When --name is not provided:
- If spec is a file path: use the filename without extension, converted to kebab-case (e.g.
auth_migration_plan.md→auth-migration-plan) - If spec is a description: take the first 3-5 significant words, kebab-case (e.g. "Refactor the authentication system" →
refactor-auth-system) - If the auto-generated name already exists in the registry, append a numeric suffix:
auth-refactor-2,auth-refactor-3, etc.
Argument Validation Rules
Before proceeding, validate every parsed argument:
| Argument | Type | Constraint | On Violation |
|---|---|---|---|
spec | string (file path or description) | If a file path: file must exist and be readable | STOP with error: "Spec file not found or unreadable: {path}" |
--name | string | Must be kebab-case (lowercase letters, digits, hyphens only), 1-50 chars | STOP with error: "Instance name must be kebab-case (a-z, 0-9, hyphens), 1-50 chars, got: {value}" |
--threshold | integer | Must be between 1 and 10 inclusive | STOP with error: "Threshold must be an integer between 1 and 10, got: {value}" |
--max-retries | integer | Must be >= 0 | STOP with error: "Max retries must be a non-negative integer, got: {value}" |
--start-from | integer | Must be >= 1 | STOP with error: "Start-from must be a positive integer, got: {value}" |
--sprints | integer | Must be between 1 and 10 inclusive | STOP with error: "Sprints must be an integer between 1 and 10, got: {value}" |
--skip-eval | boolean flag | No value required | N/A |
--eval-weights | JSON object | Must contain exactly 4 keys: functionality, reliability, compatibility, quality. All values must be non-negative integers summing to exactly 100. | STOP with error describing which constraint failed |
--resume | string | Instance must exist in registry | STOP with error: "Instance not found: {name}. Use --list to see available instances." |
--archive | string | Instance must exist and have status completed or aborted | STOP with error describing the issue |
Mutual exclusions:
--skip-evaland--eval-weightsMUST NOT be used together. If both are present, STOP with error: "Cannot use --skip-eval and --eval-weights together: --skip-eval disables evaluation, but --eval-weights configures it."--list,--resume, and--archiveare management commands — they MUST NOT be combined withspecor with each other. If mixed, STOP with error explaining which flags conflict.
Spec File Validation
If spec is a file path, validate the spec file before any workspace initialization:
- Existence check: Verify the file exists at the given path. If not, STOP with error: "Spec file does not exist: {path}".
- Readability check: Attempt to read the file. If it fails (permissions, encoding), STOP with error: "Spec file is not readable: {path} — {reason}".
- Minimum content check: The file must contain at least 50 non-whitespace characters. If it does not, STOP with error: "Spec file appears empty or too short (< 50 non-whitespace chars): {path}".
Only proceed to Step 0.5 after all argument and spec validations pass.
Project Root
Determine {project_root} using this priority:
- Spec git root: If
specis a file path, use the git repository root containing that file (rungit -C <spec_dir> rev-parse --show-toplevel). - CWD git root: If the spec is not a file or step 1 failed, use the git repository root of the current working directory (run
git rev-parse --show-toplevel). - CWD: If neither git root can be determined, fall back to the current working directory.
All .harness/ paths are relative to {project_root}.
Step 0.5: Management Commands & Backward Compatibility
Backward Compatibility Migration
Before any operation, check if a legacy flat .harness/ structure exists:
- If
{project_root}/.harness/config.jsonexists AND there is no{project_root}/.harness/registry.json:- This is a legacy single-instance layout
- Create directory
{project_root}/.harness/default/ - Move all files/directories (
spec.md,config.json,summary.md,contracts/,completions/,evaluations/,logs/) into.harness/default/ - Do NOT move
temp/— it stays at.harness/temp/ - Create
.harness/registry.jsonwith one entry for the migrateddefaultinstance (read status from the migrated config.json) - Inform the user: "Migrated legacy .harness/ to .harness/default/. Created registry."
--list: List Instances
If --list is specified:
- Read
{project_root}/.harness/registry.json - Display a table of all instances:
Harness Instances: | Name | Status | Sprints | Created | Last Updated | |------|--------|---------|---------|--------------| | auth-refactor | completed | 4/4 passed | 2026-03-30 | 2026-03-30 | | ota-integration | running | 2/5 passed | 2026-03-31 | 2026-03-31 | - If no registry exists, display: "No harness instances found."
- STOP — do not proceed to sprint execution.
--resume: Resume Instance
If --resume <name> is specified:
- Read
{project_root}/.harness/registry.json, find the instance - Read
{project_root}/.harness/{name}/config.json - Determine the resume point:
- Find the first sprint with status
pendingorin_progressorfailedin the sprints array - If all sprints are
passedorauto_skip, report "Instance already completed" and STOP
- Find the first sprint with status
- Set
startFromto that sprint number - Load all existing config values (threshold, maxRetries, evalWeights, etc.)
- Continue to Step 3 (Sprint Execution Loop) using the instance's working directory
--archive: Archive Instance
If --archive <name> is specified:
- Verify the instance status is
completedoraborted - Create
{project_root}/.harness/_archived/if it doesn't exist - Move
{project_root}/.harness/{name}/to{project_root}/.harness/_archived/{name}/ - Update registry.json: set instance status to
archived - Inform the user and STOP
Step 1: Initialize Workspace
Resolve the instance name {name} (from --name, --resume, or auto-generated).
Create the harness working directory structure:
{project_root}/.harness/
├── registry.json # Instance registry (create if not exists)
└── {name}/ # Instance working directory
├── spec.md # Full specification (input or generated)
├── config.json # Harness configuration
├── contracts/ # Sprint contracts
│ └── s{N}_contract.md
├── completions/ # Generator outputs
│ └── s{N}_completion.md
├── evaluations/ # Evaluator outputs
│ └── s{N}_evaluation.md
└── logs/
└── harness.log # Execution log
Registry: Create or update {project_root}/.harness/registry.json:
{
"version": 2,
"instances": [
{
"name": "<instance name>",
"description": "<first line of spec or description>",
"status": "initialized",
"createdAt": "<timestamp>",
"updatedAt": "<timestamp>",
"sprintsPassed": 0,
"sprintsTotal": 0
}
]
}
Instance config: Write {project_root}/.harness/{name}/config.json:
{
"name": "<instance name>",
"threshold": <parsed or 7>,
"maxRetries": <parsed or 3>,
"startFrom": <parsed or 1>,
"skipEval": <parsed or false>,
"evalWeights": {
"functionality": 30,
"reliability": 30,
"compatibility": 20,
"quality": 20
},
"createdAt": "<timestamp>",
"status": "initialized",
"sprints": []
}
Global status values (updated as execution progresses):
| Status | Meaning |
|---|---|
initialized | Workspace created, not yet started |
planning | Phase 0 planning in progress |
running | Sprint execution loop is active |
completed | All sprints finished (passed or failed) |
aborted | Execution stopped due to unrecoverable error |
archived | Instance moved to _archived/ (registry only) |
sprints array schema (one entry per sprint, appended during planning, updated during execution):
{
"sprint": 1,
"name": "<sprint name>",
"status": "pending",
"score": null,
"retries": 0,
"duration": null
}
Per-sprint status values: pending, in_progress, passed, failed, auto_skip.
Registry sync: After every status change (planning → running → completed, sprint pass/fail), update both the instance config.json AND the registry.json entry (status, updatedAt, sprintsPassed, sprintsTotal).
Step 2: Phase 0 — Planning
If a spec file was provided, copy it to .harness/{name}/spec.md.
If only a description was given, act as Planner:
- Read the project codebase to understand current architecture
- Generate a complete technical specification including:
- Current state analysis
- Target architecture
- Data/API inventory
- Feature degradation matrix (if applicable)
- Implementation priorities
- Write the spec to
.harness/{name}/spec.md
Then decompose into Sprints:
- Analyze the spec and break it into 3-7 sequential sprints
- Each sprint should be:
- Self-contained with clear boundaries
- Buildable on prior sprints
- Completable in one Claude session (~10min of coding)
- For each sprint, write a contract file
.harness/{name}/contracts/s{N}_contract.mdcontaining:- Sprint goal (1 sentence)
- Detailed task description
- Numbered acceptance criteria (5-12 items, specific and testable)
- Input dependencies (which prior sprints)
Present the sprint plan to the user for confirmation before proceeding.
Step 3: Sprint Execution Loop
For each sprint N (from startFrom to total):
3a-0. Contract Negotiation (optional)
Before launching the Generator, review the sprint contract for feasibility:
- Read
s{N}_contract.mdand verify:- The acceptance criteria are specific and testable (not vague like "improve performance")
- The scope is achievable in a single session
- All input dependencies (prior sprints) have status PASSED (not FAILED or AUTO-SKIP)
- If any issue is found:
- Present the concern to the user with a proposed amendment
- Wait for user approval or revision
- Write the amended contract back to
s{N}_contract.md
- If no issues are found, proceed directly to 3a.
This phase is skipped when --start-from jumps past a sprint or when re-running a Generator on retry (the contract was already negotiated on the first attempt).
3a. Generator Phase
Launch a subagent (Agent tool, subagent_type: general-purpose) as the Generator:
Generator system prompt pattern:
You are a senior engineer executing Sprint {N} of a multi-sprint implementation.
Instance: {name}
[Project Spec]: {contents of .harness/{name}/spec.md}
[Prior Sprint Completions]: {contents of all prior s{M}_completion.md}
[Sprint {N} Contract]: {contents of s{N}_contract.md}
{If retry > 0: [Fix Requirements]: {evaluator feedback}}
RESTRICTION: Do NOT read .harness/{name}/evaluations/. The Generator must never see Evaluator reports
from the current or prior sprints except via the fix feedback provided below. This maintains
strict Generator/Evaluator isolation.
File reading scope: The Generator MAY read any project source file, .harness/{name}/spec.md,
.harness/{name}/config.json, .harness/{name}/contracts/*, and .harness/{name}/completions/* (prior sprints only).
The Generator MUST NOT read .harness/{name}/evaluations/* or .harness/{name}/logs/*.
The Generator MUST NOT read or modify other instances under .harness/.
Instructions:
1. Read relevant source files first to understand existing code
2. List files to change/create with summaries
3. Implement changes using Edit/Write tools directly
4. Write completion report to: {.harness/{name}/completions/s{N}_completion.md}
Completion report format:
# Sprint {N} Completion: {name}
## Changed Files
| Path | Operation | Summary |
|------|-----------|---------|
(One row per file. Operation must be one of: CREATE, MODIFY, DELETE.)
## Acceptance Criteria Check
| # | Criterion | Status | Evidence |
|---|-----------|--------|----------|
(Status must be one of: PASS, PARTIAL, FAIL. Evidence format: file:line or a brief description.)
## Remaining Issues
(Bullet list of unresolved items, or "None" if all criteria passed.)
3b. Evaluator Phase (skip if --skip-eval)
Launch a separate subagent (Agent tool, subagent_type: general-purpose) as the Evaluator:
Evaluator system prompt pattern:
You are an independent QA engineer. You did NOT write this code. Evaluate objectively.
Instance: {name}
[Project Spec]: {contents of .harness/{name}/spec.md}
[Sprint {N} Contract]: {contents of s{N}_contract.md}
[Completion Report]: {contents of s{N}_completion.md}
CRITICAL: You MUST read the actual source files to verify changes exist and are correct.
Do NOT trust the completion report blindly.
File reading scope: The Evaluator MAY read any project source file, .harness/{name}/spec.md,
.harness/{name}/config.json, .harness/{name}/contracts/*, .harness/{name}/completions/s{N}_completion.md (current
sprint only), and .harness/{name}/evaluations/* (prior sprints only, to check for regressions).
The Evaluator MUST NOT read .harness/{name}/completions/ for sprints other than the current one.
The Evaluator MUST NOT read or modify other instances under .harness/.
Score on these dimensions (1-10 each):
1. Functionality (weight: {evalWeights.functionality}%)
- Check each acceptance criterion: PASS / FAIL / PARTIAL with evidence
2. Reliability (weight: {evalWeights.reliability}%)
- Does it truly work without dependencies it claims to avoid?
- Are there hidden assumptions or implicit dependencies?
- Do fallbacks/error handlers actually work?
3. Compatibility (weight: {evalWeights.compatibility}%)
- Does it break existing functionality?
- Are boundaries between old and new code clean?
4. Code Quality (weight: {evalWeights.quality}%)
- API design, naming, error handling
- No hardcoded values, magic numbers, or duplication
Output format:
## 1. Functionality: X/10
{evidence}
## 2. Reliability: X/10
{evidence}
## 3. Compatibility: X/10
{evidence}
## 4. Code Quality: X/10
{evidence}
## Weighted Score: X.X/10
Compute as: weighted_score = (f*Wf + r*Wr + c*Wc + q*Wq) / 100
where f=Functionality score, r=Reliability score, c=Compatibility score, q=Quality score,
and Wf/Wr/Wc/Wq are the respective percentage weights from evalWeights.
## Pass (>= {threshold}): YES/NO
## Fix Recommendations
{specific file + issue + fix for each failing item}
Write report to: {.harness/{name}/evaluations/s{N}_evaluation.md}
3c. Score Check & Retry
- Read the evaluation report
- Extract weighted score
- If score >= threshold: PASS -- proceed to Sprint N+1
- If score < threshold AND retries remaining:
- Extract fix recommendations from the evaluation report
- Compose a structured Fix Requirements block for the Generator:
[Fix Requirements] (retry {attempt}/{maxRetries}): Previous score: {score}/10 (threshold: {threshold}) Issues: 1. [{FAIL|PARTIAL}] {criterion} -- {file}:{line} -- {description of what is wrong} 2. ... Required fixes: 1. {specific action to take, referencing file and location} 2. ... - Re-run Generator with the Fix Requirements block. The Generator MUST overwrite (not append to) the completion report at
.harness/{name}/completions/s{N}_completion.md. - Re-run Evaluator on the updated completion and source files.
- If score < threshold AND no retries left:
- Log failure to
.harness/{name}/logs/harness.logwith sprint number, final score, and retry count - Apply failure cascading (see 3c-1 below) to auto-skip dependent sprints
- Continue autonomously to the next non-skipped sprint (do NOT prompt the user)
- Log failure to
Registry sync: After each sprint completes (pass or fail), update both config.json and registry.json.
3c-1. Failure Cascading (AUTO-SKIP)
When a sprint N fails (exhausts all retries), any subsequent sprint that depends on sprint N (declared via Input dependencies in its contract) is automatically marked AUTO-SKIP:
- Identify all sprints whose contract lists sprint N (or any already-skipped sprint) as an input dependency.
- For each such sprint M, write an evaluation file
.harness/{name}/evaluations/s{M}_evaluation.mdcontaining:## AUTO-SKIPPED Sprint {M} was automatically skipped because its dependency Sprint {N} failed. Score: 0/10 | Status: AUTO-SKIP - Record status
AUTO-SKIPin the progress table (Step 4). - Do NOT launch Generator or Evaluator subagents for auto-skipped sprints.
- Continue to the next non-skipped sprint.
This prevents wasted execution on sprints that cannot succeed due to missing prerequisites.
3d. Progress Reporting
After each Generator/Evaluator cycle, report to user. Measure wall-clock duration for each phase and format as Xm Ys (e.g., 2m 34s):
[{name}] Sprint {N}/{total}: {sprint_name}
Generator: done ({duration, e.g. 3m 12s})
Evaluator: {score}/10 {PASSED|FAILED} ({duration, e.g. 1m 45s})
Retries: {used}/{max}
Sprint duration: {total wall-clock for this sprint, e.g. 5m 22s}
Cumulative: {passed}/{attempted} sprints passed
Step 4: Final Summary
After all sprints complete, generate .harness/{name}/summary.md:
# Harness Execution Summary
**Instance**: {name}
| Sprint | Name | Score | Retries | Status |
|--------|------|-------|---------|--------|
| 1 | ... | X.X/10 | N | PASSED |
## Configuration
- Instance: {name}
- Threshold: {threshold}/10
- Eval Weights: {weights}
- Total Duration: {time}
## Evaluation Highlights
{Key findings from evaluators across all sprints}
## Recommended Follow-ups
{Aggregate P0/P1 items from all evaluations that passed but had warnings}
Update registry.json with final status (completed), sprintsPassed, and sprintsTotal.
Key Principles (from Anthropic's methodology)
- Generator and Evaluator are ALWAYS separate agents — never self-evaluate
- Files are the handoff protocol — no conversational context leakage
- Contracts before code — agree on acceptance criteria first
- Specific over subjective — score on measurable dimensions, not "is this good?"
- Iterate on failure — feed evaluator feedback back to generator
- Context isolation — each agent gets a fresh context via subagent
- Language consistency — all output (contracts, completion reports, evaluations, summaries) must be written in the same language as the spec
- Instance isolation — each harness run operates in its own directory; agents MUST NOT cross instance boundaries