Skip to content

Drift Detection

Drift is a disagreement between an authoritative input, a derived artifact, a deployed state, or the evidence used to explain either one. Atlas classifies drift by ownership so operators can correct the source rather than normalize an unexplained difference.

Drift Chain

flowchart LR
    Source["Governed source"] --> Generated["Generated manifest or inventory"]
    Generated --> Packet["Release packet"]
    Packet --> Deployed["Rendered and deployed state"]
    Deployed --> Observed["Runtime observation"]
    Source -. compare .-> Generated
    Generated -. compare .-> Packet
    Packet -. compare .-> Deployed
    Deployed -. compare .-> Observed

Governed Classes

The checked-in drift simulation defines five negative fixtures:

Drift class Fixture mutation Risk exposed
Configuration Changes inventory schema version Producer and consumer interpret different shape
Artifact Manifest references a missing file Release inventory cannot be materialized
Registry Adds an unknown invariant Policy references an unowned identity
Runtime configuration Offline values name an unknown dataset Cached-only runtime cannot establish data authority
Operations profile Install matrix names an unknown profile Deployment intent has no governed profile contract

These fixtures prove expected detector inputs. They do not show the current repository or a deployment is drift-free.

Name the Baseline Before Comparing

Every drift result needs two identities: the observed subject and its expected baseline. “Different from main” or “different from production” is insufficient when either reference can move.

Surface Baseline identity Observation identity
source and generated files source revision plus generator and control hashes checkout revision plus generated-file hashes
release packet packet manifest and evidence-set digest candidate packet digest
Kubernetes deployment approved rendered-manifest and image digests cluster, namespace, workload revision, and live-object digest
runtime configuration approved effective-configuration receipt pod and configuration identities plus parsed result
dataset release, species, assembly, manifest, and payload hashes resolved runtime dataset identity and verified bytes
telemetry release-labeled signal contract and deployment identity scrape, log, and trace source identities

Capture both sides before remediation. If the baseline cannot be identified, classify the comparison as indeterminate rather than clean.

Current Evidence Boundary

The repository contains example drift reports under ops/_generated.example/, but no current configuration, control-plane, fixture, registry, schema, or stack drift reports under ops/_generated/. The active generated directory contains only a control-plane surface list. A generated readiness score that says inventory_drift: none is not a substitute for the absent reports because it does not preserve their comparisons or findings.

The checked-in ignore rules are also an example. They suppress an unknown profile finding by path and message. Do not activate an ignore without owner, rationale, expiry, and evidence that the divergence is safe.

Account for Detection Coverage and Blind Time

A clean comparison says nothing about the interval before or after it. Every drift claim needs the surfaces observed, comparison cadence, last successful baseline, current observation time, and any gap where collection or comparison was unavailable.

flowchart LR
    Baseline[Approved baseline] --> Compare[Scheduled or event-driven comparison]
    Observation[Observed state] --> Compare
    Compare --> Result{Difference found?}
    Result -->|yes| Finding[Classify and contain]
    Result -->|no| Clean[Bounded clean receipt]
    Gap[Collector or comparison gap] --> Unknown[Unknown drift interval]
Coverage property Required record
scope source, generated, packet, deployment, runtime, dataset, and telemetry surfaces actually compared
trigger schedule, deployment event, catalog promotion, policy change, or incident action
freshness baseline identity, observation time, and maximum accepted age
continuity successful comparison sequence and missing intervals
enforcement alert, promotion hold, containment action, and owner

After an observation gap, compare the complete governed state before declaring the environment clean. Resuming a collector proves only that collection returned; it cannot show whether an unauthorized change occurred during the gap. Preserve the unknown interval in incident and promotion evidence.

Classification and Action

  • Source changed, generated output stale: regenerate from the authoritative source and review the complete diff.
  • Generated output changed without source change: reject it and investigate the generator or provenance.
  • Packet differs from verified evidence: reject and rebuild the release set.
  • Deployment differs from packet: contain the environment and reconcile through the deployment authority.
  • Observation differs from declared state: confirm telemetry identity, then treat the result as runtime or configuration drift.

Any drift that changes installed resources, security posture, dataset identity, recovery authority, or consumer-verifiable evidence blocks promotion. Preserve the raw comparison, classification, owner, decision, and final corrected state.

Close a Drift Finding

flowchart TD
    Detect[Detect difference] --> Attribute[Bind baseline and observation]
    Attribute --> Classify[Classify owning surface and impact]
    Classify --> Decision{Expected and authorized?}
    Decision -- no --> Contain[Block promotion or contain deployment]
    Contain --> Repair[Repair through owning authority]
    Decision -- yes --> Govern[Update governed baseline]
    Repair --> Recheck[Repeat original comparison]
    Govern --> Recheck
    Recheck --> Evidence[Retain finding, decision, and closure evidence]

A finding is closed only when the original comparison passes against the intended baseline or an authorized baseline change explains the difference. An ignore rule suppresses a detector result; it does not reconcile state.

After repair, also verify downstream consumers. Regenerating a manifest does not prove a release packet, deployment, or runtime refreshed to that identity.

See Environment Overlays for execution identity and Release Packets for transport coherence.