Skip to content

Operational Readiness Review (dev-to-ops handoff gate)

Before a dev-owned scope (a resource group, a workload, an environment) becomes the operations team’s responsibility, use the automated Operational Readiness Review (ORR). It evaluates the whole scope against the governance, security, RBAC, and reliability rules that ops depends on, grounds each detected issue in the exact rule that produced it, and returns one decision - clear, needs_review, or blocked - keyed to the ownership-transfer event. It is the deployment-preflight pass and the assurance-twin posture assessment, composed into a single handoff gate so nothing crosses the dev-to-ops boundary un-reviewed.

This closes a class of failures that a per-change review misses: a workload can be individually compliant on every merge yet still arrive at ops with an over-privileged managed identity, a guest principal holding Owner, no diagnostic settings, or no backup - because no single change introduced the whole gap. The ORR reviews the accumulated posture of the scope at the moment of handoff, not one diff.

Customer-agnostic: the trigger label, the required-rule set, and the severity that gates a handoff are all config or fork-supplied. Upstream ships the machinery and the generic ReadinessReport shape, never a customer’s specific handoff policy (generic-scope.instructions.md).

Where it sits: the ORR is a read-only review built on the assurance twin. It holds no privileged identity and executes nothing. Every proposed fix still flows through risk-gate -> executor -> delivery, preserving the read-only surface rule in app-shape.instructions.md.

The pieces already exist; what was missing is the handoff as a first-class milestone. Three surfaces overlap but none of them, alone, is the dev-to-ops gate:

Existing surfaceWhat it reviewsWhy it is not the handoff gate
deployment-preflightone deploy: can this change land in the target scopescoped to a single terraform apply / fix PR, not the accumulated posture
assurance-twin proactive reviewone change event: does this diff violate a ruleper-diff; a scope can pass every diff and still fail as a whole
assurance-twin PostureAssessmentReportthe whole estate on demandnot bound to an ownership-transfer event; nobody is required to run it before ops takes over

The ORR binds the whole-scope assessment to the ownership-transfer event and makes it a required, audited, observation-first gate.

The ORR is triggered, not polled. When a scope is proposed for handoff, an ownership_transfer signal enters event-ingest, is normalized like any event, and drives one review pass:

ownership_transfer signal
-> event-ingest (normalize)
-> assurance-twin: run every applicable rule over the scope projection
-> deploy-preflight: run the feasibility probes over the scope
-> checklist evidence: evaluate rules, artifacts, metrics, drills, and approvals
-> compose -> ReadinessReport (clear | needs_review | blocked)
-> blocked + enforce mode -> gate the handoff, route fixes to risk-gate/HIL
-> audit (Saga)

Both inputs are deterministic-first (T0-flavored): static evaluation over the twin projection resolves most detected issues; bounded, read-only probes confirm the rest. Nothing in the pass mutates anything.

The ownership_transfer signal is the CSP-neutral event that starts the review. It is emitted by whatever the fork wires as the handoff moment:

  • a pull-request label (ops-handoff-requested) on the IaC repo, or
  • a resource tag applied to the scope (lifecycle-stage: handoff), or
  • an explicit operator request through the console (request_ops_handoff).

The signal carries the target scope (resource-group-equivalent or narrower, the same scope hierarchy the rule-governance overrides use), the submitter identity, and the target environment. It never carries a role or a privileged token.

The ORR runs the full applicable rule set over the scope. Five dimensions are the ones ops most depends on and that a per-change review most often misses:

DimensionRepresentative checkSourced from
policy_guardraildisallowed resource types, public access, missing encryptionrule-catalog-collection.md
identity_rbacover-privileged workload identity, guest holding Owner, standing privileged access, wildcard-action role, Owner-count over limitthe workload RBAC least-privilege rule pack (managed-identity.role-assignment.*, subscription.role-assignment.*, resource-group.role-assignment.*)
reliabilityno backup / PITR, no diagnostic settings, no zone redundancycatalog reliability rules
dependency_orderingrequired links (private endpoint, NSG, diagnostic settings) present before handoffdeployment-preflight probe
best_practiceframework controls with explicit rule, probe, artifact, metric, drill, and approval requirementsrule-catalog/best-practices/ plus ARB bindings

The identity_rbac dimension is the one the ORR adds that neither preflight nor per-change review covered before: preflight’s identity_rbac probe checks the executor’s permission to deploy, while the ORR checks the workload’s own least-privilege posture using the authored RBAC rules. See architecture.instructions.md § Rule Catalog.

The pass assembles detected issues into a ReadinessReport - a generalization of the PostureAssessmentReport (assurance-twin.md) bound to an ownership-transfer event. Each detected issue keeps the same three required parts:

  • evidence - a CSP-neutral citation of the rule, probe, or Best Practice control that produced it. Checklist detected issues also retain control_id and the unmet requirement_refs. A detected issue that cannot cite a source is a defect, the same rule the T2 verifier and preflight probes follow.
  • severity - preserves the source value: posture levels such as low through critical, or preflight warning / blocking. The coordinator records the resolved gate separately in the detected issue’s blocking boolean.
  • resolution - how to clear it, mapped to a concrete fix ActionType (for the RBAC dimension, remediate.right-size-role) or to guidance when no autofix exists.
DecisionMeaning
clearno detected issues
needs_reviewdetected issues exist but none is blocking (warnings only)
blockedat least one blocking detected issue

The report always records the truthful decision. Whether that decision gates the handoff is a separate flag, blocks_handoff, true only when the ORR ran in enforce mode - the same truthful-decision / separate-gate split the deployment-preflight blocks_deploy flag uses.

Every ORR ships in observation mode: it reports blockers truthfully but blocks_handoff stays false, so an unproven review can never wrongly stop a real handoff on a false positive. Promotion to enforce is per-environment and gated on a measured false-positive rate on the frozen scenario set, the same promotion discipline the ActionType contract and the preflight probes apply.

A blocked ORR does not just list problems. Each detected issue with an autofix carries a observation mode fix-PR proposal built from the rule’s fix ActionType, exactly as the assurance twin does. For the identity dimension that is remediate.right-size-role, which narrows an over-broad grant to least privilege; because RBAC changes carry a resource_group impact scope and AsymmetricRollback, they route to human approval through risk-classification.md and never auto-execute. The ORR proposes; a human approves; the executor applies. The console and ChatOps remain read-only surfaces.

The proposal builder is deterministic and holds these invariants:

InvariantBehavior
Grounded onlyA proposal exists only when the detected issue’s own cited control or rule maps to a fix ActionType in the caller-supplied lever map. An unmapped detected issue produces no proposal; the ORR holds for review rather than inventing a lever.
Observation mode onlyEvery proposal carries shadow, even when the ORR gate itself runs in enforce. The review cannot raise an ActionType above its own promotion state.
Distinct approverThe handoff submitter cannot approve their own fix. Principals are compared after Unicode NFKC folding, so an encoding variant of the submitter is still a self-approval attempt. Any such attempt is denied and audited before any proposal is built.
No executor identityA proposal records the submitter and approver as accountability facts only. It carries no credential, token, or executor principal.
Deterministic identityThe same scope, environment, cited evidence, resource, and ActionType always derive the same idempotency key, so a redelivered proposal is a downstream no-op.

Delivery is two-phase audited: the service records the proposal intent with the approver identity, publishes each proposal through the RemediationProposalPublisher seam, then records delivery. A publisher failure records the failed delivery with the delivered count and propagates; it never reports a silent success and never falls back to a direct call.

The ORR is the enforcement point for environment promotion (dev -> staging -> prod). The ownership_transfer signal carries the target environment, and the gate tightens with it: a promotion into prod treats any critical detected issue as blocking regardless of the profile default, reusing the prod-downgrade posture that every mutating ActionType already declares (risk-classification.md). The environment classifier and promotion order are specified in environment-promotion contract; the ORR consumes them and doesn’t define them.

The ORR introduces no new privileged surface and minimal new code: it composes the existing core/assurance_twin/ and core/deploy_preflight/ subsystems and adds a thin coordinator plus one normalized signal.

ComponentResponsibility
ownership_transfer signalnormalized event (scope + submitter + target environment) that triggers the review; emitted by a fork-wired handoff moment
core/assurance_twin/reportrun every applicable rule over the scope projection (reused)
core/deploy_preflightrun the feasibility probes over the scope (reused)
core/readiness/checklistcombine explicit requirement outcomes without treating missing evidence as a pass
ORR coordinatorcompose posture, preflight, and checklist results, apply the environment gate, set blocks_handoff
composition/readiness.pyrun posture, preflight, and optional checklist evidence concurrently, audit success/failure, and publish the serialized report
composition/readiness_evidence.pyproject ARB artifacts, evidence expiry, and owner bindings into typed outcomes
core/readiness/remediationderive deterministic, grounded, observation mode-only fix proposals and reject self-approval
fdai-service-contracts/readiness_remediationdefine the content-addressed, no-authority observation mode request and its generated JSON Schema
core/control_loop/readiness_remediationvalidate the exact event source, ActionType trigger and arguments, and active ontology release digest; invoke the unified safety check without dispatch
runtime/consumers.py and bootstrapvalidate and deduplicate canonical ownership_transfer events, invoke the Forseti-accountable review after startup readiness, and dead-letter malformed payloads
runtime/bootstrap_readiness.pywhen the complete posture/report pair is active, select the upstream EventBus fix adapter from the active ontology release and active Rule fix declarations; an incomplete release or empty lever map leaves fix unavailable
delivery intenta fork binds ReadinessReportPublisher to a Checks API annotation / console ReadPanel; Core selects the upstream RemediationProposalPublisher mechanically and the deployment still supplies no approval, promotion, or execution authority through that selection

The coordinator imports only shared/ contracts and providers, like every other core subsystem (project-structure.md). It holds no cloud SDK and no privileged identity.

  • Read-only review, gated execution: the ORR and every detected issue are read-only; the only path to a mutation is a proposal that enters risk-gate -> executor, with the seven safeguards (stop-condition, rollback, impact scope limit, dry-run, resource lock, idempotency, audit entry) enforced there.
  • Approval and execution stay distinct: HandoffApproval carries a distinct principal’s decision, and OperationalReadinessService.propose_remediations denies and audits a self-approval attempt before building any proposal. The proposal publisher is not yet bound to the live safety check, so the end-to-end Var approval flow remains open.
  • Fail closed: a stale twin (inventory freshness beyond freshness_ttl) refuses to certify a handoff rather than certify on stale state; an ungroundable detected issue holds for review; an unproven review stays observation mode.
  • Audited: The current service records the ORR decision, blocks_handoff, submitter, target scope, environment, workflow id, accountable Forseti attribution, and delivery/assessment failures in append-only state-store audit entries. Fix entries additionally record the approver identity, the observation mode, the proposal count, and the delivered count on failure. Saga agent attribution must be added with the future event-driven approval workflow.
To learn aboutRead
The whole-graph review the ORR composesassurance-twin.md
The single-deploy feasibility pass it reusesdeployment-preflight.md
The RBAC least-privilege rules the identity dimension firesrule-catalog-collection.md
The cross-agent workflow that runs the gateoperational readiness handoff
The environment model the gate consumesrisk-classification.md § Environment Promotion
The risk classification each proposed fix resolves againstrisk-classification.md
To learn aboutRead
Delivery status and remaining workImplementation ledger