Causal Ordering Between Account Events

By DX Research Group · · State and memory

Account state needs explicit dependencies when timestamps cannot order its changes.

An account event should become eligible for a state update when its required predecessors are present. Sorting every message by its wall-clock timestamp can violate that condition. We would preserve causal references for events whose meaning depends on another event, while allowing independent updates to remain unordered.

Our state snapshot method binds a decision to eligible facts. This note adds a dependency requirement for assembling those facts. The resulting event graph belongs beside the decision trace, where it can explain why a received message remained pending.

The fee that arrives first

Consider a hypothetical fill F for 2 asset units and a fee adjustment C that references F. The fee service sends C before the fill service delivers F. Local arrival order is C, F. A clock offset also gives C an earlier displayed timestamp. Neither ordering tells us that the portfolio reducer may apply the fill-dependent adjustment immediately.

We would stage C with a missing predecessor reference. Once F arrives, the reducer applies F and then C under the account's declared accounting semantics. If the adjustment is a fee debit of 3 cash units, the result should contain one fill and one debit. Repeated delivery of either message should leave the same economic state.

Lamport's paper on event ordering supplies the underlying distinction: causality defines a partial order, while a clock-based total ordering can extend it. A total order is useful for reproducibility, but arbitrary ordering between independent events carries no additional causal meaning.

Test the operation, then the scheduler

Two additive cash debits can commute. Starting with 100, applying debits of 2 and 3 in either order yields 95. A balance-reset message and a debit generally do not commute: resetting to 100 then subtracting 3 gives 97; subtracting 3 then resetting gives 100. The reducer needs a documented meaning for the reset, including the event boundary it already covers.

We would construct a small dependency graph before randomizing message delivery. Each permutation should either reach the expected state or report an unresolved dependency. A message claiming an impossible predecessor cycle should return a diagnostic rather than waiting indefinitely. An absent predecessor after the fixture's timeout should remain explicitly unresolved.

The measurement is dependency completeness at decision assembly, with recovery delay reported separately. Calling every delayed event a failure would penalize a correct staging policy. Calling every eventually applied event a success would conceal decisions that ran while essential account facts were still missing.

A useful trace excerpt shows the received message, the predecessor it required, the moment that predecessor became available, and the snapshot that first included both. It need only expose enough structure to verify the dependency. The proposed test concerns state construction, rather than forecast skill or investment performance. For a frontier agent using many tools, explicit dependency handling gives parallel work a precise joining rule: an answer can arrive early and still become usable later.

Sources

Related field notes