An agent can complete every step in a runbook and still make the wrong change. The missing question is often not "did the command finish?" but "did the important things that should remain true actually remain true?"
An invariant check is a small assertion about the system that should survive the work. It gives an agent a boundary to preserve while it edits files, regenerates artifacts, investigates failures, or promotes a change.
Choose invariants before changing state
A useful invariant is stable, observable, and related to the risk of the task. Examples include:
- only the intended content section changed
- generated files can still be reproduced from source
- public output contains no private paths, tokens, or identifiers
- the number of published items increased by at most one
- a route that existed before the change still returns successfully
- a failed validation leaves deployment and notification steps untouched
These are stronger than a vague instruction to "be careful." They tell the agent what must be true after the next action, even if the implementation details change.
Check both positive and negative invariants
A positive check confirms the intended result: the new article has the expected slug, the build produced the expected route, or the index contains the new item. A negative invariant confirms that an unwanted result did not occur: no unrelated files changed, no draft became public, and no private diagnostic text entered the generated site.
Pairing the two catches a common automation error: proving that the target exists while failing to notice that the operation also changed something outside scope.
A compact runbook rule might look like this:
After each state-changing step, verify the intended output and at least one relevant absence. Stop if an invariant fails; do not continue to deployment or notification.
Make invariants cheap to replay
Invariants should be easy to check at promotion gates. A source diff, content validator, build, route fetch, generated-file scan, or item-count comparison is usually more useful than a long session transcript. Stable labels and expected values make the result easy to include in a public-safe handoff.
Invariant receipt
Intended: one new published note is present at the expected route.
Preserved: no unrelated source files changed; generated output was regenerated.
Absent: no credentials, private paths, or internal identifiers in public output.
Decision: continue only if all three assertions pass.
The receipt records the conclusion without exposing raw logs or sensitive context. If an assertion fails, the same format explains why the agent stopped and what a reviewer should inspect next.
Treat failed invariants as scope changes
When an invariant fails, the agent has learned something important about the system. It should switch from execution to diagnosis: identify which assertion broke, preserve the last safe state, and decide whether a bounded correction is justified. It should not silently widen the task to make the assertion pass.
Invariants turn verification into a control loop rather than a final ceremonial check. They keep unattended work aligned with its purpose, make regressions visible early, and give the next operator a concise way to trust—or challenge—the result.