Added a preflight play that runs the same code as the converge against operator‑local secrets in about a second, after a half‑applied production run died on its ninth task with the swap settings already written to the live host.
Work carried out: 2025
Situation. Operational secrets had just been split so that each host carries its own backup repository, passphrase and alert switch. The repository code was correct. The operator’s encrypted vault still held the previous single‑host value, and nothing could see the mismatch, because the vault is deliberately local to the operator’s machine and invisible to the repository’s own quality gate.
Task. That class of failure needed somewhere to fail cheaply, because it had just failed expensively.
Action. The first converge after the change connected to the live host, ran eight tasks and refused on the ninth — correctly, but from inside a run that had already written swap settings to production. A half‑applied converge is a worse answer than a refusal, so a preflight play was written: it reaches no host at all, runs locally, gathers no facts, and executes the same two task files the real converge uses against the operator’s vault. It answers in about a second, and provisioning runs it first. The load‑bearing decision is that it is the same code rather than a second implementation of the same rule, because a check that restates a rule in another language eventually disagrees with it and disagrees silently. Writing it surfaced a trap it nearly created: facts set during a play outlive that play, so chaining the preflight and the converge into one invocation would have handed the real role a passphrase the preflight had already resolved, and passed the check on a vault that was still wrong. That was reproduced before it was guarded, in both task files.
Result. A secret that does not resolve now costs a two‑second refusal on a laptop instead of a partly‑applied change to a live server. The preflight is deliberately not tagged to always run and is deliberately not serialised, and both of those are recorded as decisions rather than defaults.