Idempotency Is Necessary, Not Sufficient


A playbook can pass every idempotency test I described in the last post and still be the wrong candidate for automatic approval. Pre-check, post-check, rollback: all three present, all three proven. That tells you the playbook is safe to run without a human standing by. It does not tell you how much of the environment it touches, or what depends on the thing it’s changing. A taxonomy that only checks for idempotency will auto-approve changes it should not, because it never asks about blast radius, dependency chain, or reversal cost.

A config change scoped to one host and a firmware push that hits every hypervisor in a cluster at once can both be idempotent, but blast radius makes them different risks: one breaks a lot more at once if the rollback path itself fails.

A service restart is low risk if nothing outside the automation notices it happens. It is a different change if a downstream consumer polls that service every few seconds and treats a gap as a failure. Idempotency describes what the playbook can undo, not what already reacted before it got the chance, and that gap is what the dependency chain measures.

A rollback-capable playbook proves the state can be undone. It does not prove the outage window the change created can be undone, and that gap is where reversibility outgrows idempotency. Ninety seconds of downtime on a payment path is not the same risk as ninety seconds on a batch job that retries anyway, even when both changes are equally reversible on paper.

Put the three together and the tier structure follows directly. A change with a narrow blast radius, no external dependency, and a reversal cost contained inside the automation auto-approves with no notification needed. Widen the dependency to one that tolerates a brief gap and the same change still auto-approves, except the downstream owner gets told after the fact. Everything else goes to a human: a wide blast radius, a dependency that is intolerant or unclear, a reversal cost that lands on the payment path instead of the batch job, or a playbook that never cleared the idempotency bar.

Idempotency gets a change into the first two tiers. It cannot get a change out of the third on its own. Enforcing that tier structure automatically, instead of relying on memory, is a job template problem, and it is what the next post takes on.