The rule
A report cannot exist while one lamport has no destination.
Not a policy. The CLOSED arm of a basket requires a seal, the seal carries a symbol this codebase declares and never exports, and the only function that returns one checks the arithmetic first.
§1 Four destinations, four different proofs
Money that reached people left the wallet, so there is a signature. Naming it is the whole difference between a distribution and a promise — and the figure that has no signature behind it is, without exception, a database row.
A cost is money that left. If it left, it left in something anybody can open. A cost line with no transaction is indistinguishable from a subtraction somebody typed.
It has not moved, so there is no signature to give — which is exactly why this arm demands something else instead. Without a date, “reserved” is a nicer word for missing, and it can stay that way for years.
You may have a remainder. Rounding is real, sweeps run late, a swap leaves dust. What you may not do is name it a remainder and walk away — which is the precise shape of the 207.74 SOL that started this project.
§2 The seal
declare const CLOSED: unique symbol; // declared, never exported
export type Closed = {
readonly [CLOSED]: true;
readonly received: bigint;
readonly assigned: bigint;
};
type Basket =
| { state: "CLOSED"; received; allocations; closed: Closed }
| ...An object literal cannot supply a key it cannot write down. Nothing outside lib/sportula.ts can name that symbol, so nothing outside can build a seal — and close() only returns one when the allocations sum exactly to what arrived, compared as bigint. One lamport out is one lamport out.
It also refuses negative allocations before it adds anything up. Without that, two wrong numbers cancel and the books balance without ever touching the type system — the one way this rule could be satisfied dishonestly.
§3 Three states, and the middle one is not an error
closed — 1 SOL, all of it assigned
unbalanced — the residue was never named
UNBALANCED is displayable on purpose. A system that could only represent balanced books would not stop money going unaccounted for — it would only stop anyone seeing it, and the same figure would move somewhere quieter. What is removed here is not the imbalance. It is the ability not to mention one.