Governance Gate System¶
Policy-driven approval gates that enforce quality, compliance, and review requirements at lifecycle boundaries.
Synopsis¶
Gate status is queried via MCP resource:
apogee://status/gates
Description¶
The gate system evaluates a policy file (apogee.policy.json) against
the current project state to determine whether lifecycle transitions are
permitted.
Policy conditions map symbolic codes to severity levels. For example,
missing_proof_report might be a blocker in a released project but
acceptable in a pre-release project.
Lifecycle-stage awareness: the evaluator adjusts severity defaults
based on the project’s lifecycle stage (pre-release vs released).
Pre-release projects can relax gates that would block a released product.
Immutable gates: some gates declared in skill metadata are non-overridable — they cannot be relaxed by policy configuration.
Configuration¶
Policy file: apogee.policy.json at the repository root.
{
"policy_version": "1",
"policy_name": "default",
"lifecycle_stage": "pre-release",
"default_band": "ship-quality",
"conditions": {
"missing_proof_report": "acceptable",
"missing_unit_tests": "warning"
}
}
Reference¶
Key classes
GatePolicy— immutable acceptance-gate configuration (version, name, band, lifecycle stage, conditions, required reports/runners)GateMetadata— per-workflow gate declaration (has_approval_gate,immutableflag)GateMetadataProvider— protocol for providing gate metadata
Evaluator API
evaluate_gates(inventory, policy) → GateSummary
Pure evaluation function (no I/O). Returns findings with severity ordering: blocker > warning > informational.
Severity levels: blocker, warning, acceptable, informational.
Examples¶
Querying gate status from a chain step or automation script:
# Check gate status for a feature
gate_status = read_resource("apogee://status/gates")
# Evaluate gates against policy
# Returns: blocker/warning/acceptable/informational per gate
for finding in gate_status["findings"]:
if finding["severity"] == "blocker":
raise GateBlockedError(finding["code"], finding["message"])
Programmatic evaluation without MCP (e.g. in tests):
from apogee_engine.gate_evaluator import evaluate_gates
from apogee_engine.gate_policy import GatePolicy
policy = GatePolicy.from_file("apogee.policy.json")
summary = evaluate_gates(inventory, policy)
assert summary.passed, f"Blocked by: {summary.blockers}"
What a gate looks like in practice¶
A developer completing a feature chain reaches a release-tier step. The chain engine evaluates gates before allowing the transition:
==> Gate evaluation: release-readiness
======================================
missing_unit_tests warning
missing_proof_report BLOCKER
manifest_stale acceptable
--------------------------------------
Verdict: BLOCKED — resolve blockers before proceeding.
======================================
Blocker detail:
missing_proof_report: No proof report found for feature
"incremental-branch-loading". Run the proof harness to
generate one:
apogee-proof-harness --suite incremental-branch-loading
The developer runs the proof harness, the report is written to
apogee_artifacts/, and the gate re-evaluates on the next
execute_chain(action="next"). Once all blockers clear, the
chain proceeds.
In CI: the same evaluation runs headless. A blocker sets a
non-zero exit code. The apogee.policy.json file controls which
conditions are blockers vs warnings — a pre-release project can
mark missing_proof_report as acceptable while a released
project treats it as a blocker.
Severity Levels¶
Level |
Meaning |
Action |
|---|---|---|
blocker |
Prevents lifecycle progression |
Must resolve before the transition is permitted |
warning |
Should be addressed |
Review and resolve before release |
acceptable |
Known and accepted risk |
Document the acceptance reason in policy |
informational |
For-your-information only |
No action needed; logged for audit trail |
Severity ordering is strict: blocker > warning > acceptable >
informational. The evaluator short-circuits on the first blocker
unless the caller requests a full scan.
Immutable Gates¶
Some gates declared in skill metadata carry the immutable flag.
These gates cannot be overridden by policy exceptions or lifecycle
stage relaxations.
Immutable gates exist for conditions where relaxation would compromise the integrity of the verification process itself. Examples include:
Proof report presence — a proof report must exist before any release-tier transition, regardless of policy.
Manifest freshness — the manifest must not be stale beyond a configured threshold.
Chain completion — all required chain steps must have recorded outcomes before finalization.
Immutable gates are identified by the immutable: true flag in
GateMetadata. The evaluator enforces them unconditionally:
{
"gate_code": "missing_proof_report",
"has_approval_gate": true,
"immutable": true
}
Policy conditions that attempt to relax an immutable gate are silently ignored by the evaluator. A validation warning is emitted in the gate summary when this occurs.
Note
This page is also available as a man page: man apogee-gates
See Also¶
Chain Engine — chains that insert gates at boundaries
apogee-proof — proof reports consumed by gate checks
apogee-mcp — MCP resource endpoint for
apogee://status/gatesGlossary — terminology definitions for gate-related concepts