As discussed in the previous article, the CDM Event Model is built around state transitions: a TradeState, an Instruction carrying primitive changes, and a resulting after TradeState. Nine primitives compose into business events. A partial novation, for example, is three primitives in one BusinessEvent producing two after-states.
This article starts with an end-to-end example – one trade, five events – then derives three concepts from it: lineage, workflow, and the distinction between the two most commonly confused primitives.
An End-to-End Lifecycle
A 5Y USD IRS — USD 100M, Party A pays fixed 3.50%, Party B pays 3M SOFR, quarterly resets and payments. Five events across the first seven months, with no gaps.

Each column adds to exactly one part of the state. The first Reset adds to resetHistory. The second Reset adds to resetHistory again. The Transfer adds to transferHistory — it does not touch resetHistory; the two entries there were added by the two Reset events. The PartialTermination changes the trade itself. Nothing overwrites. Every entry in every history was put there by a visible event.
15 Mar 2026 — Execution. The trade is born. No before — execution is the only primitive that creates a trade from nothing. Both histories are empty.
{ "BusinessEvent": { "eventQualifier": "Execution", "eventDate": "2026-03-15", "instruction": [ { "primitiveInstruction": { "execution": {} } } ], "after": [ { "trade": { "... IRS, notional 100M, A↔B ..." }, "state": {}, "resetHistory": [], "transferHistory": [] } ] }}
28 Jun 2026 — Reset. SOFR fixes at 5.12%. The before points to the Execution TradeState. The after TradeState is identical except resetHistory now has one entry. The product was not modified.
{ "BusinessEvent": { "eventQualifier": "Reset", "eventDate": "2026-06-28", "instruction": [ { "primitiveInstruction": { "reset": { "resetValue": 0.0512 } }, "before": { "reference": "TS_1" } } ], "after": [ { "trade": { "... IRS, notional 100M, A↔B ..." }, "state": {}, "resetHistory": [ { "resetValue": 0.0512, "resetDate": "2026-06-28" } ], "transferHistory": [] } ] }}
28 Sep 2026 — Reset. The second quarterly fixing. Same primitive, same pattern, different value. The before points to the June Reset TradeState. The after TradeState is identical except resetHistory now has two entries. Neither touches the product.
{ "BusinessEvent": { "eventQualifier": "Reset", "eventDate": "2026-09-28", "instruction": [ { "primitiveInstruction": { "reset": { "resetValue": 0.0485 } }, "before": { "reference": "TS_2" } } ], "after": [ { "trade": { "... IRS, notional 100M, A↔B ..." }, "state": {}, "resetHistory": [ { "resetValue": 0.0512, "date": "2026-06-28" }, { "resetValue": 0.0485, "date": "2026-09-28" } ], "transferHistory": [] } ] }}
02 Oct 2026 — Transfer. The first floating payment settles (Sep quarter end, +2BD). The before points to the Sep Reset TradeState. The after TradeState inherits both entries in resetHistory unchanged. The Transfer primitive only adds to transferHistory.
{ "BusinessEvent": { "eventQualifier": "Settlement", "eventDate": "2026-10-02", "instruction": [ { "primitiveInstruction": { "transfer": { "payerReceiver": { "payer": "B", "receiver": "A" }, "quantity": 2480000 } }, "before": { "reference": "TS_3" } } ], "after": [ { "trade": { "... IRS, notional 100M, A↔B ..." }, "state": {}, "resetHistory": [ { "resetValue": 0.0512 }, { "resetValue": 0.0485 } ], "transferHistory": [ { "transferStatus": "Settled", "amount": 2480000 } ] } ] }}
15 Oct 2026 — Partial Termination. Notional is reduced from 100M to 80M. This event changes the trade itself. Both histories persist unchanged from the previous state.
{ "BusinessEvent": { "eventQualifier": "PartialTermination", "eventDate": "2026-10-15", "instruction": [ { "primitiveInstruction": { "quantityChange": { "newQuantity": 80000000 } }, "before": { "reference": "TS_4" } } ], "after": [ { "trade": { "... IRS, notional 80M, A↔B ..." }, "state": {}, "resetHistory": [ { "resetValue": 0.0512 }, { "resetValue": 0.0485 } ], "transferHistory": [ { "transferStatus": "Settled", "amount": 2480000 } ] } ] }}
Three things are visible in this example. First, how the states connect — the before on each Instruction and the after on each BusinessEvent create a walkable chain. Second, that not all primitives change the same thing — reset adds to resetHistory, transfer adds to transferHistory, quantityChange changes the trade itself. Third, that nothing is overwritten — each event adds, the previous state is preserved via the before reference. The rest of this article walks through each.
Lineage — How Did the Current State Come to Exist?
As the diagram shown above, the before reference on Instruction is a pointer, and the after on BusinessEvent is the full new TradeState, embedded inline. Together they create a bidirectional trace.
Forward: from execution through each event to the current state. Backward: from any state through its before-reference to the previous state. An AI agent walks this chain in either direction.
For AI-native data, this is what makes a state explainable. Why is the notional USD 80M? Because the TradeState inside the PartialTermination BusinessEvent carries a quantity of 80M. The Instruction’s before points to the previous state with 100M. The current state did not appear from nowhere.
Workflow — Was the Change Effective?
Lineage tells us what happened. Workflow tells us whether it was effective. Not every instruction becomes an event. Some are proposed and rejected. Some are proposed and still awaiting acceptance. Some are accepted and produce after TradeStates.
WorkflowStep wraps each event in an operational state machine:
type WorkflowStep: businessEvent BusinessEvent (0..1) proposedEvent EventInstruction (0..1) rejected boolean (0..1) previousWorkflowStep WorkflowStep (0..1) timestamp EventTimestamp (1..*) eventIdentifier Identifier (1..*) action ActionEnum (0..1)
A step is in one of three states: Proposed (proposedEvent populated, no businessEvent — the change has not occurred), Accepted (businessEvent populated — the change is effective), or Rejected (rejected = true — dead).
A proposed termination is not a termination. If event and workflow are mixed, an AI agent might say “This trade was terminated on 15 March” when the termination was proposed on 15 March but never accepted. A businessEvent populated means the change happened. Only proposedEvent populated means it has not.
Reset Is Not Transfer
The end-to-end example shows two events that look similar at a glance — both add entries to a history on TradeState — but are fundamentally different.
In the F-PAL framework, Stage 3 (Value Determination) produces a calculated amount from observed rates. Stage 4 (Settlement / Realisation) turns that amount into a cashflow. The CDM event model maps these to two different primitives:
| F-PAL Stage | Primitive | What it records | Where it lives |
|---|---|---|---|
| Value Determination | Reset | An observed rate, price, or index value | TradeState.resetHistory |
| Settlement / Realisation | Transfer | An asset movement between parties | TradeState.transferHistory |
A reset does not move money. A transfer does. A reset updates a value used in a calculation. A transfer discharges an obligation. Neither modifies the product definition.
Across Asset Classes
| Product | Reset | Transfer |
|---|---|---|
| IRS | ✓ (rate observation) | ✓ (cash settlement) |
| Equity swap | ✓ (closing price) | ✓ (cash payment) |
| CDS | ✓ (credit event, recovery) | ✓ (protection payment) |
| Commodity swap | ✓ (average price) | ✓ (cash or physical) |
| FX forward | — (fixed price) | ✓ (currency delivery) |
| Repo | — (fixed price) | ✓ (securities delivery × 2) |
If reset and transfer are collapsed into one “settlement” event, the model cannot answer: has the rate been fixed but the payment not yet made? (reset exists, transfer does not). Is this cashflow based on an observed rate or a projected rate? (reset present = known). Has a credit event been determined but settlement not yet completed?
Conclusion
| Layer | Type | Question |
|---|---|---|
| Event | PrimitiveInstruction → BusinessEvent | What changed? |
| Lineage | Instruction.before → BusinessEvent.after → WorkflowStep.previousWorkflowStep | How did we get here? |
| Workflow | WorkflowStep (proposed / accepted / rejected) | Was the change effective? |
The end-to-end example shows all three layers in action. Four events, each with lineage to the previous, each wrapped in a workflow step. Two kinds of change — reset and transfer — that are different primitives, different F-PAL stages, different TradeState fields, and should never be confused.