Execute economy-transition-v6 and record its transition trace - #173
Merged
Conversation
…rived rules Building the first thing that runs an `economy-transition-v6` transition reached three places where the accepted contract admits two readings and one place where it is silent. ADR 0045 records each reading, the alternative, and why the alternative was rejected. The debit-overflow test belongs at envelope check 8, because the literal shared-envelope order leaves the balance comparison undefined on its own input and would make a frozen code unreachable that the specification does not list as unreachable. The rule that an unrequested confirmation field must be zero is placed at admission, which cannot read the stored posture the predicate needs, and names `MALFORMED_TRANSACTION`, which the result-code space does not contain; it is refused at execution with `UNAUTHORIZED`. And `NOTHING_TO_MINT` is the empty walk range rather than an equality, because the literal wording lets a freshly activated seat's mint lower its own accumulation mark by two windows. The fourth is worth more than the other three together: a cycle assignment due at a window boundary is written before that block's transactions. The specification's own sentence about the last assigned window at any height forces it, and the cost of the other reading is that a mint in the boundary block succeeds, collects nothing, and forfeits that cycle permanently. No rule in the accepted specification changes. It gains an evidence pointer to the execution model and a note that one of its rules is stated in a place that cannot evaluate it, which a later version should correct outright.
…ion trace The version-six package encoded the contract and ran none of it. This adds the half that executes: a ledger state, escrow resolution under both authorization schemes, the shared envelope checks, the fourteen transitions in their specified rejection orders, ordered block execution with the cycle-assignment prologue, and the recorded fixture the vectors are taken over. It comes before the C++ kernel for the reason M3.9b established: a codec never asks where a transaction gets its arguments, so two implementations agreed perfectly about a message neither could construct. The execution model is the first step that runs a transition. `test-vectors/economy-transition-v6-execution.txt` holds 499 normative vectors over six scenarios — registration as one atomic execution and a forfeiting collection thirty windows later; the millionth-and-first user, who registers successfully and holds nothing; recovery end to end, where a person with no signer assigns one with their identity alone and pays from the escrow that already held their value; the accepted version-one signed transfer admitted byte-for-byte and refused for its recipient, then accepted with only that field replaced; both directions of a posture change including a mixed one; and a block that writes a cycle assignment, mints against the record it just wrote, and commits a root. Every value two sources can reach is derived twice and recorded only when both agree, and `expected.py` imports nothing from `simulation/`. Three inherited constructions are checked against a third source first: the ordered transaction tree and the accepted signed transfer against `protocol-primitives-v1.txt`, and the 146-byte block header and block ID against `ledger-transition-v1.txt`. The settlement is imported from the version-three package rather than copied. Five mutation probes establish that the verifier fails closed: a re-versioned block header, the cycle assignment moved after the transactions, an unrequested confirmation no longer refused, the literal `NOTHING_TO_MINT` equality, and a changed escrow domain label. The tests caught one real defect during the slice — admission codes were being looked up in the result-code table, which are disjoint namespaces that share numbers. Nothing accepted was edited. All five predecessor vector files verify at their recorded counts of 238, 579, 441, 550, and 462.
…failure A referral balance is written by the assignment prologue, so one can only exist on a chain that has already assigned a window. The kind-5 mint asserted that rather than saying it: an `assert` is the wrong shape for a state no sequence of conforming transitions produces, because it reads as a type narrowing rather than as the invariant it is.
…next M3.10b made economy-transition-v6 execute. The handoff records what the slice found, which is the part that outlives it: four execution rules the accepted contract left to be derived, one real defect the tests caught that the vectors could not, and the five mutation probes that establish the verifier fails closed. The recorded next action becomes M3.10c, the C++20 kernel for version six, with the four derived rules named as what it has to reproduce and the observation that a codec alone can demonstrate none of them. One founder-reserved consequence is recorded and is not blocking: the millionth-and-first verified person registers successfully, holds nothing, and can do nothing until somebody already inside the ecosystem funds them. That follows from ADR 0042's bounded airdrop and the universal fee rather than from anything this slice decided, and it was raised to the owner at the close of the session.
kaikisegfault
force-pushed
the
feat/153-economy-transition-v6-execution
branch
from
August 16, 2026 14:19
089e9b4 to
593e28c
Compare
`ledger-transition-v1` requires that an internal invariant failure, a height error, or a resource-bound violation reject the whole proposed block and preserve the pre-block state, while ordinary transaction results never reject it. The block executor raised and left the ledger part-written, so the rule was prose rather than behaviour. It now snapshots the state before the height increment and restores it if the block is rejected, and a test offers a boundary block a window the state already holds and requires the height and the state root to be exactly what they were.
… vectors Every block in the boundary scenario was separated by a height jump, so the per-scenario claim that a block opens on its predecessor's committed root was an `all()` over an empty set — true forever and establishing nothing. That is the hazard `docs/engineering/verification.md`'s third rule names, in the file written by the person applying the rule. The scenario gains a real successor block at the very next height, which also shows that the window the boundary block assigned is not assigned a second time and that a referral already collected refuses again. The checker now fails rather than emitting a boolean over an empty set, and dropping the successor block is a sixth mutation probe that fires. The file grows from 499 to 512 vectors.
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.
Closes #153.
The version-six package encoded the contract and ran none of it. This adds the half that executes, and it comes before the C++ kernel for the reason M3.9b established: a codec never asks where a transaction gets its arguments, so two implementations agreed perfectly about a message neither could construct. The execution model is the first step that runs a transition.
What it adds
simulation/economy_transition_v6/ledger.py— a version-six state and its conservation and structural invariants, every one an equality.execution.py— admission, escrow resolution under both authorization schemes, and the shared envelope checks.transitions.pyandvalue_transitions.py— the fourteen kinds in their specified rejection orders. The settlement is imported fromsimulation/economy_transition_v3/, never copied.block.py— ordered block execution with the cycle-assignment prologue, the transaction root, the 146-byte header, the block ID, and block-level atomicity that restores the pre-block state on a rejection.trace.py— the recorded six-scenario fixture.test-vectors/economy-transition-v6-execution.txt— 512 normative vectors.tools/economy-transition-v6-execution-vectors/— the verifier, whoseexpected.pyimports nothing fromsimulation/.CMakeLists.txt.The four things it settles
Building it reached three places where the accepted contract admits two readings and one where it is silent. Each is consensus-visible; none is founder-reserved. ADR 0045 records each with its alternative.
DEBIT_OVERFLOWbelongs at envelope check 8. The literal shared-envelope order leaves the balance comparison undefined on its own input and would make a frozen code unreachable that the specification does not list as unreachable.UNAUTHORIZED. The specification places the rule at admission, which cannot read the stored posture the predicate needs, and namesMALFORMED_TRANSACTION, which the result-code space does not contain — admission codes and result codes are disjoint namespaces that share numbers. This is the one correction owed to a later contract version.NOTHING_TO_MINTis the empty walk range. The literal equality lets a freshly activated seat's mint lower its own accumulation mark by two windows, which destroys the exactness argument the accumulation cap rests on.Evidence
expected.py, once by a live run — and recorded only when both agree.test-vectors/protocol-primitives-v1.txt, and the block header and block ID againsttest-vectors/ledger-transition-v1.txt.RECIPIENT_NOT_REGISTERED, and then accepted with only the 32 recipient octets replaced. Byte identity preserved, execution identity not.NOTHING_TO_MINTequality (36), a changed escrow domain label (116), and a fixture that loses its last consecutive block pair (20).all()over an empty set of consecutive block pairs.Verification
Full hosted matrix required (
tools/verification_scope.pyclassifies thisfull). Locally: 6 v6 test modules OK, all six transition verifiers pass at their recorded counts,tools/verify_metadata.pyvalidates 207 internal links, and the registration guard passes.