checkId: check.release.environment.matches-approved plugin: release-orchestrator severity: warning tags: [release, estate, drift, deviation, deployment]
Environment Matches Approved Releases
Source verified against 7dd8ee3985 (2026-10-13). Re-verify with tools/scripts/test-targeted-xunit.ps1 -Project src/ReleaseOrchestrator/__Tests/StellaOps.ReleaseOrchestrator.Integration.Tests/StellaOps.ReleaseOrchestrator.Integration.Tests.csproj -Method '*EstateDoctorOwner*' -BuildProjectReferences. This source check is distinct from the dated live observation below.
Release Orchestrator serves this check through its existing doctor-check/v1 host at GET /doctor/release-orchestrator/checks, authorized by ops.health. It reads its own deployed estate, latest verdicts and agent drift observations. The singleton Doctor context is not a tenant-domain request: results contain owner-wide counts, without tenant, environment, release, agent, digest or verdict identifiers. Use the tenant-scoped Estate and chain reads for details.
The former StellaOps.Doctor.Plugin.Release implementation is withdrawn. Loading that plugin or running stella doctor run does not execute this service-owned check. The estate worker’s estate-doctor profile remains core.worker, docker, observability, security and servicegraph; this adoption adds no worker family and no host.
What it checks
The check enumerates the owner’s deployed tenants, reads each tenant explicitly and reuses EstateRiskAssessment, the classification used by Watch and estate status. Drift observations are matched through the existing tenant UUID resolver, without choosing a request/default tenant.
| Classification | Healthy | Severity | Meaning, in precedence order |
|---|---|---|---|
mismatch | false | Critical | Drift, an outstanding deviation, or a re-evaluation without an authorizing baseline. Known mismatches retain precedence over incomplete reads elsewhere. |
unavailable | false | Warning | An inventory, tenant, verdict, resolver or drift read failed or returned no required result. |
unverified | false | Warning | Invalid attribution, unevaluated/unknown subjects, unresolved tenants, absent/truncated/unobserved/unknown observations, or current deployed digests missing from the tenant’s observations. |
no-data | false | Warning | No deployed estate establishes agreement. |
matches-approved | true | Info | No outstanding mismatch and established observation and re-evaluation coverage. |
No deployed components is not a pass. A standing regression counts once; a recovered or replaced release no longer counts. Unknown outcomes never establish current risk. An in_sync agent status alone does not establish coverage: every distinct currently deployed digest must occur in that tenant’s non-truncated in-sync observations. Empty observations and observations of only another approved digest cannot pass. The stored observation contract does not bind each container observation to a deployment target or environment. This check establishes tenant-wide current-digest coverage only; it does not prove every placement is observed or introduce a freshness threshold. Those limits remain explicit even when healthy=true.
Evidence contains classification; estate.deployedComponents, estate.subjects, estate.deviations, estate.unbaselined, estate.unevaluated, estate.unknown, estate.invalidRows; observation.inSyncAgents, observation.driftingAgents, observation.unobservedAgents, observation.unknownAgents, observation.unobservedTenants, observation.unresolvedTenants, observation.unobservedDigests; read.failures, bounded read.failureTypes when present, and this article’s runbook path. Error messages and tenant identifiers are not copied into evidence. Cancellation propagates.
Inspect and repair
Use an operator token from the established runtime credential mechanism and read the owner route named above through the existing authenticated client. Do not save credentials in commands or outputs. On the local estate the Console origin serves this route at https://stella-ops.local/doctor/release-orchestrator/checks.
Find check.release.environment.matches-approved in checks. HTTP 401/403 is a refused read, not a healthy result. An absent check means the serving owner has not adopted this source. For detail, use authenticated Console Estate/custody views or the tenant-scoped /api/v1/release-orchestrator/estate/status, /estate/drift, /estate/deviations and /estate/chain-completeness reads. Their own domain scopes and tenant restrictions still apply; ops.health does not grant them. A deviating placement also counts as a chain gap, so the Compliance assurance queue groups intentionally overlap.
- Docker Compose: inspect the existing Release Orchestrator service and agents. Restore the heartbeat/digest path or failed owner dependency. For real drift, restore the pinned digest through the approved deployment process; do not retag an unapproved image.
- Bare metal: inspect existing service/agent processes and connectivity, restore observation or the failed owner read, then repeat the authenticated check. A missing authorizing decision requires the normal approval workflow, not a diagnostic data patch.
- Kubernetes: unsupported by the product’s non-Kubernetes estate contract; this article does not prescribe Kubernetes repair or admission.
For changed risk, review the Policy basis and use the authorized remediation/re-evaluation workflow. The subsequent owner read must show recovery; waiting for the hourly job is not proof. The check performs no remediation, scan, approval or deployment.
Platform registration
Direct authenticated owner pulls need no registration. To include this check in Platform’s existing aggregate, Release Orchestrator registers its check catalog with Platform’s Doctor registry. The Release Orchestrator compose overlay (devops/compose/docker-compose.release-orchestrator.yml) sets:
Doctor__Registration__Enabled=${RELEASE_ORCHESTRATOR_DOCTOR_REGISTRATION_ENABLED:-false}
Doctor__Registration__PlatformBaseAddress=http://platform.stella-ops.local:8080/
Doctor__Registration__SelfEndpoint=http://release-orchestrator.stella-ops.local:8080/doctor/release-orchestrator/checks
Doctor__Registration__Tenant=default
Registration is off by default, as in the other service overlays: the registrar sends requests to Platform, so an installation opts in. An estate that registers, such as the local estate under the owner ruling of 2026-10-19, sets RELEASE_ORCHESTRATOR_DOCTOR_REGISTRATION_ENABLED=true in its environment file; a sealed installation leaves it unset. These settings ship in the Release Orchestrator compose overlay only. The release bundle (devops/release/bundle/docker-compose.yml) and devops/compose/docker-compose.stella-services.yml define release-orchestrator without any Doctor__Registration key, so an installation from the release bundle does not register until the bundle carries these settings.
Both addresses are direct listeners with their port; verify owner-to-Platform and reverse connectivity before a recreate. Registration uses the existing shared stellaops-release-dispatch identity; do not register a second host auth client. That client is assigned two tenants, so the token request must select one: Tenant=default identifies the registration/token context, and the check remains owner-wide. The client’s platform:doctor:register grant is declared in devops/etc/authority/plugins/standard.yaml, and Authority applies it to an existing install through the Startup migration 040_authority_release_dispatch_doctor_register_scope.sql (Seed companion S068_release_dispatch_doctor_register_scope.sql). Enable registration only after the Authority deployment that applies 040: until the grant is present, Authority refuses the registrar’s token request (invalid_scope) and the registrar retries every 30 seconds, without stopping the host. Platform’s existing stellaops-platform-doctor pull identity needs ops.health. After activation, verify the exact check ID in the owner response, Platform capabilities and aggregate. Registration absence, authentication failure or an absent check is not a clean result.
The 2026-10-13 read-only observation found registration disabled and the deployed owner response without this check. Activation on an estate needs, in this order: the Authority deployment that applies migration 040 (read back both scope values of the client), then RELEASE_ORCHESTRATOR_DOCTOR_REGISTRATION_ENABLED=true and a Release Orchestrator recreate that carries these compose settings. Platform needs no change. Withdrawal changes the legacy Release plugin artifact in profiles already carrying it; the neutral SDK and five-family estate-worker profile are unchanged. The single AdvisoryAI seed entry is copied publish content; refresh its owning knowledge artifact when deploying that change.
