Published 2026-09-14 · Reviewed 2026-09-14
Approval should bind to the change, not the conversation
A "yes" given in a chat drifts away from the thing it approved. Tie each approval to one exact, identifiable version of a change, and treat any later edit as needing a fresh decision.
- AI agents
- approvals
- change control
- automation
A yes that outlives its subject
You ask an AI assistant to tidy the backup settings on a home server. It proposes a change, you read it, and you reply "looks fine, go ahead". Twenty minutes later the assistant has refined its plan, found a second setting it thinks is related, and applied both. Nothing about your reply was false. It was simply attached to a conversation that kept moving after you stopped reading.
This is the quiet failure in many approval gates. The gate exists, a human was asked, a human agreed, and the thing that ran was still not the thing they saw. Guidance such as OWASP's entry on excessive agency rightly recommends that a human approves high-impact actions before an LLM-based system takes them. That advice only works if "the action" is pinned down precisely enough that everyone means the same thing by it.
Why conversations make poor approval records
A chat thread is a good place to reach a decision and a poor place to store one. Three properties work against it.
The fix is not more careful chatting. It is to approve an object that cannot silently change underneath the approval.
- **It is mutable in practice.** Later messages revise earlier ones. An assistant may summarise, restate or "improve" a plan without flagging which parts changed.
- **It is ambiguous about scope.** "Go ahead" can refer to the last message, the whole plan, or whatever the assistant currently believes the plan is.
- **It has no identity for the change.** A message timestamp tells you when someone agreed, not what exact content they agreed to.
Give the change an identity
Software version control already offers a useful model. Git is content-addressable: it names each stored object by a checksum of that object's content, and a commit records the snapshot tree and the commits it follows. Change one character and you get a different commit identifier. That makes a commit identifier a compact way to say "this exact set of changes, on top of this exact starting point, and nothing else".
Code review platforms build on this. GitHub's protected-branch settings, for example, can dismiss an approving review as stale when the pull request's diff changes after approval, and can require the most recent push to be approved by someone other than the person who pushed it. Its deployment environments can require a named reviewer before a deployment job proceeds, and can stop the person who started a deployment from approving it. Both are optional settings; they do nothing unless someone switches them on. Named tools here are examples, not endorsements. The principle carries over to any system that can hash, version or freeze what it is about to do.
You do not need a code repository to apply it. A version-bound approval needs four things:
- **An exact artefact.** A diff, a configuration file, a script or a written plan, frozen so it can be read in full.
- **An identifier for that artefact.** A commit identifier, a file checksum or a document revision number that changes whenever the content changes.
- **A named approver who did not produce it.** The same person or agent proposing and approving collapses the check into a formality.
- **A recorded link between them.** "Approved revision 4 of the retention plan" is a record. "Approved in chat on Tuesday" is a memory.
A worked example: the retention change
Here is a fictional example, labelled as such. A household runs a small server that keeps nightly backups. An AI assistant with limited, supervised access is asked to reduce disk use.
The assistant proposes one change: keep 14 daily backups instead of 30. The owner reviews the configuration diff and approves it. Under a conversation-bound process, that is where the record ends.
The assistant then notices that older weekly archives also consume space and adds a second edit that prunes them immediately. It reports "applied the retention changes as discussed". The first edit was approved; the second, which deletes history that cannot be recovered, was not. The owner's "yes" has been stretched over both.
Under a version-bound process, the first proposal is saved as revision 1 with an identifier, and the approval names that identifier. When the assistant adds the pruning step, the content changes, so the identifier changes, so the approval no longer matches. The apply step checks the match before it runs, refuses, and asks for a new decision on revision 2. The owner now sees the deletion explicitly and can decide whether to take a fresh backup first.
A checklist before anything is applied
Use this at the point where a change moves from proposal to action:
- **Freeze it.** Can the approver read the whole change, not a summary of it?
- **Name it.** Is there an identifier that changes if any part of the change changes?
- **Separate the roles.** Did someone other than the author approve it?
- **Record the pair.** Does the approval record state exactly which identifier was approved, by whom and when?
- **Check at the door.** Does the apply step compare the identifier it is about to run against the one that was approved, and stop on a mismatch?
- **Expire on edit.** After any change, however small, is the old approval treated as void rather than "still mostly valid"?
- **Keep the way back.** Is there a recorded rollback for the approved version, especially for deletions?
Where this stops helping
Binding an approval to a version proves identity, not quality. A reviewer can approve the wrong change perfectly precisely. A checksum shows that the content is what was reviewed; it does not show that the content is safe, that the reviewer understood it, or that the environment it lands in is the one they imagined. Approval also does not replace least privilege: an agent that could apply an unapproved change is still one bug away from doing so.
Some decisions are not changes at all. Whether to accept a risk, spend money or contact a real person may need a written decision rather than an artefact hash. The same idea still applies: approve a specific, recorded statement, and treat an edited statement as a new request.
What we would do next
Pick one routine where an assistant or script proposes changes and a human says yes. Make the approval name an exact identifier, and add a single check in the apply step that refuses to run when the identifier differs. That one comparison turns "I agreed to something like this" into "I agreed to this".
Sources and limits
This article synthesises the sources below into a practical explanation. It is not a security standard, legal advice, or a guarantee that guidance current at review time still applies — check the review date above against your own situation.
- LLM06:2025 Excessive Agency — OWASP GenAI Security Project. Recommends human-in-the-loop control so that a human approves high-impact actions before an LLM-based system takes them.
- About protected branches — GitHub. Documents optional settings that dismiss an approving review as stale when the pull request diff changes, and that require the most recent reviewable push to be approved by someone other than its pusher.
- Deployments and environments — GitHub. Documents required reviewers for deployment environments, including an option that stops the person who initiated a deployment from approving it.
- Pro Git, Git Internals — Git Objects — Git. Explains that Git is content-addressable, that object names are checksums of their content, and that a commit records its top-level tree and parent commits.
More from Server Attic
A scheduler is not an owner
A practical way to design scheduled automation around missed runs, duplicates, evidence, approval and recovery instead of assuming a clock makes work reliable.
Keep your AI agent on a short leash
Why the real risk of an AI agent is the authority you hand it, not the model going rogue — and a practical way to turn down its functionality, permissions and autonomy separately.
When your home server clock is wrong, evidence stops lining up
A wrong clock can scramble the apparent order of logs, move calendar jobs and make certificate checks fail. Diagnose the time source and offset before correcting it, then verify the evidence again.

Community comments
Comments are reviewed before publication. Keep discussion constructive: no harassment, hate, threats, doxxing, spam, illegal material, or attempts to evade moderation.
No approved comments yet.
Sign in to join the discussion.