calesthio/OpenMontage · error · CheckpointValidationError

GATE VIOLATION: stage {stage!r} requires human approval ({ga

Error message

GATE VIOLATION: stage {stage!r} requires human approval ({gate_source}) but status='completed' was written without human_approved=True. Correct protocol: write status='awaiting_human', present the artifact summary to the user, END YOUR TURN, and only after the user approves re-write with status='completed', human_approved=True.

What it means

Raised by lib/checkpoint.py when a checkpoint for a stage that requires human approval (via human_approval_default: true in the pipeline manifest, or human_approval_required=True passed by the caller) is written with status='completed' but without human_approved=True. The checkpoint system enforces a human-in-the-loop gate: the agent must first persist status='awaiting_human', present the artifact summary, end its turn, and only after explicit user approval write status='completed' with human_approved=True. This is a deliberate protocol violation guard, not a data corruption bug.

Source

Thrown at lib/checkpoint.py:487

    # gates on human approval; a caller may gate MORE strictly (e.g. a
    # manual_all checkpoint policy) but never less. A gated stage can only be
    # written "completed" with explicit evidence of approval
    # (human_approved=True). Skipping a gate is a hard error.
    #
    # Enforcement happens at write time only: pre-existing checkpoints written
    # before gating (or by hand) still read as completed — deliberate
    # back-compat so in-flight and legacy projects keep resuming.
    manifest_gate = _stage_requires_approval(pipeline_type, stage)
    gated = bool(manifest_gate) or human_approval_required
    if gated:
        human_approval_required = True
        if status == "completed" and not human_approved:
            gate_source = (
                f"human_approval_default: true in the {pipeline_type!r} manifest"
                if manifest_gate
                else "human_approval_required=True was passed by the caller"
            )
            raise CheckpointValidationError(
                f"GATE VIOLATION: stage {stage!r} requires human approval "
                f"({gate_source}) but status='completed' was written without "
                f"human_approved=True. Correct protocol: write "
                f"status='awaiting_human', present the artifact summary to the "
                f"user, END YOUR TURN, and only after the user approves "
                f"re-write with status='completed', human_approved=True."
            )

    _enforce_stage_prerequisites(
        pipeline_dir,
        project_id,
        pipeline_type,
        stage,
        status,
    )

    checkpoint = {
        "version": "1.0",

View on GitHub (pinned to 95e1c3d0ab)

Solutions

  1. Rewrite the checkpoint with status='awaiting_human' first, present the artifact summary to the user, and end the turn.
  2. After the user approves, write the checkpoint again with status='completed' and human_approved=True.
  3. If the gate is intentional and the caller is authorized, pass human_approved=True together with status='completed' only when a real human approval exists.
  4. If the stage should not be gated, edit the pipeline manifest and remove human_approval_default: true for that stage (a user/product decision, not an agent one).

Example fix

# before
write_checkpoint(stage="final_review", status="completed")

# after
write_checkpoint(stage="final_review", status="awaiting_human")
# ... present artifact summary, END TURN ...
# after user approval:
write_checkpoint(stage="final_review", status="completed", human_approved=True)
Defensive patterns

Strategy: validation

Validate before calling

from lib.pipeline_loader import load_pipeline_readonly, get_stage_human_approval_default

def stage_is_gated(pipeline_type: str, stage: str) -> bool:
    try:
        manifest = load_pipeline_readonly(pipeline_type)
    except Exception:
        return False
    return bool(get_stage_human_approval_default(manifest, stage))

# before writing 'completed':
if stage_is_gated(pipeline_type, stage) and not human_approved:
    write_checkpoint(stage=stage, status="awaiting_human")  # then end turn

Type guard

def can_complete_stage(pipeline_type: str, stage: str, human_approved: bool) -> bool:
    """True only when the stage is ungated OR a human has approved."""
    return human_approved or not stage_is_gated(pipeline_type, stage)

Try / catch

try:
    write_checkpoint(stage=stage, status="completed", human_approved=approved)
except CheckpointValidationError as e:
    if "GATE VIOLATION" in str(e):
        write_checkpoint(stage=stage, status="awaiting_human")
        present_artifact_summary()
        return  # end turn; complete only after user approval
    raise

Prevention

When it happens

Trigger: Calling the checkpoint write API with status='completed' for a stage whose manifest entry has human_approval_default: true (e.g. final_review in a gated pipeline), or passing human_approval_required=True while omitting human_approved=True. Also triggered when an agent skips the awaiting_human intermediate write and tries to complete a gated stage in a single call.

Common situations: Agents automating a full pipeline end-to-end without pausing; new pipeline manifests that enable human_approval_default on stages previously auto-completed; legacy code written before the gating was added that resumes in-flight projects and writes completed directly.

Related errors


AI-assisted analysis of calesthio/OpenMontage@95e1c3d0ab (2026-08-15). Data as JSON: /api/errors/78d6d179dab909a4. Report an issue: GitHub.