Record the M3.13g delivery and the next slice - #224
Conversation
M3.13g completed the structural stack: every layer between a signed version-seven transaction and a consensus engine now exists, and the handoff says so rather than still naming the adapter as the missing piece. **The delivery note records the finding rather than the code.** The slice's one real design question — what an adapter does when a consensus engine replays a block the application has already committed — was answered by reading CometBFT v0.39.4 rather than by choosing: it replays exactly that case against a mock application built from its own saved response, and says in the source that it will not call Commit twice on the real app. The handoff keeps why a reconciliation would have been worse than useless, so a later session does not build one. **The next action is now the fixture rather than the adapter**, and its shape is written down before the slice starts. The version-one integration test builds its expectations from a Python model that constructs signed transfers; version seven has no such builder, because only the C++ trace constructs its transactions. Emitting the recorded blocks' raw inputs is the obvious step and is not sufficient on its own: those blocks hold two and four transactions each, a root commits to the whole block, and broadcasting through a mempool does not put four transactions into one block in a chosen order. The likely answer — a scenario recorded for the run, one transaction per block, emitted through the verifier's own `--emit` — is stated with the alternative and the reason it loses. Two durable notes are added in the same shape as the existing ones: what the Go adapter looks like now, including the two things not to "simplify", and the scratch-module check that type-checks and runs the whole `internal/localapp` package locally in under a second while `bridge` and `nodeconfig` can only be verified on the hosted matrix. The four-validator devnet's version-seven dependency is recorded against requirement 13 rather than left to be rediscovered: its genesis and the `-protocol-version` its supervisor passes each bridge have to move in one slice, because a genesis that says one thing while the bridges say another fails at `InitChain`. The duplicated uptime-schedule paragraph in the gap section is folded into one. Both said the same thing about the same `nullptr`.
The next-action section said the end-to-end run needs the recorded blocks' raw inputs emitted into a vector file. That is true and it is not the obstacle, and building on it would have produced a fixture no chain can accept. **Every recorded version-seven transaction is signed with a stand-in.** `simulation/economy_transition_v7/trace.py` says so outright — no signature is computed anywhere, a stand-in is an eight-octet counter padded to 64 octets, recorded in an oracle that verifies by exact-match lookup — and `Signatures` in `tests/kernel/economy_v7_execution_fixture.hpp` issues byte-identical tokens so the C++ trace reproduces the model's exact transaction bytes. That is deliberate and right: the model implements no cryptography and every message-binding claim in the contract stays testable. **But `protocol-application-v7` opens its store through `open_sqlite_ledger_v7`, whose verifier defaults to `protocol::v7::ed25519_verifier()`.** It would refuse every recorded input as `invalid_signature`. So the next slice is a fixture slice: a version-seven fixture that signs for real, which is exactly what version one has in `tests/differential/cases.py` and `pinned_sodium` and what version seven has never needed until a real engine had to accept its bytes. The Python model turns out to be already parameterized for it — `execute_block` takes the oracle as an argument and only ever calls `oracle.verify(public_key, message, signature)`, so a libsodium-backed class is a drop-in and nothing in the model changes. That is recorded with the rest, along with why one transaction per block is a requirement rather than a simplification: a root commits to the whole block, and broadcasting through a mempool does not put four transactions into one block in a chosen order. ADR 0061's owed note is amended in place with the same finding, marked as established after the ADR was first written, because a reader who acted on its first wording would have emitted the octets and discovered the signatures afterwards.
A correction pushed before merge, and it is the reason this PR is worth readingThe first commit recorded the next slice as "emit the recorded blocks' raw inputs Every recorded version-seven transaction is signed with a stand-in. But a real node verifies real signatures. So M3.13h is a fixture slice, not a plumbing one: a version-seven fixture that ADR 0061's owed note is amended in place with the same finding, marked as Still Markdown only, so the focused metadata path remains the required |
VerificationRun 33502535967 on head Scope classified
Merging after the |
Pure Markdown.
docs/project/current-state.mdonly, so the focused metadatapath is the required verification.
What it records
M3.13g completed the structural stack. Every layer between a signed
version-seven transaction and a consensus engine now exists, and the handoff no
longer names the adapter as the missing piece — the phase section, the "What
works now" list, and the gap section are updated together so they agree.
The delivery note records the finding rather than the code. The slice's one
real design question was answered by reading CometBFT v0.39.4 rather than by
choosing: it replays an already-committed height against a mock application
built from its own saved response, saying in the source that it will not call
Committwice for one block on the real app. The note keeps why inventing areconciliation would have been worse than useless, so a later session does not
build one.
The next action is the fixture rather than the adapter, and its shape is
written down before the slice starts:
constructs signed transfers; version seven has no such builder, because only
the C++ trace constructs its transactions;
four transactions each, a root commits to the whole block, and broadcasting
through a mempool does not put four transactions into one block in a chosen
order;
block through the verifier's own
--emit, is stated with the alternative andthe reason it loses.
Also recorded
like now, including the two things not to "simplify", and the scratch-module
check that type-checks and runs the whole
internal/localapppackage locallyin under a second while
bridgeandnodeconfigcan only be verified on thehosted matrix.
its genesis and the
-protocol-versionits supervisor passes each bridge haveto move in one slice, because a genesis that says one thing while the bridges
say another fails at
InitChain.one delegated — and the note that one of them was settled by reading the
engine rather than by choosing.
Both said the same thing about the same
nullptr.Verification
git diff --check main HEADclean. No line in the diff exceeds 81 columns,which is the file's existing width.