Maintenance Workflow

The maintenance workflow runs iterate and maintain automation against each registered project, committing and pushing any changes they produce. It is designed to be triggered nightly via launchd or manually via foundry emit.

How It Works

Each project goes through its own independent chain. The chain is driven entirely by events — no mutable state is shared between projects.

Per-Project Chain

flowchart TD
    A([maintenance_run_started]) --> B[[Validate Project]]
    B --> C([project_validation_completed])
    C --> D[[Route Project Workflow]]
    D -->|iterate=true| E([iteration_requested])
    D -->|iterate=false, maintain=true| F([maintenance_requested])
    D -->|no actions enabled| G([end])
    E --> H[[Resolve Gates]]
    H --> I[[Run Preflight Gates]]
    I --> J[[Check Charter]]
    J --> K[[Assess Project]]
    K --> L[[Triage Assessment]]
    L --> M[[Create Plan]]
    M --> N[[Execute Plan]]
    N --> O[[Run Verify Gates]]
    O --> P[[Route Gate Result]]
    P -->|pass| Q([project_iteration_completed])
    P -->|fail, retries left| R[[Retry Execution]]
    Q -->|maintain=true| F
    F --> S[[Resolve Gates]]
    S --> T[[Execute Maintain]]
    T --> U[[Run Verify Gates]]
    U --> V[[Route Gate Result]]
    V -->|pass| W([project_maintenance_completed])
    V -->|fail, retries left| X[[Retry Execution]]

Routing Logic

Route Project Workflow reads the actions flags forwarded in the project_validation_completed payload and makes a single decision:

ConditionEmits
status != "ok"nothing — chain stops
actions.iterate = trueiteration_requested
actions.iterate = false, actions.maintain = truemaintenance_requested
both falsenothing — no automation enabled

When iterate = true, the actions.maintain flag is forwarded inside the iteration_requested payload. After a successful iteration, the gate routing emits maintenance_requested automatically when that flag is true, so the maintain sub-workflow starts without an extra routing step.

Triggering a Maintenance Run

To run maintenance for a single project:

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

To trigger the full nightly cycle:

foundry emit maintenance_run_started my-project

Throttle Behaviour

ThrottleEffect
fullAll blocks execute and emit events
audit_onlyObservers emit; mutators suppress output
dry_runObservers emit; mutators are skipped entirely

Under dry_run, only iteration_requested or maintenance_requested are emitted (by the Observer router). No execution blocks run.

Agent Capabilities

The maintenance workflow uses a single agent invocation in Execute Maintain:

PhaseCapabilityModelAccessPurpose
Execute MaintainCodingclaude-sonnet-4-6FullUpdate dependencies, fix vulnerabilities, resolve gate failures

Gate definitions are passed as context so the agent knows what must pass after its changes. If the project has an agent file registered, it is supplied via --agent.

See the Iteration Workflow for the full model-to-capability mapping and CLI parameters used across all agent invocations.