Iteration Workflow

The iteration workflow is Foundry's code quality improvement engine. It identifies the most-violated engineering principle in a project, creates a targeted fix plan, executes it, and verifies the result against quality gates — with automatic retries on failure.

The Chain

flowchart TD
    A([iteration_requested]) --> B[[Resolve Gates]]
    B --> C([gate_resolution_completed])
    C --> D[[Run Preflight Gates]]
    D --> E([preflight_completed])
    E --> F[[Check Charter]]
    F --> G([charter_validated])
    G --> H[[Assess Project]]
    H --> I([project_assessed])
    I --> J[[Triage Assessment]]
    J --> K([assessment_triaged])
    K --> L[[Create Plan]]
    L --> M([plan_created])
    M --> N[[Execute Plan]]
    N --> O([execution_completed])
    O --> P[[Run Verify Gates]]
    P --> Q([gate_verification_completed])
    Q --> R[[Route Gate Result]]
    R -->|pass| S([project_iteration_completed])
    R -->|fail, retries left| T[[Retry Execution]]
    T --> O
    R -->|fail, retries exhausted| U([project_iteration_completed — failure])
    S -->|maintain=true| V([maintenance_requested])

Phase by Phase

1. Gate Resolution

Resolve Gates reads .hone-gates.json from the project directory and emits the gate definitions with workflow: "iterate". The actions object from the trigger event is forwarded through the chain so that gate routing can chain into the maintenance workflow afterwards.

Each gate has a name, a command, a required flag, an optional timeout (seconds), and an optional fix_command — an in-place command that mechanically repairs the gate's failure. A gate looks like:

{
  "name": "format",
  "command": "cargo fmt --check",
  "required": true,
  "fix_command": "cargo fmt"
}

Only declare a fix_command for gates whose failures are safely auto-fixable — formatters and lint autofixers (cargo fmt, ruff format, biome check --write, a clang-format target). Never for tests, typecheck, build, or security gates, where a "fix" would mask a real problem.

2. Preflight Gates

Run Preflight Gates executes every gate against the unmodified codebase.

When a gate fails and declares a fix_command, the runner runs the fix once and re-checks; a passing re-check resolves the gate (recorded with fix_applied: true on the result), and the in-place changes left in the working tree are committed by the downstream Commit and Push step. This is what lets formatter/lint gates self-heal: without it, a required formatting gate would abort the run before the maintain step that reformats the code — a deadlock where the failing gate blocks its own fix.

If a required gate fails and cannot self-heal (no fix_command, or the fix didn't resolve it), required_passed is false and the chain stops — Assess Project self-filters on preflight success.

This establishes a baseline: the iterate workflow only attempts improvements when the project is already in a passing state (or can be brought to one mechanically).

3. Charter Validation

Check Charter verifies that the project has intent documentation (e.g. CHARTER.md). If the charter is missing, passed is false and the chain stops at this point — there is no assessment without context.

4. Assessment

Assess Project invokes an AI agent with reasoning capability and read-only access to analyse the codebase. It identifies the single most-violated engineering principle, returning a severity score (1–10), the principle name, category, and a detailed assessment.

A second quick agent call generates a kebab-case audit filename for traceability.

5. Triage

Triage Assessment uses a quick agent call to decide whether the finding is worth acting on. It rejects issues with severity below 4 or findings that amount to busy-work rather than substantive improvement. On agent failure, triage defaults to accepted — it is better to attempt a fix than to silently skip.

If triage rejects the finding, Create Plan self-filters on accepted=false and the chain stops cleanly.

6. Plan Creation

Create Plan invokes an AI agent with reasoning capability and read-only access to produce a step-by-step correction plan. The plan is concrete — it names exact files and functions — minimal, and testable. Gate definitions are forwarded so the execution phase knows what must pass.

The plan agent is also asked to emit a machine-readable JSON block at the end of its response declaring whether correction is actually needed:

{ "correctionNeeded": true, "reason": "<one sentence>" }

Setting correctionNeeded to false signals that the agent examined the codebase and found the original assessment inaccurate — the codebase already satisfies the principle and no changes are warranted. This becomes a legitimate no-op (see §7). The flag defaults to true on any parse failure (fail-closed).

7. Execution

Execute Plan is the only Mutator in the assessment-to-execution pipeline. It invokes an AI agent with coding capability and full filesystem access. The agent receives the plan plus gate context (the gates it must satisfy) and applies the changes.

Under dry_run throttle, this block returns a simulated success without modifying any files.

Legitimate no-ops — When correctionNeeded is false in the PlanCompleted payload, a clean working tree after execution is treated as a success rather than a flake. The downstream gate verification runs normally and, assuming gates pass, the iteration completes successfully. This mirrors hone's busy-work-containment semantics: an agent that correctly concludes "nothing to do" should not be penalised with retries.

Silent no-op guard — When correctionNeeded is true (the default), an agent that exits successfully but makes no meaningful file changes is overridden to success: false, triggering the retry loop. This prevents agents that silently skip their work from consuming a passing iteration slot.

8. Gate Verification

Run Verify Gates re-reads .hone-gates.json from disk (a fresh read, not cached from phase 1) and runs every gate against the modified codebase. The retry_count from the payload tracks which attempt this is.

9. Routing and Retry

Route Gate Result makes the terminal decision:

ConditionAction
All required gates passEmit project_iteration_completed (success)
Required gates fail, retry count < 3Emit retry_requested with failure context
Required gates fail, retry count ≥ 3Emit project_iteration_completed (failure)

When retrying, Retry Execution receives the failure context (which gates failed and their output) and invokes a coding agent to fix only the issues causing those failures. The result loops back to Run Verify Gates for another round.

The maximum is 3 retries (4 total attempts: 1 initial + 3 retries).

10. Chaining to Maintenance

On success, if actions.maintain=true was forwarded through the chain, Route Gate Result also emits maintenance_requested. This triggers the Maintenance Workflow without re-querying the project configuration.

Self-Filtering

Several blocks use self-filtering to stop the chain gracefully without errors:

  • Assess Project — skips when workflow != "iterate" or preflight failed
  • Check Charter — skips when workflow != "iterate"
  • Create Plan — skips when accepted != true (triage rejected)
  • Summarize Result — skips when success != true

The engine routes by event type only and cannot inspect payloads. Each block checks the relevant payload fields and returns an empty result when the condition does not match.

Running the Workflow

Direct trigger

To run the iterate workflow for a single project:

foundry emit iteration_requested my-project \
  --payload '{"actions":{"iterate":true,"maintain":false}}'

With maintenance chaining

To iterate and then run maintenance:

foundry emit iteration_requested my-project \
  --payload '{"actions":{"iterate":true,"maintain":true}}'

Via the maintenance run

The full maintenance lifecycle triggers iteration automatically when iterate=true in the project's registry entry:

foundry emit maintenance_run_started my-project

Dry run

Only observers execute. Mutators are skipped entirely:

foundry emit iteration_requested my-project \
  --throttle dry_run \
  --payload '{"actions":{"iterate":true,"maintain":false}}'

Agent Capabilities

Foundry delegates AI work to the Claude CLI, mapping each block's capability hint to a concrete model:

CapabilityModelUse Case
Reasoningclaude-opus-5Deep analysis and planning
Codingclaude-sonnet-5Code generation and modification
Quickclaude-haiku-4-5-20251001Fast, lightweight decisions

Access levels control which CLI tools the agent may use:

AccessAllowed Tools
Read-onlyRead, Glob, Grep, WebFetch, WebSearch
FullAll tools (no restrictions)

Each phase in the iterate workflow maps to a specific capability and access level:

PhaseCapabilityModelAccessPurpose
AssessmentReasoningOpusRead-onlyDeep analysis of codebase
Audit namingQuickHaikuRead-onlyGenerate kebab-case filename
TriageQuickHaikuRead-onlyAccept/reject decision
Plan creationReasoningOpusRead-onlyStep-by-step correction plan
ExecutionCodingSonnetFullApply code changes
RetryCodingSonnetFullFix gate failures
SummarisationQuickHaikuRead-onlyGenerate headline and summary

All agent invocations use the --print flag (non-interactive output) and --dangerously-skip-permissions (unattended execution). Blocks that reference a project agent file pass it via --agent. Timeouts are set per-project from the registry entry, except Triage and Summarisation which use a fixed 120-second timeout for their lightweight Quick calls.

Payload Fields

FieldCarried ByPurpose
actionsAll events{iterate, maintain} flags for workflow routing
gatesGates resolved through plan creationGate definitions for execution context
audit_nameAssessment through plan creationKebab-case audit filename for traceability
severityAssessment through plan creationViolation severity (1–10)
principleAssessment through plan creationName of the violated principle
categoryAssessment through plan creationCategory of the violation
assessmentAssessment through plan creationDetailed assessment text
retry_countExecution through gate routingCurrent retry attempt (0-based)
failure_contextRetry requestedGate output from failed verification
correction_neededPlan completed through executionfalse when plan agent concluded no changes are warranted; defaults to true
correction_reasonPlan completed through executionOne-sentence explanation when correction_needed is false