Skip to main content

ADR-0010: Remediation state machine, idempotency, and drift

Status: Accepted · 2026-07-14

Decision

ActionRequest state machine: Draft → Validated → AwaitingApproval → Approved → Executing → Verifying → Succeeded | PartiallySucceeded | Failed | Cancelled | Drifted with transitions enforced in one module and by DB constraints.
  • Envelope: tenant, typed action + version, target snapshot (asset + source version at preview time), current/desired state, initiator, justification, approval policy, idempotency key, execution attempts, verification evidence.
  • Separation of duties: the requester cannot approve their own action (policy check + test). Approval requires action.approve capability scoped to the action type/domain.
  • Idempotency: executor deduplicates on (tenantId, idempotencyKey); duplicate delivery of an approved action performs exactly one source mutation (tested with duplicated queue delivery).
  • Drift: before execution, the connector re-reads the target; if source version differs from the approved snapshot, the action transitions to Drifted and requires re-preview (no silent convergence by default).
  • Verification: after execution, the source state is re-read and stored as a RemediationVerified observation; executor success text alone never marks success.
  • MVP action types: internal remediation task (fully live), Purview label assign/change (adapter real; live execution config-gated on protected/metered API enablement — blocked state reported honestly), label downgrade/removal requires justification + approval by policy default.

Consequences

  • Duplicate delivery, drift, and self-approval are all covered by automated tests.
  • Rollback is recorded only where genuinely supported (internal tasks); no implied rollback guarantee for label operations.