Skip to content

feat!: adopt the five-state Mixnet Mode and the zingolib funnel (ADR 0024 phase 2 slice) - #1241

Open
zancas wants to merge 2 commits into
devfrom
mixnet_convergence_dev
Open

feat!: adopt the five-state Mixnet Mode and the zingolib funnel (ADR 0024 phase 2 slice)#1241
zancas wants to merge 2 commits into
devfrom
mixnet_convergence_dev

Conversation

@zancas

@zancas zancas commented Jul 29, 2026

Copy link
Copy Markdown
Member

The first phase-2 slice of the consumer convergence (zingolib ADR 0024, #1236). One commit on top of dev.

The zingolib pin advances from branch = dev to a rev pin on the convergence stack head (zingolib 5c02b2ed8, the #2586 tip). That rev carries the five-state Mixnet Mode wire mint, the session driver, the mixnet-only price rule, and the netutils funnel. Rev pins are the ratified form (ADR 0024 decision 7). The pin advances along zingolib history as the stack merges.

The app-side wire mint dies. mixnet_mode_string is deleted and every render goes through zingolib's MixnetMode::as_str, the canonical mint. disable reports the real switched_off token instead of the retired off. zec_price consumes the typed MixnetPriceFetch route evidence. The direct crates.io zingo-netutils dependency is dropped in favor of zingolib::netutils, which kills the capability-less duplicate copy (#1236, zingolib#2566): cargo tree now shows one netutils.

The TypeScript layer follows. The enum re-declares zingolib's five tokens verbatim and the parser rejects the retired off (accepting it would reunify consent with absence). The app-side consent bit (ClearnetConsent, vetPolledStatus) retires: the wallet itself distinguishes switched_off (deliberate clearnet consent) from unattached (no transport, no consent), which was the whole point of #1226. The presenter splits off into those two states, the Settings toggle reads the new keys, and the mixnet.status.off translation key splits in all five locales. The mixnet unit suites pin the five-token parse, the retired-token rejection, and the consent flow through the wallet's own states.

The iOS fail-open closes end to end (#1235). A platform whose transport has not landed gets the blocked platform-unavailable view instead of null, and the Send gate itself fails closed on a null view. Absence is never consent.

Merge dependency: the rev pin targets the open zingolib stack (#2579 through #2586). The rev resolves and builds today, and CI runs against it, but this PR should land after (or together with) that stack's merge so the pin can advance to a dev-reachable rev.

Verified: cargo check and clippy clean, 56/56 rust tests, tsc clean, jest 66 suites, 452 tests, 95 snapshots green.

🤖 Generated with Claude Code

…0024 phase 2 slice)

The zingolib pin advances from branch = dev to the convergence stack rev
(5c02b2ed8, zingolib#2586, rev-pinned per ADR 0024 decision 7), bringing
the five-state Mixnet Mode wire mint, the session driver, the
mixnet-only price rule, and the netutils funnel. The app-side wire mint
dies: mixnet_mode_string is deleted and every render goes through
zingolib's as_str, disable reports the real switched_off token instead
of the retired off, and zec_price consumes the typed MixnetPriceFetch
route evidence. The direct crates.io zingo-netutils dependency is
dropped in favor of zingolib::netutils, killing the capability-less
duplicate copy (zingo-mobile#1236, zingolib#2566).

The TypeScript layer follows: the enum re-declares zingolib's five
tokens verbatim and the parser rejects the retired off; the app-side
consent bit (ClearnetConsent, vetPolledStatus) retires in favor of the
wallet's switched_off/unattached distinction; the presenter splits off
into unattached (blocked, no consent) and switched-off (consented
clearnet); the Settings toggle reads the new keys; the
mixnet.status.off translation key splits in all five locales; the
mixnet unit suites pin the five-token parse, the retired-token
rejection, and the consent flow through the wallet's own states.

The iOS fail-open closes end to end (zingo-mobile#1235): a platform
whose transport has not landed gets the blocked platform-unavailable
view instead of null, and the Send gate itself fails closed on a null
view. Absence is never consent.

Verified: cargo check and clippy clean, 56/56 rust tests; tsc clean;
jest 66 suites, 452 tests, 95 snapshots green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@zancas
zancas requested review from dorianvp and juanky201271 July 29, 2026 05:25
…rnet

The integration shards fell to one root cause: the funded mobileclient
scenarios' faucet sends panicked on MixnetNotReady(Unattached), because
the five-state wallet refuses an unconsented send and the scenario
clients predate that doctrine. The ledger-and-parsing shard carried the
genuine failure; the accounts and chain shards were fail-all
cancellations of the same run.

The pin advances to the stack head that fixes the scenarios at the
source (zingolib 53e806f47: consent_to_clearnet before every scenario
send, behind a new zingolib_testutils `nym` feature), and the
zingolib_testutils dependency enables that feature so the consent
compiles in. Workspace check and 56/56 unit tests stay green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

1 participant