feat(positions): organization positions, settlement, and the wallet they are not - #23
Merged
Merged
Conversation
…t runs Phase 9A. The domain had all eight quantities since Phase 0, including both worked examples from the laws. What it did not have was any way to produce one from real data: two of the five inputs had nowhere to live, and nothing ever moved an entry out of the settlement window. Debts and receivables get their own tables, deliberately not columns on accounts. 19 keeps them outside the supply equation because "adding either to the equation would double-count the KRED that funds them", and a liability in a separate table cannot be summed into a balance by accident. Amendment A01 exists because the first model recorded debt as a negative balance. The constraints are in the database rather than in a convention. A receivable cannot settle beyond its own value, a debt cannot owe more than was financed, and a claimant cannot be their own obligor: Law XXXIV forbids the two-account version of that, this forbids the no-account version. Settlement is the mechanism Law VII rests on and it did not exist. The window arrives as an argument, never a default, because the published normal window and the risk-adjusted ones come from different places and one of those is deliberately not published. A window of zero throws: that is not a short window, it is the absence of one. The window is written twice, as an indexed SQL cutoff and as the domain's `due`. Mutation testing showed that breaking either alone changes nothing, so the comment claiming a division of labour was wrong and now says what is true. What the redundancy buys is a rule reachable without a database, plus a boundary test: an entry created exactly one window ago must settle, which is the only input that can tell `<=` on a cutoff from `>=` on a due time. Two sweeps racing settle each entry once, because the UPDATE still requires PENDING. Without that both claim the same rows and both report success. The policy package now reads settlement, accounting, receivables and debtTypes, with the laws pinned as literals rather than parsed as data. A policy file permitting negative balances, or letting an underwater position withdraw a single kredbit, fails to load instead of being obeyed. The snapshot is untouched and its checksum still matches. Also found by mutation: the negative-balance test matched on the word "negative", and `kredbits` refuses a negative value with a message containing the same word, so it passed with the check deleted. Two guards, one message, one of them untested.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 9, both halves. The private side is in
kreds-networkat312c526; nothing about how the Network computes a position is in this PR or in this repository.What was actually missing
The domain has had all eight quantities since Phase 0, with both worked examples from the laws pinned as tests. What it did not have was any way to produce a position from real data:
debtsandreceivableshad nowhere to live, and nothing ever moved an entry out of the settlement window.withdrawablewas permanently zero for every earner.Liabilities get their own tables
Not columns on
accounts. 19: Invariants keeps them outside the supply equation because "adding either to the equation would double-count the KRED that funds them", and a liability in a separate table cannot be summed into a balance by accident. Amendment A01 exists because the first model recorded debt as a negative balance.Constraints, not conventions:
settled_value <= gross_valueoutstanding <= principalclaimant_account_id <> obligor_account_idSettlement
The mechanism Law VII rests on, which did not exist. 11 on why the length was chosen:
The window is an argument, never a default: the published normal window and the risk-adjusted ones come from different places and one of those is deliberately not published. A window of zero throws.
Two sweeps racing settle each entry exactly once. Mutation-tested by removing the
PENDINGguard on the UPDATE.Protocol v3
OfficialPositionhad a flatbalanceand a flatwithdrawablewith no context attached. That is Law V's shortcut already taken, at the one place it matters most: the boundary Core actually reads. It now carries one global wallet and a list of organization standings, and there is no top-level balance, so Core cannot ask what somebody holds without saying in which context. Both repositories pin the shape independently with@ts-expect-error.netPositionis the only figure on this protocol that carries a sign. A balance never does.Policy
packages/policynow readssettlement,accounting,receivablesanddebtTypes, with the laws pinned as literals rather than parsed as data. A policy file permitting negative balances, or letting an underwater position withdraw a single kredbit, fails to load instead of being obeyed. The snapshot is untouched and its checksum still matches.Two things mutation testing found
The negative-balance test matched on the word "negative", and
kredbitsrefuses a negative with a message containing the same word, so it passed with the Law XXI check deleted. Two guards, one message, one of them untested.The settlement window is written twice, as SQL and as domain. Breaking either alone changed nothing, so the comment claiming a division of labour was wrong. It now says what is true, and there is a boundary test at exactly one window, which is the only input that can tell
<=on a cutoff from>=on a due time.