sofi: R4, the Core read adapter, and the faucet becomes a release of the native ERA reserve - #939
Merged
cryptskii merged 2 commits intoSep 21, 2026
Conversation
…the native ERA reserve
Rebuild step R4 (spec §44) plus the owner's R4 addition (§44.3): the dead
SoFi-named counting goes, and the beta faucet's quorum-backed ticket register
is replaced by the native ERA reserve — one canonical lineage per network,
released leader first, replicated to every member in the background.
Core: `sofi::arith::resolve_objects` derives Final/LeaderHeld/Open/Unavailable
from raw reads over a recognition predicate; `read_economic_root_cell` runs on
it. `economic/native_reserve.rs`: R_0 = 80,000,000,000 ERA at generation 0,
`release_constructible` as the one transition (remaining' = remaining − amount,
no mint arm, no creator withdrawal), the release names its recipient directly
(`ReleaseSource::FaucetClaimant`; the emission lottery is a later arm), cells
K(reserve, R_n) with the leader over the committed set, `walk_lineage`. Credit
source 0x005D (0x0030 burned); `Operation::FaucetClaim { reserve_id,
generation }` at tag 31; the provenance arm re-runs the construction predicate
against the walked parent, then the recipient/AK, position + digest, set and
evidence bindings.
Finality vs replication (owner ruling): the leader plus two other holders is
final and the recipient is credited at once; the SDK carries every final
successor to every remaining member in the sync pass; an unavailable
non-leader never blocks a claim.
SDK: `sdk/native_reserve.rs` (memoised walk, leader-first write, `release_at`,
the carry), `faucet_claim_flow.rs` rewritten, client schema v15. Node: the
faucet-ticket route, table, `node.network_id`, write-once suite and
conformance suite deleted; the Postgres test floor moves to 10.
Formal, in tandem: `tla/DSM_NativeReserveRelease.tla` (13 invariants, 8
faults + 3 reachability configs, every one violating exactly its invariant),
`lean4/DSMNativeReserve.lean`; `DSM_EconRegisterObservation.tla` and the §10
quorum theorems deleted with `observe_cell` (runner 69 → 75, Lean 15 → 16).
Deleted: economic/faucet.rs, cell_observation.rs, dlv/beta_storage_profile.rs
(`sofi_beta_quorum_for`, `SOFI_BETA_QUORUM`, `dev_only_single_node_quorum`),
`RootRegisterProfile.quorum`, `AuthenticatedCaller`/`verify_claim_attribution`,
the SDK one-shot claim machinery, the ticket fake register, and
scripts/init_faucet_dlv.sh. Kept as ruled: the artifact-delivery and
identity-publication quorums.
Five faucet tags left with the ticket register; seven native reserve tags arrived with the reserve. The pinned count follows the registry.
cryptskii
deleted the
feat/sofi-r4-leader-first-reads-and-native-reserve-release
branch
September 21, 2026 00:19
cryptskii
added a commit
that referenced
this pull request
Sep 21, 2026
0x0030 was moved into burned_class by R4 (#939) without being added to burned_class::ALL, so is_burned_class(0x0030) answered false for a constant declared as burned and sofi_v8_independent::class_discriminants_do_not_collide has been red on main since. One line.
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.
R4 — the Core read adapter, and the beta faucet becomes a release of the native ERA reserve
Rebuild step R4 of the SoFi build order (spec §44), plus the owner's R4 addition (§44.3, 2026-09-20): the dead SoFi-named counting goes, and the beta faucet's quorum-backed ticket register is replaced by the native ERA reserve — one canonical lineage per network, released leader first, replicated to every member in the background.
What is built
Core read adapter (R4 proper).
sofi::arith::resolve_objectsderivesFinal/LeaderHeld/Open/Unavailablefrom raw member reads over a recognition predicate;read_economic_root_cellnow runs on it. Nothing is counted; the leader's read decides, and an unread leader isUnavailable, never empty.The native ERA reserve (
CORE/economic/native_reserve.rs, new):R_0 = NativeReserveState { era_reserve_id(network), ERA, remaining = 80,000,000,000, generation 0, S }— computed from public inputs, never stored.release_constructible(parent, release)→remaining' = remaining − amount,generation' = generation + 1. No mint arm, no creator withdrawal; an overdraft or a zero release is not an object naming the cell and counts as nothing.ReleaseSource::FaucetClaimant { claimant_public_key }is the beta source: the recipient IS the claimant; the seam for a laterEmissionLotteryRecipientis another arm of that enum, not a change to the mechanics.K(reserve, R_n), seed(reserve, R_n), leader =FisherYates(seed, S)[0]over the committed set;recognize_release,resolve_successor,walk_lineage.0x005D CreditSourceNativeReserveRelease;0x0030burned.Operation::FaucetClaim { reserve_id, generation }(tag 31, byte-identical layout). The provenance arm re-runs the construction predicate against the parent state the walk validated, then checks recipient = the identity under validation with the proven AK, position + operation-digest binding, the canonical set, and the evidence address.Finality vs replication (owner ruling, §44.3 item 11). Finality is the deterministic leader plus two other members holding the same recognized object — a release final on three members is exposed to the recipient at once. Replication is all-member, asynchronous:
sdk::native_reserve::carry_pending_releasesruns in the artifact sync pass until every member holds each successor. An unavailable non-leader never blocks a claim.Committed set, never live membership.
S_commit(R_n)decidesR_n → R_{n+1}: every reserve state commitsstorage_set_id,release_constructiblerefuses a release naming any other set, and the SDK'sread_successor/write_releaserefuse aStorageSetwhose id is not the state's before computing a leader or touching a member (committed_set_only).S_liveis only ever the carry's target; nothing the carry writes is read back intoresolve_objects, which reads the committed members only.SDK.
sdk/native_reserve.rs(memoised walk fromR_0, leader-first write,release_atfor the live resolver, the carry),faucet_claim_flow.rsrewritten (walk to the head → sign once per parent root → write leader first → read backFinalof our bytes; a lost race re-walks; a crash after finality is resumed from the memo), client schema v14 → v15.What is deleted
Core:
economic/faucet.rs,economic/cell_observation.rs(observe_cell,canonical_quorum),dlv/beta_storage_profile.rs(sofi_beta_quorum_for,SOFI_BETA_QUORUM,dev_only_single_node_quorum),RootRegisterProfile.quorum,AuthenticatedCaller/verify_claim_attribution/MAX_CLAIM_BYTES. SDK: the one-shot claim machinery (ClaimFanout,classify_one_shot_response,answer_counts_for,MemberEcho,submit_one_shot_claim,read_register_cell), the ticket fake register,select_ticket. Node:api/economic/faucet_ticket.rs, thefaucet_ticket_claimstable on both backends,node.network_id,db/write_once_properties.rs,tests/economic_register_conformance.rs. Formal:DSM_EconRegisterObservation.tlaand its 6 configs, the §10 quorum theorems ofDSMEconomicSmtSeparation.lean. Scripts:init_faucet_dlv.sh(wrote a 1 MBdlv_slotsquota row, nothing the faucet ever read).Kept as ruled (§44.3 item 9):
StorageSet::quorum/publication::quorum_for— artifact delivery and identity publication, unrelated subsystems.Formal side, in tandem
tla/DSM_NativeReserveRelease.tla(new, exhaustive):Conservation,NoValidReserveTransitionMints,NoCreatorBackout,RecipientIsClaimant,ReleaseAccounting,FinalRequiresLeader,AtMostOneFinal,LeaderFromCommittedSet,UnrecognizedBytesNeverOccupy,ThreeHoldersIsFinal,UnavailableNonLeaderNeverBlocks,ReplicasDoNotAlterTheWinner. 8 fault configs + 3 reachability configs; every one violates exactly its named invariant under TLC. Runner: 69 → 75 standard specs.lean4/DSMNativeReserve.lean(new): the one transition,Reachwith a single step constructor (no creator backout by shape),total_era_is_conserved, leader-firstwinner/final. Lean modules 15 → 16.Correspondence and controls
Conservation,ReleaseAccountinga_release_conserves_the_reservea_release_conserves_the_reserveNoValidReserveTransitionMintsno_valid_reserve_transition_can_mint_era,an_overdraft_is_refusedno_valid_reserve_transition_can_mint_era; wirea_release_that_is_not_its_parents_successor_funds_nothingConservationtotal_era_is_conservedtotal_era_is_conserved_along_the_lineage; wirecredits_funded_along_a_lineage_sum_to_what_the_reserve_releasedNoCreatorBackoutno_creator_backout(single constructor)no_creator_backout_the_only_transition_is_a_release_to_its_recipientRecipientIsClaimantfaucet_claim_names_its_claimant_as_recipientfaucet_claim_names_its_claimant_as_recipientFinalRequiresLeaderfinality_without_the_deterministic_leader_is_impossibleReplicasDoNotAlterTheWinneradditional_replicas_do_not_alter_the_winneradditional_replicas_do_not_alter_the_winnerLeaderFromCommittedSeta_set_other_than_the_one_the_reserve_commits_never_names_a_leaderUnavailableNonLeaderNeverBlocks,_AllMembersHoldReachablethree_holders_is_finalan_unavailable_non_leader_never_blocks_finality_and_the_carry_reaches_it_laterMutation controls executed (each restored afterwards):
FinalRequiresLeader,LeaderFromCommittedSet,ThreeHoldersIsFinal,UnavailableNonLeaderNeverBlocks,NoValidReserveTransitionMints,Conservation,NoCreatorBackout,RecipientIsClaimant, and the three reachability claims).amount ≤ remainingfailsa_release_conserves_the_reserve,release_never_exceeds_the_reserve,an_overdraft_is_refused,total_era_is_conserved; droppingrecipient = claimantfailsfaucet_claim_names_its_claimant_as_recipient; counting without the leader failsfinality_without_the_deterministic_leader_is_impossible.release_constructible→no_valid_reserve_transition_can_mint_eraanda_release_that_is_not_its_parents_successor_funds_nothingred; dropping the recipient/AK check in the provenance arm →faucet_claim_names_its_claimant_as_recipientred; lettingsofi::arith::resolvefall back to any holder when the leader holds nothing →three_non_leaders_agreeing_is_not_final, Corefinality_without_the_deterministic_leader_is_impossibleand the SDK fake-fleet twin red; droppingcommitted_set_only→a_set_other_than_the_one_the_reserve_commits_never_names_a_leaderred.Gates
--features testing): lib filtereconomic::native_reserve sofi::arith economic::write_set economic::provenance economic::credit types::operations types::device_state134/0; integrationnative_reserve_wire12/0,economic_admission_lifecycle14/0,economic_write_set23/0,economic_lineage_register12/0,economic_provenance_semantics3/0,economic_peer_evidence9/0,economic_authorized_issuance12/0,economic_root_primitives20/0,domain_encoding_byte_preservation9/0,universal_faucet_invoke_test1/0.--features test-utils):sdk::native_reserve4/0,handlers::faucet_flow_tests6/0, plusstorage_io/client_dbfilters 15/0 total;faucet_claim2/0,bearer_staging_fail_closed2/0.db::cell_properties6/0,cells_keep_everything6/0,immutable_store_round_trip4/0;ci/storage_is_dumb.shOK.DSM_NativeReserveRelease.cfgexhaustive, 1,768,960 distinct states, no error; all 11 falsification configs violate exactly their invariant. Lean:DSMNativeReserve.leanandDSMEconomicSmtSeparation.leankernel-check with-DwarningAsError=true.make lintexit 0;ci/production_safety_checks.shpassed (sofi reachability: 60 pub fn reachable, 19 in the baseline).Frontend: proto bindings regenerated (
npm run proto:gen); thefaucet.claimroute and its request/response are unchanged. Android: unchanged.Spec
§44.2 gains the R4 row; §44.3 carries the owner's R4 addition and the finality-vs-replication ruling; Appendix A reconciled (native supply is its own reserve lineage, not a Market DLV).