# How OpenMontage Enforces Human Approval Gates at Specific Pipeline Stages

> Discover how OpenMontage enforces human approval gates at critical pipeline stages using manifest configuration and fail-closed validation. Ensure compliance and control.

- Repository: [Calesthio/OpenMontage](https://github.com/calesthio/OpenMontage)
- Tags: how-to-guide
- Published: 2026-08-30

---

**OpenMontage prevents stages marked as requiring human oversight from being recorded as completed unless the caller explicitly provides `human_approved=True`, implementing a fail-closed gate policy through manifest configuration and three-layer checkpoint validation.**

OpenMontage orchestrates creative AI workflows where human judgment is mandatory at critical junctures. The system manages **human approval gate enforcement** through a declarative `human_approval_default` policy defined in each pipeline's manifest, ensuring that creative stages cannot advance without explicit sign-off. This architecture combines runtime validation in [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py) with JSON Schema constraints to provide fail-closed guarantees while preserving backward compatibility with existing checkpoints.

## Gate Policy Configuration in Pipeline Manifests

Each OpenMontage pipeline declares its approval requirements in YAML manifests located under `pipeline_defs/*.yaml`. The boolean field `human_approval_default` determines whether a specific stage requires human sign-off before completion.

The [`lib/pipeline_loader.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/pipeline_loader.py) module exposes this configuration through `get_stage_human_approval_default`, which the checkpoint system queries at runtime. If the manifest is missing or malformed, the resolution logic logs a warning and returns `None`, falling back to any caller-provided `human_approval_required` flag to maintain operational continuity.

## Three-Layer Enforcement Architecture

The enforcement mechanism operates through three tightly-coupled validation layers that trigger when `write_checkpoint` attempts to persist stage state.

### Layer 1: Resolving the Gate Flag via `_stage_requires_approval`

The `_stage_requires_approval` function (lines 51-62 in [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py)) implements the first line of defense. It reads the `human_approval_default` value from the pipeline manifest and combines it with any `human_approval_required` argument supplied by the caller. This resolution step determines whether the current stage is gated before any state changes are written.

### Layer 2: Write-Time Validation in `write_checkpoint`

When `write_checkpoint` executes (lines 67-95 in [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py)), it enforces the gate policy strictly during the write operation. If `_stage_requires_approval` returns `True`, the function forces `human_approval_required` to `True` regardless of caller input.

Attempting to write `status="completed"` without `human_approved=True` immediately raises a `CheckpointValidationError`, halting execution and explaining the specific protocol violation. This ensures that gated stages can never accidentally be marked completed through API misuse.

### Layer 3: Prerequisite Chain Validation

Before allowing any checkpoint to advance, `_enforce_stage_prerequisites` in [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py) verifies that all predecessor stages satisfy completion criteria. For downstream gated stages, this validation ensures that every predecessor is not only marked **completed** but also carries `human_approved=True` if the predecessor itself requires human approval.

Missing or unapproved predecessors trigger a `CheckpointValidationError` that lists the specific offending stages, preventing pipeline progression until the human approval chain is satisfied.

## Fail-Closed Behavior and Backward Compatibility

The OpenMontage gate system guarantees **fail-closed** semantics. A stage declared as gated in the manifest can never transition to completed status without the explicit `human_approved` flag, regardless of API caller permissions or network conditions.

The enforcement applies **only at write time**, providing backward compatibility for checkpoints written before gate policies were enabled. Existing checkpoints remain readable and queryable, but any new writes must obey the current gate policy defined in the manifest.

## Implementing Approval Gates in Practice

Attempting to complete a gated stage without approval results in a validation error:

```python
from pathlib import Path
from lib.checkpoint import write_checkpoint, CheckpointValidationError

project_dir = Path("/tmp/myproj")
stage = "compose"  # Assumed gated in manifest

try:
    write_checkpoint(
        pipeline_dir=Path("/tmp/projects"),
        project_id="proj123",
        stage=stage,
        status="completed",  # Illegal without human_approved=True

        artifacts={"render_report": {...}},
        pipeline_type="talking-head",
    )
except CheckpointValidationError as e:
    print(e)  # GATE VIOLATION … requires human_approved=True

```

Properly completing a gated stage requires the explicit approval flag:

```python
write_checkpoint(
    pipeline_dir=Path("/tmp/projects"),
    project_id="proj123",
    stage="compose",
    status="completed",
    artifacts={"render_report": {...}},
    pipeline_type="talking-head",
    human_approved=True,  # Explicit approval required

)

```

Downstream gated stages validate their predecessors. If `compose` is completed but unapproved, the following call fails:

```python

# "publish" stage is gated; predecessor "compose" must be approved

write_checkpoint(
    pipeline_dir=Path("/tmp/projects"),
    project_id="proj123",
    stage="publish",
    status="awaiting_human",
    artifacts={"publish_log": {...}},
    pipeline_type="talking-head",
)

# Raises: CheckpointValidationError - completed without required approval: ['compose']

```

## Schema and Testing Infrastructure

The checkpoint structure is formally defined in [`schemas/checkpoints/checkpoint.schema.json`](https://github.com/calesthio/OpenMontage/blob/main/schemas/checkpoints/checkpoint.schema.json), which specifies the `human_approved` and `human_approval_required` fields and their boolean types. This schema ensures that all checkpoint data conforms to the approval tracking format.

According to the OpenMontage source code, unit tests in [`tests/contracts/test_phase3_contracts.py`](https://github.com/calesthio/OpenMontage/blob/main/tests/contracts/test_phase3_contracts.py) enforce that every creative stage—including `proposal`, `script`, `scene_plan`, and `publish`—declares `human_approval_default: true` in its manifest. Additionally, documentation in `skills/pipelines/*/*-director.md` explicitly marks which stages gate on human approval, creating a transparent contract between pipeline designers and runtime enforcement.

## Summary

- **Manifest-driven configuration**: The `human_approval_default` field in pipeline manifests determines which stages require human sign-off.
- **`_stage_requires_approval`**: Resolves gate status by querying the manifest at lines 51-62 of [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py) and combining it with runtime flags.
- **`write_checkpoint`**: Enforces the gate at persistence time, raising `CheckpointValidationError` for unauthorized completion attempts.
- **`_enforce_stage_prerequisites`**: Validates that all gated predecessors carry `human_approved=True` before allowing downstream progression.
- **Fail-closed safety**: Stages cannot be marked completed without explicit approval, but existing checkpoints remain readable for backward compatibility.

## Frequently Asked Questions

### What happens if the pipeline manifest is missing or malformed?

If [`lib/pipeline_loader.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/pipeline_loader.py) cannot locate or parse the pipeline manifest, `_stage_requires_approval` logs a warning and returns `None`. The system then falls back to the `human_approval_required` argument provided by the caller, ensuring that missing configuration data does not accidentally open a gate that should be closed.

### Can checkpoints written before gating was enabled be modified without approval?

Yes. The enforcement applies only to new write operations through `write_checkpoint`. Checkpoints written before a gate policy was enabled remain readable and valid, preserving backward compatibility. However, any attempt to update such a checkpoint to `completed` status after gating is enforced will require `human_approved=True`.

### Which creative stages require human approval by default?

According to the contract tests in [`tests/contracts/test_phase3_contracts.py`](https://github.com/calesthio/OpenMontage/blob/main/tests/contracts/test_phase3_contracts.py), the creative stages `proposal`, `script`, `scene_plan`, and `publish` all declare `human_approval_default: true`. These stages represent critical creative decisions where human oversight is mandatory per the OpenMontage design philosophy.

### How does the system prevent bypassing approval through direct API calls?

The gate validation occurs inside `write_checkpoint` in [`lib/checkpoint.py`](https://github.com/calesthio/OpenMontage/blob/main/lib/checkpoint.py), not in client-side code. Even if a caller possesses valid credentials and attempts to set `status="completed"` directly, the function checks the manifest-defined gate policy and the `human_approved` flag before persisting state. Any violation raises an immediate `CheckpointValidationError`, making client-side bypass impossible.