Authority, context and temporal truth
The irreversibility gradient and transaction semantics
Actions should move from automatic retry to guarded rollback, compensating sagas, escrowed commit and named human authority as the option to recover their effects decays.
TLDR
- A timeout is uncertainty, not evidence that an action failed.
- Idempotency prevents duplicate intended effects; it does not make an action safe or reversible.
- Compensation creates a later balancing state; it rarely erases history or every downstream consequence.
- As recovery options decay, validation and review must move before commit.
- Every consequential tool call needs a typed action contract, an effect receipt and an explicit recovery mode.
The payment that both happened and did not
At 11:58, an operations agent submits a synthetic £12,400 supplier payment. The bank connection stalls. Thirty seconds later the agent receives a timeout and the workflow marks the step as failed.
The obvious response is to retry. The invoice is due at noon, and delay has a cost. Yet the timeout says nothing about whether the bank committed the transfer. It says only that the agent did not receive a usable reply. In one possible world, the request never crossed the bank’s admission gate. In another, the debit and credit were posted, but the acknowledgement vanished on the return path. The agent sees the same observation in both worlds.
Suppose it retries with a fresh request identifier. In the first world, the retry repairs a missed action. In the second, it creates a duplicate payment. Suppose instead it refuses to retry. In the first world, the supplier remains unpaid. In the second, everything is fine. The output label failed has collapsed two causally different states into one.
The hidden mistake is treating uncertainty about an effect as evidence about the effect. Distributed systems have lived with this problem for decades. Machine-initiated action makes it more dangerous because a model can generate plausible next steps faster than a human can reconstruct what actually happened.
A timeout with two possible worlds
A request passes through at least four relevant moments. The caller forms an intent. The remote system accepts or rejects the request. The effect commits. The caller observes an acknowledgement or performs a later readback. These moments are often close together, so ordinary interfaces treat them as one event. Failure separates them.
HTTP formalises one part of the answer. A method is idempotent when multiple identical requests have the same intended effect as one request. That property allows automatic retry after a communication failure, provided the operation is genuinely idempotent or the client can determine that the first request was never applied.1 The word intended matters. A server can still log every request or produce other side effects. Idempotency is a contract about the requested effect, not a promise that nothing else happens.
Four clocks, not one
The next design move is to stop representing an action with a single status field. A useful action record distinguishes at least four clocks:
- Intent time: when the principal formed and authorised this particular action.
- Admission time: when the target system accepted the request for processing.
- Effect time: when the authoritative state changed.
- Observation time: when the caller obtained an acknowledgement or read the effect back.
These clocks can share a timestamp in a local database transaction. Across services, they can diverge. A timeout after admission but before observation creates an explicit uncertain state. That state is neither failure nor success.
“Exactly once” belongs to the effect, not the message
Engineers sometimes describe the goal as exactly-once delivery. That phrase can obscure the real obligation. A message broker may deliver once while the worker crashes after applying the effect but before recording completion. It may deliver twice while the application correctly deduplicates both attempts into one effect. The number of deliveries and the number of intended effects are different variables.
Consider a queue containing the instruction “credit account A by £10”. A worker reads the message, credits the ledger, and then loses power before acknowledging the queue. The queue reasonably redelivers. If the worker treats the second delivery as a new instruction, the ledger changes by £20. If it records the stable intent identifier inside the same protected boundary as the credit, the second delivery can return the first result. The queue still delivered at least twice; the business effect occurred once.
This distinction becomes harder across several systems. Suppose a payment service commits the transfer, a notification service sends a message and an analytics service records the event. One idempotency key does not automatically make all three effects atomic. Each consumer needs its own deduplication or replay contract, and the orchestrator needs evidence about which effects completed. Otherwise the system can be financially correct but communicatively wrong, or communicatively correct while the ledger is uncertain.
The useful guarantee is not “the network delivered exactly once”. It is “this declared intent produced no more than one authorised effect in each governed boundary, and every required effect can be read back”. That formulation is less elegant, but it survives crashes, retries and partial execution. It also reveals why a single green checkmark is inadequate for compound actions.
Worked example 1: a mentally traceable retry
A service exposes create_transfer(amount, beneficiary, intent_id). The first call with intent INV-804 commits, but its reply is lost. A retry carries the same intent identifier and the same request fingerprint. The service returns the previously recorded result instead of creating another transfer. If the amount changes while the intent identifier stays the same, the service rejects the call as an intent conflict.
The key is not a random technical token. It binds retries to a stable, auditable human or system intent. Idempotency is strongest when it preserves declared intent, rather than only repeated bytes.
This solves duplicate execution under uncertainty. It does not solve whether the action should have been attempted, whether its effects can be repaired, or whether a model had the authority to propose it. For those questions, we need a second distinction.
flowchart TD A["The payment that both happened<br/>and did not"] --> B["A timeout with two possible worlds"] B --> C["Undo is not one operation"] C --> D["Transaction modes on the slope"] D -. "re-test" .-> A classDef first fill:#0a1424,stroke:#B96D00,stroke-width:2px,color:#e6f3ff classDef step fill:#0a1424,stroke:#3f7da0,stroke-width:1px,color:#e6f3ff class A first class B,C,D step
Undo is not one operation
Imagine an assistant changing a draft invoice address. The new value is wrong. A versioned database can restore the previous address in milliseconds. Now change one property: the invoice has already been sent, imported into the supplier’s system and used to schedule a shipment. The original field can still be restored, but the outcome cannot.
Classic transaction processing gives us atomicity, consistency, isolation and durability for state inside a defined transaction boundary.34 That boundary is powerful, but it is not the world. A database can roll back a row; it cannot make a recipient unread an email, return a lost market opportunity or forget a public allegation.
Rollback, compensation and containment
Three recovery verbs are often mixed together:
- Rollback restores controlled state to a prior valid version, usually before outside observers can rely on the intermediate state.
- Compensation performs a new action intended to neutralise selected consequences of an earlier action.
- Containment stops further propagation when neither rollback nor complete compensation is available.
A refund is compensation. It does not delete the original charge from history, restore the customer’s temporarily reduced balance, recover fees automatically or erase the anxiety created by an unexplained debit. Microsoft’s current guidance makes this boundary explicit: compensating transactions are application-specific, can fail, and do not necessarily return data to its starting state.6
A recovery envelope
Rather than ask whether an action is reversible, describe its recovery envelope: the set of states that can still be reached after an error, within an acceptable time, using available authority and resources. Four properties shape that envelope.
- Restoration gap: how much of the prior state and outcome cannot be re-established.
- Propagation reach: how many independent systems, people or physical processes can act on the effect.
- Temporal decay: how quickly recovery options lose value or disappear.
- External dependence: how much recovery relies on parties or resources outside the controller’s authority.
Each property can be scored ordinally from 0 to 4 for routing, not measurement. A public announcement may score modestly on state restoration because a correction can be posted, but highly on propagation and temporal decay. A database flag may score low on all four. A payment may have a moderate restoration gap, high external dependence and a shrinking recall window.
The mechanism: option decay
Irreversibility rises because viable recovery paths disappear after commit. Copies spread. Other agents act. Legal or contractual states change. Time windows close. Human expectations update. This is why review must migrate earlier. The less complete the recovery envelope, the more evidence and authority must be assembled before the pivot.
Here, the four r values are the ordinal recovery properties above. The coupling uplift is one class when at least two properties are already high. This rule deliberately uses the dominant dimension rather than an average. Averaging can hide a fatal property. A perfectly reversible internal record does not make a widely propagated disclosure low risk.
Worked example 2: a small routing calculation
Consider an email to a regulator containing a draft explanation. Score restoration gap 3, propagation 3, temporal decay 4 and external dependence 3. The dominant value is 4. Because several dimensions are high, the compiler routes the action to the highest class. By contrast, updating an internal note might score 1, 0, 1 and 0, routing it to a guarded reversible mode.
The numbers do not prove harm. They choose protocol obligations. The first action needs final-content review, named authority, a frozen evidence snapshot and no autonomous commit. The second can use optimistic version checks, idempotency and rollback.
Transaction modes on the slope
The central design decision is not whether an agent may “use tools”. It is which transaction semantics apply to each typed action. Five modes cover most operational cases. They are not maturity levels. A well-designed system may use all five on the same day.
- Retry-safe mutation. Use a stable idempotency key, request fingerprint, bounded retries and authoritative readback. Appropriate when repetition is the main failure risk and the effect is cheap to restore.
- Guarded reversible commit. Add version preconditions, a rollback window, immutable history and verification of the post-state. Appropriate when controlled state can be restored before substantial propagation.
- Compensatable saga. Decompose the workflow into local transactions, record a receipt for each step, define compensating actions and name the pivot after which remaining work must complete. Appropriate when atomic rollback is unavailable but selected consequences can be neutralised.57
- Escrowed pivot. Validate, reserve and prepare first. Require explicit approval against a frozen evidence snapshot. Commit only after resources, authority and recovery plans are ready. Appropriate when the pivot is difficult to reverse but can be delayed safely.
- One-way commit. Do not allow autonomous release. Require independent verification, named accountable authority, simulation or dry-run evidence where possible, and a containment plan. Appropriate when the act changes rights, publishes sensitive material, produces physical effects or otherwise outruns meaningful compensation.
Idempotency appears in every mode because timeouts and retries remain possible. What changes is what idempotency can accomplish. At T1 it may be the principal safeguard. At T5 it is merely hygiene. Sending the same irreversible instruction only once is better than sending it twice, but it does not make the instruction correct.
The pivot matters more than the workflow label
Saga implementations often distinguish compensable steps, a pivot transaction and retryable steps after the pivot. Once the pivot succeeds, the system cannot simply reverse the earlier sequence; subsequent idempotent work must bring it to a consistent final state.7 This is a stronger design idea than “use a saga”. It asks where the option to abort disappears.
Place the pivot as late as possible, but not later than reality permits. Validate beneficiary details before payment submission. Reserve stock before promising delivery. Generate a public statement before the approval meeting, not during it. Freeze the evidence used for approval so the approved object cannot silently change before commit.
A realistic configured-system example
Return to the synthetic supplier payment. The proposal originates in a probabilistic model, but no model output is itself an action. A deterministic action gateway turns the proposal into a typed contract. It validates the supplier identity, invoice identifier, amount, currency, payment date, authority grant and current account state. It then reserves the amount and produces a decision receipt for a human approver.
The approver sees the exact beneficiary, amount, evidence snapshot, recovery class and expiry. Approval authorises only that immutable contract. The gateway submits the transfer with a stable idempotency key. If the connection times out, it queries the bank using the original intent identifier or authoritative transaction reference before deciding whether another submission is permitted. Success is not declared until readback returns the expected effect or a trusted effect receipt arrives.
Worked example 3: compensation after the pivot
If readback confirms the transfer, the system cannot label a later return payment as rollback. It opens a new case: request return, notify treasury, track fees and reconcile the supplier’s response. Each step has its own identifier and receipt. The original transfer remains part of the evidence ledger.
If readback confirms that the request never committed, the gateway may retry using the original intent. If the status remains unknowable, it escalates instead of manufacturing certainty. This is slower than a blind retry, but the delay is placed exactly where the causal ambiguity exists.
Review should change position, rather than only intensity
Teams often respond to risk by adding another approval box. The gradient suggests a more precise shift. Low-irreversibility actions can be sampled after execution because rollback remains available. Medium actions need policy checks and readback around commit. High actions need review of the exact contract before the pivot. The highest class needs independent verification and named authority, with no autonomous release.
This also changes what a reviewer sees. “Approve payment?” is not decision-sufficient. The review object should contain the principal, purpose, beneficiary, amount, evidence snapshot, policy result, recovery class, pivot, expiry and expected post-state. Approval of a natural-language summary should not authorise a mutable payload.
stateDiagram-v2 [*] --> Claim state "Thought experiment 1, the<br/>silent wire" as Claim state "Four clocks, not one" as Test state "“Exactly once” belongs to the<br/>effect, not the message" as Revision Claim --> Test: expose mechanism Test --> Decision: evidence survives Test --> Revision: rival survives Revision --> Claim: narrow or rebuild Decision --> [*]
Compile the action before the model can call it
A probabilistic model can propose a beneficiary, amount, message or configuration change. It should not decide its own transaction mode, invent its own authority or declare its own success. Those are deterministic control functions.
The smallest useful implementation is an action gateway between model proposals and effectful tools. The gateway accepts only typed contracts. It verifies identity, authority, preconditions and recovery obligations; then it routes the action to the required mode.
The typed action contract
The contract below is intentionally stricter than a generic tool-call schema. It records not only inputs but the conditions under which the effect is allowed, how duplicate intent is recognised, where the pivot lies and what counts as verified completion.
type Level = 0 | 1 | 2 | 3 | 4;
type TransactionMode =
| "T1_RETRY_SAFE"
| "T2_REVERSIBLE"
| "T3_COMPENSATABLE_SAGA"
| "T4_ESCROWED_PIVOT"
| "T5_ONE_WAY_COMMIT";
type ActionState =
| "PROPOSED" | "VALIDATED" | "PREPARED" | "AUTHORISED"
| "SUBMITTED" | "UNCERTAIN" | "COMMITTED" | "VERIFIED"
| "COMPENSATING" | "COMPENSATED" | "CONTAINED" | "REJECTED";
interface RecoveryVector {
restorationGap: Level;
propagationReach: Level;
temporalDecay: Level;
externalDependence: Level;
}
interface AuthorityGrant {
principalId: string;
capability: string;
purpose: string;
notBefore: string;
expiresAt: string;
maxValue?: number;
currency?: string;
}
interface IdempotencyContract {
intentId: string;
key: string;
requestFingerprint: string;
scope: string;
expiresAt: string;
}
interface ActionContract<Payload> {
actionType: string;
payload: Payload;
targetSystem: string;
expectedStateVersion?: string;
authority: AuthorityGrant;
idempotency: IdempotencyContract;
recovery: {
vector: RecoveryVector;
mode: TransactionMode;
rollbackWindowSeconds?: number;
compensationPlanId?: string;
pivotStep?: string;
};
review: {
level: 0 | 1 | 2 | 3 | 4 | 5;
evidenceSnapshotHash: string;
requiredApproverRoles: string[];
};
verification: {
readbackQuery: string;
expectedPostcondition: string;
effectReceiptRequired: true;
};
}
function compileMode(v: RecoveryVector): TransactionMode {
const values = Object.values(v);
const dominant = Math.max(...values);
const coupled = values.filter(x => x >= 3).length >= 2;
const recoveryClass = Math.min(5, dominant + (coupled ? 1 : 0));
if (recoveryClass <= 1) return "T1_RETRY_SAFE";
if (recoveryClass === 2) return "T2_REVERSIBLE";
if (recoveryClass === 3) return "T3_COMPENSATABLE_SAGA";
if (recoveryClass === 4) return "T4_ESCROWED_PIVOT";
return "T5_ONE_WAY_COMMIT";
}
// Invariants enforced by the action gateway:
// 1. Same idempotency key + fingerprint cannot create another intended effect.
// 2. A changed fingerprint under the same intent ID is rejected.
// 3. No execution occurs outside authority scope, time or value bounds.
// 4. UNCERTAIN is resolved by authoritative readback, never by assumption.
// 5. T3 requires a resumable compensation plan and named pivot.
// 6. T4 and T5 cannot commit on model authority alone.
// 7. VERIFIED requires an effect receipt or authoritative post-state readback.
The schema exposes logic that prose usually hides: uncertainty is a state, authority is bounded, recovery is typed and successful completion requires evidence from the target system.
Failure injection before release
The contract is useful only if the implementation survives the failure states it names. A minimal test harness should inject four cases:
| Injected fault | Required observable behaviour | Prohibited inference |
|---|---|---|
| Timeout before remote commit | Readback finds no effect; retry reuses the original intent and fingerprint. | “Timeout means the target rejected it.” |
| Timeout after commit, before acknowledgement | Readback finds the original effect; retry returns its receipt without another mutation. | “No reply means retry with a fresh key.” |
| Duplicate message after a worker restart | Deduplication returns the prior result; version and amount remain unchanged. | “At-least-once delivery implies at-least-once effect.” |
| Compensation fails halfway | Progress is durable; the workflow resumes or escalates with a complete case record. | “Starting compensation means the system is restored.” |
Interactive irreversibility compiler
The instrument below converts a recovery profile into a proposed transaction mode and review gate. It uses synthetic ordinal inputs. The output is a design prompt, not a compliance decision or actuarial risk score.
| Consequence ↓ / Recovery class → | 1 Retry-safe | 2 Reversible | 3 Saga | 4 Escrowed | 5 One-way |
|---|---|---|---|---|---|
| 1 Minimal | Auto + log | Policy check | Named owner | Pre-commit review | Named authority |
| 2 Limited | Auto + sample | Policy check | Named review | Pre-commit review | Dual control |
| 3 Material | Policy gate | Named review | Named review | Dual control | Independent verify |
| 4 Severe | Named review | Named review | Dual control | Independent verify | No autonomous commit |
| 5 Critical | Dual control | Dual control | Independent verify | Named authority | One-way governance |
Named reviewer before the pivot.
What the instrument establishes
A positive result means the proposed action contract contains the minimum fields and controls for the routed mode. It permits implementation testing, not execution in production. A negative result means the action lacks a credible recovery path, authority gate or verification method. The correct response may be to redesign the workflow, narrow the capability or prohibit the action.
The tool cannot establish that an action is ethically justified, legally permitted, free of hidden side effects or safe in every environment. It also cannot infer recovery values from prose reliably. Human domain judgement remains necessary, especially for harms that do not appear in system state.
Optional depth: how to run the smallest useful pilot
Choose three actions that already have distinct recovery properties: a reversible record update, a compensatable multi-step workflow and a one-way communication. Implement the same action-contract fields and state machine for each. Inject the four failures in the table above. Measure duplicate intended effects, unresolved uncertain states, time to authoritative readback, compensation completion and reviewer decision time.
Do not begin with a live high-impact process. Use a synthetic target or operational twin. The pilot succeeds when every execution can be reconstructed from intent through authority, effect and recovery without relying on model narration.
Where the gradient can mislead
The framework’s strongest boundary is that recoverability is not identical to acceptability. A system may technically reverse a discriminatory eligibility decision while the person still loses time, dignity or opportunity. A high-consequence action can require strict oversight even when database state is easy to restore. This is why consequence remains a separate axis.
The opposite failure is over-gating. A slow approval path can itself create harm during fraud containment, safety response or service restoration. The answer is not to bypass the gradient. It is to design pre-authorised emergency contracts with narrow scope, short expiry, deterministic triggers and mandatory post-event review.
Ordinal scores can also create false precision. Two reviewers may disagree about propagation or temporal decay. That disagreement is useful when it exposes a hidden assumption, but the number should never become a claim that “3.7 is safe”. Use the instrument to route design obligations, then test the actual recovery mechanism.
Boundary condition: the action type can defeat the generic score
Some domains already have stronger transaction semantics, legal controls or safety cases than this framework. Do not replace them with a five-mode label. Map the action contract into the domain’s existing control system and preserve the stricter requirement.
Worked example 4: a reversible state with irreversible human impact
An automated scheduler wrongly cancels a medical appointment, then restores it five minutes later. The database is back to its prior state. Yet the patient may have received a cancellation message, rearranged transport or lost trust. A purely technical assessment would classify the action as reversible. The wider recovery envelope shows propagation to a person and rapid temporal sensitivity.
The correction is not to declare every scheduling action one-way. It is to separate tentative changes from released notifications, introduce a brief confirmation window, and make the notification itself a higher transaction class than the internal edit.
NIST’s AI RMF treats risk management as continuous across the lifecycle and asks organisations to assign responsibilities, manage impacts and prepare mechanisms to disengage or deactivate systems.810 Its Generative AI Profile also notes that different systems and risks may require different levels of human oversight, tracking and management review.9 The gradient supplies one engineering answer to that general requirement: vary the control location and transaction semantics according to the action’s recovery envelope.
sequenceDiagram participant Q as Question participant M as Mechanism participant E as Evidence participant D as Decision Q->>M: The payment that both happened and did not M->>E: Thought experiment 1, the silent wire E-->>M: compare rival explanations E->>D: Ask for proof earlier as undo becomes harder D-->>Q: revise scope or act
Ask for proof earlier as undo becomes harder
Stop deciding whether an AI system may “take actions” in the abstract. That category is too coarse. Updating a draft note, issuing a refund, releasing a payment, publishing an allegation and moving a physical device are not the same permission with different risk scores. They require different transaction semantics.
The decision to make before connecting a tool is this: what recovery envelope does each typed action have, and which mode follows from it? Once that is explicit, several design choices become clearer.
- Use stable intent identifiers and idempotent handling wherever communication can fail.
- Represent uncertain outcomes explicitly and close them with authoritative readback.
- Call something rollback only when controlled state can truly be restored.
- Call something compensation only when a durable, resumable balancing path exists.
- Move review before the pivot as propagation, time decay and external dependence rise.
- Require an immutable decision receipt before commit and an effect receipt after it.
This changes the practical unit of governance. The unit is not the model, the agent or even the tool. It is the typed action contract at a particular recovery class. A single agent can be highly autonomous for T1 actions, bounded for T2 and T3, and unable to commit T4 or T5 actions without named authority.
The purpose is not to eliminate failure. It is to prevent uncertainty from becoming duplicate effect, prevent compensation from masquerading as erasure, and prevent a persuasive proposal from acquiring authority by crossing an untyped interface. As the world becomes harder to undo, the system must know more, prove more and ask earlier.
Glossary
- Effect receipt
- Evidence from an authoritative target that states what effect committed, under which identifier and with which observed post-state.
- Idempotency
- The property that repeating the same intended request does not create an additional intended effect.
- Pivot
- The point after which the workflow can no longer abort through ordinary compensation and must complete or contain consequences.
- Recovery envelope
- The set of acceptable states still reachable after an error within available time, authority and resources.
- Rollback
- Restoration of controlled state to a prior valid version within a transaction or protected recovery boundary.
- Compensation
- A new action that neutralises selected consequences of an earlier action without erasing its history.
- Uncertain
- An execution state in which the caller lacks authoritative knowledge of whether the target effect committed.
References
- Fielding, R., Nottingham, M. and Reschke, J. (2022). RFC 9110: HTTP Semantics, section 9.2.2, Idempotent Methods. RFC Editor.
- Featonby, M. (2020). Making retries safe with idempotent APIs. Amazon Builders’ Library.
- Gray, J. (1981). The transaction concept: virtues and limitations. Proceedings of the 7th International Conference on Very Large Data Bases.
- Härder, T. and Reuter, A. (1983). Principles of transaction-oriented database recovery. ACM Computing Surveys, 15(4), 287–317.
- Garcia-Molina, H. and Salem, K. (1987). Sagas. Proceedings of ACM SIGMOD, 249–259.
- Microsoft Azure Architecture Center (2026). Compensating Transaction pattern.
- Microsoft Azure Architecture Center (2026 access). Saga distributed transactions pattern.
- National Institute of Standards and Technology (2023). Artificial Intelligence Risk Management Framework 1.0: Core.
- Autio, C. et al. (2024). Artificial Intelligence Risk Management Framework: Generative Artificial Intelligence Profile. NIST AI 600-1.
- National Institute of Standards and Technology (2026 access). AI RMF Playbook: Manage.