Skip to content

Execute economy-transition-v6 and record its transition trace - #173

Merged
kaikisegfault merged 6 commits into
mainfrom
feat/153-economy-transition-v6-execution
Aug 16, 2026
Merged

Execute economy-transition-v6 and record its transition trace#173
kaikisegfault merged 6 commits into
mainfrom
feat/153-economy-transition-v6-execution

Conversation

@kaikisegfault

@kaikisegfault kaikisegfault commented Aug 16, 2026

Copy link
Copy Markdown
Owner

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.py and value_transitions.py — the fourteen kinds in their specified rejection orders. The settlement is imported from simulation/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, whose expected.py imports nothing from simulation/.
  • 51 tests across two modules, both registered in CMakeLists.txt.
  • ADR 0045.

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.

  1. DEBIT_OVERFLOW belongs 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.
  2. An unrequested confirmation field is refused at execution with UNAUTHORIZED. The specification places the rule at admission, which cannot read the stored posture the predicate needs, and names MALFORMED_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.
  3. NOTHING_TO_MINT is 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.
  4. The cycle assignment is a prologue, and that is a decision about money. Under the accepted reading a founder's mint at the window boundary collects 114,860,000,000 atomic; under the other it succeeds, collects zero, and advances the mark anyway, forfeiting the cycle permanently. A referral in the same block is only deferred. Both readings are run against identical inputs and both figures are recorded.

Evidence

  • 512 vectors verified. Every value two sources can reach is derived twice — once by expected.py, once by a live run — and recorded only when both agree.
  • Three inherited constructions are checked against a third source before anything rests on them: the ordered transaction tree and the accepted version-one signed transfer against test-vectors/protocol-primitives-v1.txt, and the block header and block ID against test-vectors/ledger-transition-v1.txt.
  • The accepted 200-octet version-one transfer is admitted byte-for-byte on a chain stamped with the accepted chain ID, refused with RECIPIENT_NOT_REGISTERED, and then accepted with only the 32 recipient octets replaced. Byte identity preserved, execution identity not.
  • Six mutation probes fail closed: a re-versioned block header (104 failures), the assignment moved after the transactions (33), an unrequested confirmation no longer refused (10), the literal NOTHING_TO_MINT equality (36), a changed escrow domain label (116), and a fixture that loses its last consecutive block pair (20).
  • Two real defects were found during the slice. The tests caught admission codes being looked up in the result-code table — which the vectors could not, because the trace had no admission failure in it, so two are now in the fixture. And the sixth probe exists because this slice's own file held a vacuous claim: an all() over an empty set of consecutive block pairs.
  • Nothing accepted was edited. All five predecessor vector files verify at 238, 579, 441, 550, and 462.

Verification

Full hosted matrix required (tools/verification_scope.py classifies this full). Locally: 6 v6 test modules OK, all six transition verifiers pass at their recorded counts, tools/verify_metadata.py validates 207 internal links, and the registration guard passes.

…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
kaikisegfault force-pushed the feat/153-economy-transition-v6-execution branch from 089e9b4 to 593e28c Compare August 16, 2026 14:19
`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.
@kaikisegfault
kaikisegfault merged commit cc2e8fc into main Aug 16, 2026
6 checks passed
@kaikisegfault
kaikisegfault deleted the feat/153-economy-transition-v6-execution branch August 16, 2026 14:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

M3.10b: the version-six execution model and its recorded transition trace

1 participant