Where you are. Module 6 put money and assets on a shared ledger and stress-tested the result. Everything it built lived on one ledger. This module builds the markets those tokens need, and then closes a loop module 3 opened and could not finish.
Put two ledgers on the bench. On the first, tokenised dollars. On the second, a tokenised bond, issued by somebody else entirely, running under its own rules.
Alice wants to buy the bond with the dollars. Both assets are tokens. Both settle instantly on their own ledger. And there is no transaction in the world that can move both.
The idea in one paragraph
A ledger’s atomicity stops at its own edge. Inside one book, a posting either commits in full or does not happen, which is the property module 6 spent seventeen lessons exploiting. Between two books there is no such guarantee, because there is no shared thing to commit to: ledger A has never heard of ledger B and has no way to make its own posting conditional on one over there. That gap is the whole subject of this module’s last third, and it is worth setting up now, before eleven lessons of trading machinery, so that everything built in between is built on a bench where the problem is visible.
Wider than the screen; scroll it sideways.
What the exercise proves
The exercise builds both ledgers and then tries to post one transaction across them.
The attempt fails, and the failure is unremarkable: the cash ledger has never heard of an account called “bonds in custody”, so it refuses. There is no clever error, no partial state, no half-written posting. Nothing happened at all.
That is the correct behaviour and it is exactly the problem. A refusal is much better than a half-done trade, and it still leaves Alice unable to buy the bond.
What sovereign means here
The word doing the work is sovereign, and it is worth being precise about it because the whole module turns on it.
Two ledgers are sovereign with respect to each other when neither can be made to act by the other. Not slow to act, not expensive to act: unable. Ledger A cannot read ledger B’s state, cannot make its own posting conditional on B’s, and cannot be compelled by anything B does. Each is complete and correct on its own terms and simply has no aperture facing the other.
That is not an artefact of these being toy ledgers. It is the ordinary condition of separately operated systems, and module 3 met exactly the same wall between two banking systems in different countries. What is new here is not the problem; it is that both sides are now programmable, which turns out to admit a solution that correspondent banking never had.
Where the module goes
Eleven lessons of markets first: pools, quotes, venues that show you nothing, the price a liquidation reads, and margin. Those are built on one ledger at a time, because they can be.
Then the gap. Lesson 12 shows the popular fix, which copies the asset and creates something to steal. Lesson 13 shows the one that settles instead of copying. From there the module assembles those pieces into a rail, a collateral system and a treasury desk, and ends by measuring honestly what all of it changed.
Why this is set up first
It would be possible to build all the trading machinery and only then discover the gap. The module puts both ledgers on the bench in lesson one instead, for the same reason a test fixture is written before the code that has to satisfy it.
Every mechanism from here to lesson eleven is built on a single ledger, and each one is worth having on its own. But the module’s real destination is the trade that lesson one just failed to make, and knowing that changes how you read what comes in between. When lesson twelve reaches for a bridge, you will already know what problem it is trying to solve and be in a position to judge whether it solved it.
Check yourself
1. Why can a single transaction not span two ledgers?
Because a ledger’s atomicity is a property of one book. Ledger A commits its own postings in full or not at all, and it has no way to make that commitment conditional on something happening on a ledger it has never heard of. There is no shared thing for the two to commit to.
2. The exercise’s attempt fails. Why is that the right behaviour and still a problem?
Right, because a refusal leaves both ledgers exactly as they were, which is far better than a partially applied trade. A problem, because the trade the two parties wanted is still impossible, and refusing cleanly is not the same as settling.
3. What is the software analogy, and what does it suggest about the fix?
Two databases with no distributed transaction between them. It suggests the fix is not a way to make one transaction span both, but a protocol whose observable end states are only the two you wanted, with nothing in between reachable.
Do this
Stand up both ledgers and try to cross them.
python3 code/two_ledgers.py
The starter builds the cash ledger and the bond ledger and leaves you try_single_posting: attempt one posting touching accounts on both, catch what comes back, and return a string beginning with “REFUSED”. The assertions check that both ledgers balance independently and that the failed attempt moved nothing anywhere.
The completed version is in solutions/two_ledgers.py.
What you can now do. You can run two independent ledgers, state precisely why no transaction spans them, and name the property that stops at each ledger’s edge. The next lesson starts building markets on one of them.