A reviewer approves an AI-drafted refund at 4 pm. The workflow executes it at 4:05. Between those times, the customer wrote "never mind, found it." Who is right? This is the stale approval problem, and it shows up in almost every human-in-the-loop approval step in an AI workflow once volume grows.
Pin the approval to a version
Approve a specific snapshot, not "the refund for customer X."
import hashlib, json
def fingerprint(action, context):
payload = {"action": action, "last_msg_id": context["last_msg_id"],
"order_status": context["order_status"], "amount": action.get("amount")}
return hashlib.sha256(json.dumps(payload, sort_keys=True).encode()).hexdigest()
def request_approval(store, action, context):
fp = fingerprint(action, context)
store.save(action_id=action["id"], fingerprint=fp, status="pending")
return fp
Re-check right before executing
def execute_if_still_valid(store, action, load_context, run):
record = store.get(action["id"])
if record.status != "approved":
return "not_approved"
if fingerprint(action, load_context(action)) != record.fingerprint:
store.update(action["id"], status="needs_review")
return "stale_back_to_reviewer"
run(action, idempotency_key=action["id"])
store.update(action["id"], status="done")
return "done"
Notes
- Choose fingerprint fields carefully. Include what would change the decision (new messages, order status, amount), not every timestamp.
- Use an idempotency key so a retry does not refund twice.
- Tell the reviewer why it came back. "Customer sent a new message after approval" saves a confused second look.
We write about scoping these decisions in our guide to auditing a workflow first.
Top comments (0)