Skip to the content.

Verified Stage Execution

Verified Stage Execution makes a stage's success an independently checked outcome, rather than only an agent claim. It is the first slice of the broader Stageflow Control Profiles initiative.

The first slice has a deliberately fixed set of check types. New check types are not added casually: each must have a clear evidence model, safe runtime semantics, and a use case not covered by the six core types.

Configuration

completion and recovery belong on a pipeline stage entry. They are execution policy: the same reusable stage can have a different completion bar in another pipeline.

stages:
  - id: implement
    uses: ./stages/implement.yaml
    needs: plan
    completion:
      mode: all
      checks:
        - id: unit-tests
          type: command
          run: npm test
          timeout_ms: 600000
        - id: implementation-report
          type: artifact
          path: implementation-report.md
          nonempty: true
        - id: self-review
          type: checklist
          items:
            - Implementation matches the approved plan
            - Unrelated files were not changed
        - id: valid-handoff
          type: payload_schema
        - id: operator-approval
          type: gate
          kind: confirm
        - id: actual-project-changes
          type: checkout_changes
          path_fields: [changed_files]
    recovery:
      mode: repair
      max_attempts: 3
      retry_safety: idempotent
      include_failed_checks: true

The matching reusable stage declares the handoff data and any gate kinds the contract uses:

id: implement
system_prompt: Implement the approved change and report every changed project file.
model: openai/gpt-5.6-sol
gate_kinds: [confirm]
payload_schema:
  type: object
  properties:
    changed_files:
      type: array
      items:
        type: string
  required: [changed_files]

Core check types

Type Required fields Runtime evidence
command id, run Stageflow runs the declared command, requires a successful exit status, and records stdout, stderr, timestamps, and exit code. Optional: cwd, timeout_ms.
artifact id, path Stageflow resolves the relative path inside the stage attempt's artifact directory and verifies that it exists. Optional nonempty: true requires content.
checklist id, items The agent gives a structured attestation that it considered every listed item. This is visible and recorded, but is not independent verification.
payload_schema id Stageflow validates the successful envelope payload against the reusable stage's declared payload_schema.
gate id, kind Stageflow verifies the relevant operator interaction in this attempt. The stage must declare the matching gate_kinds value.
checkout_changes id Stageflow compares checkout state before and after the attempt and requires a real change. Optional path_fields reconciles actual changes with required string-array fields in payload_schema.

gate.kind is one of free_text, confirm, multi_question, or artifact_backed.

This completion contract's gate/artifact checks run after a candidate envelope has already been captured (via repair/manual recovery) and ask a looser, retrospective question ("was this ever satisfied over the run so far" / real on-disk evidence). A stage that instead wants to block a self-approved success emit within the same attempt, before capture should declare the stage-body pre_emit_checks field instead — see Envelopes — pre_emit_checks. The two are independent and may coexist on the same stage as defense in depth.

Contract rules

Runtime semantics

The runtime lifecycle for a successful agent envelope is:

agent proposes success
  -> envelope is structurally valid
  -> completion checks run independently
  -> evidence is persisted
  -> the attempt records whether verification passed, failed, or could not run
  -> all checks pass: stage succeeds
  -> a check fails: eligible repair or honest failure

An agent may perform its own tests or self-review, but those actions are not proof by themselves. A command, artifact, checkout, or payload check is executed or read by Stageflow after the agent proposes success. Operator gates are evidence of an operator decision. Checklists remain useful because they make procedural obligations explicit, but they are recorded as agent attestations rather than authoritative evidence. LLM reviews remain outside this first check set.

Recovery policy

recovery controls what happens when a candidate success fails a completion check:

recovery:
  mode: repair
  max_attempts: 3
  retry_safety: idempotent
  include_failed_checks: true

For mode: repair, Stageflow starts a fresh agent attempt after a completion verification failure while the total number of attempts remains below max_attempts. The repair prompt receives a compact capsule of the failed checks and evidence when include_failed_checks is true. Every repair attempt runs the same completion contract again.

Automatic repair never follows an agent failure, an invalid recovery policy, or a side-effecting stage. Deployments, publishing, payments, and other externally visible work must use mode: manual until an explicit compensation policy exists.

Manual recovery

For recovery.mode: manual, a failed completion check leaves the stage failed. It does not silently reuse the normal retry path. The operator sees the attempt history and must make one explicit decision:

Stageflow records either choice. A manual retry starts a fresh attempt, carries the previous failed-check capsule, and includes the operator's instructions in the agent prompt. A stop is terminal for that stage in the current run; use a fresh run to try again later. The ordinary retry action is refused for this failure so it cannot bypass the manual decision.

sf runs recover --run <runId> --stage <stageId> --guidance "Fix the failing check"
sf runs recover --run <runId> --stage <stageId> --stop
POST /api/runs/<runId>/stages/<stageId>/recovery { "guidance": "…" }
POST /api/runs/<runId>/stages/<stageId>/recovery/stop
MCP: recover_manual_stage / stop_manual_recovery

Visibility

Stageflow keeps verification evidence with the individual attempt that produced it. Each attempt also records its verification disposition (not_run, passed, failed, or error), so recovery policy is based on a durable fact rather than an error-message convention:

Disposition Meaning
not_run The agent did not reach completion verification.
passed Every declared completion check passed.
failed At least one completion check did not pass.
error The verification runtime could not complete its work.

The operator console shows this history when a stage is open: each attempt lists its completion checks, their status, and expandable evidence. This makes an automatic repair legible rather than looking like a single unexplained retry.

The same history is available to automation:

sf runs verify --run <runId> --stage <stageId> --json
GET /api/runs/<runId>/stages/<stageId>/verification
MCP: get_stage_verification

The focused stage endpoint is intentional. Command output can be sizable, so normal run lists and summaries do not include every check's evidence.

Deliberately deferred check types

The following are useful, but are not part of the Slice 1 contract surface:

They require additional permission, evidence, or retry-safety design. Until then, model them with the six core types or an explicit human gate.