feat(dlv): surface the owner's economic-proof locator, which no trader could reach - #835
Merged
Merged
Conversation
…r could reach Step 4 requirement 6's one blocking gap, fixed on its own so the admission work that needs it is not also carrying this. The credit source a market settle must build is 0x0026 DlvReserveConsumption, whose facts are owner_economic_position and reserve_consumption_evidence_addr. The evidence itself is a ReserveConsumptionEvidenceV1 naming the exact V_n, the owner's authority evidence, and the address of the owner's EconomicProofArtifactV1. A settling TRADER could reach none of that. The route's own comment says why: the settler is usually a trader device holding no amm_vault_record, its whole knowledge of the vault having come from storage. The owner publishes the artifact at funded creation and keeps the locator in its own local record, so the owner has it and nobody else does. The locator IS on the wire. RoutingVaultAdvertisementV1 carries economic_proof_addr and economic_proof_position, with a comment explaining exactly why that is safe on an unsigned object: a reader resolves the position's root from the owner's own write-once register cell and re-derives every inclusion path against it, so a wrong address or position can only make the lookup FAIL, never succeed against a root the owner did not register. And compose_discovered_vault already fetches and decodes that advertisement. It simply never surfaced these two fields, so the information was present, verified-irrelevant and unreachable at the same time. Carried as Option<OwnerEconomicProofLocator> rather than two bare fields: - absence is EXPLICIT, so a caller cannot mistake "this path carried no advertisement" for "the owner published nothing". The owner's own composition path has no ad to read and correctly yields None. - both halves travel together because neither is usable alone: the address names the artifact, the position names the register cell whose root the inclusion paths are re-derived against. A malformed address is treated as absent rather than as a refusal. Composition is about the authenticated state, and this field authenticates nothing; failing a composition over a bad hint would let an unsigned advertisement deny a vault. No consumer yet, and that is deliberate rather than overlooked: the consumer is the admission wrapper, which is modelled on admitted_dlv_create_funded and lands next. The field is inert until then. dsm_sdk vault_state_composition 22/22 serially. make lint green; safety checks green.
cryptskii
added a commit
that referenced
this pull request
Sep 10, 2026
…admission (#837) Step 4 requirement 6's second half, and requirement 9. After a qualifying QuorumBind COMMIT the binding is authoritative, so the trader now advances its OWN chain to the successor the bundle names, with the economic admission attached. admitted_dlv_settle follows admitted_dlv_create_funded, with two differences that matter. The credit arm is 0x0026 DlvReserveConsumption: a trader's settle output is funded by consuming an owner vault reserve. It is NOT 0x0027, which is the owner-apply arm. build_write_set refuses the pairing outright, and the 5c-2 plan named the wrong one until it was corrected. The second is the gate requirement 6 asks for in as many words. `expected_successor` is the exact B.trader_successor the bundle was BOUND to, and the advance refuses unless it would commit precisely that. The check runs inside `build`, after the pure prepare and before anything is written, so a device that would diverge leaves nothing persisted, nothing credited, and the fence untouched. The evidence the credit source names is built from facts the trader already verified: the exact V_n, the owner's authority evidence re-encoded from what the presentation authenticated, and the owner's economic-proof address. A verifier REPLAYS the owner's ancestry rather than trusting this device. The locator came from #835; without it a trade is refused rather than admitted on an invented one, and the refusal says the trade is bound and needs reconciliation rather than pretending it failed. WHAT NOW MOVES, AND WHAT STILL DOES NOT. The trader's own balances move — exactly 1,000 in and 453 out in both tests, which is the constant-product output for that pool and fee — and its head advances. That is what accepting a successor means, and the credit is foreign-verifiable rather than a raw local one. The vault's reserves do not move, no receipt is published, the market fold stays PartialPendingRealization, no bundle-acceptance witness exists to construct, and THE FENCE IS NOT RELEASED. Requirement 9 is now asserted positively rather than by absence: the test reads the fence on the TRADER's own chain, keyed on the parent as it stood before this settle, and requires it to still be CommittedAwaitingAcceptance. Ordinary DSM advancement is not a certifying verdict, Ruling V3 gates release on one, and a market verdict cannot certify until 2c-D. The replay assertion changed direction, and the new one is the more important property. Re-submitting an accepted settle is now REFUSED, because the trader's chain has moved and the quorum finds the vault generation taken. The test asserts the refusal AND that the retry moved nothing further: a refusal that had already debited would be worse than an acceptance. Mutation control, restored from a byte copy and verified identical after: inverting the bound-successor comparison turns both named market tests red and reaches the "could not admit its own advance" refusal, which shows the gate executes on the happy path rather than being dead. An earlier attempt at that control replaced the comparand with a constant instead. It did not compile, because the parameter became unused and the crate denies warnings — which is its own small evidence that the value is genuinely consumed, but not a control. dsm_sdk: dlv_routes 37/37, vault_state_composition 22/22, settlement_bind 7/7, binding_occupancy 10/10 — all serial. dsm: dlv::market 15/15, conformance 12/12. make lint green; production safety checks green. Still owed in Step 4: requirement 10's remaining controls — publication below quorum leaving no fence and no bind, and a conflicting value for the same parent staying excluded after COMMIT.
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.
Step 4 requirement 6's one blocking gap, fixed on its own so the admission work that needs it is not also carrying this.
The gap
A market settle must build credit source
0x0026 DlvReserveConsumption, whose facts areowner_economic_positionandreserve_consumption_evidence_addr. That evidence names the exactV_n, the owner's authority evidence, and the address of the owner'sEconomicProofArtifactV1.A settling trader could reach none of it. The route's own comment says why: the settler is usually a trader device holding no
amm_vault_record, its whole knowledge of the vault having come from storage. The owner publishes the artifact at funded creation and keeps the locator locally — so the owner has it and nobody else does.It was already on the wire, and already fetched
RoutingVaultAdvertisementV1carrieseconomic_proof_addrandeconomic_proof_position, with a comment explaining precisely why that is safe on an unsigned object:And
compose_discovered_vaultalready fetches and decodes that advertisement. It simply never surfaced the two fields. The information was present, verified-irrelevant, and unreachable at the same time.Shape
Carried as
Option<OwnerEconomicProofLocator>rather than two bare fields:None.A malformed address is treated as absent, not as a refusal. Composition is about the authenticated state and this field authenticates nothing; failing a composition over a bad hint would let an unsigned advertisement deny a vault.
No consumer yet
Deliberate rather than overlooked. The consumer is the admission wrapper — modelled on the existing
admitted_dlv_create_funded, which does the same job for funded creation — and it lands next. The field is inert until then.Verification
dsm_sdkvault_state_composition22/22 serially.make lintgreen; production safety checks green.