Conversation
…ion ADR to 0018 ADR 0009 asserted that allow_v6_transactions vanished before any release carried it, leaving the wallet file format unchanged. ADR 0015 (PR #2529, merged to dev) supersedes that ruling: landing in dev ships the format, so version 42 names two on-disk layouts and the reader disambiguates them. The corrected sentence defers the format detail to ADR 0015. Because dev owns number 0015 for the wallet-format ADR, the branch-local migration ADR takes the next free number, 0018. The citations in ADR 0016 and in the quick_immediate_migration doc comment follow it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The concurrent mobile batch commit (f48b15c) introduced the part-anchors ADR as 0018 while the migration ADR was being renumbered to the same value. The part-anchors ADR keeps 0018, since the pushed branch already cites it by that number throughout migrate.rs and the migration store; the branch-local migration ADR takes 0019, and the citations in ADR 0016 and the quick_immediate_migration doc comment follow it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The citation in ADR 0016 and the doc-comment path in quick_immediate_migration still named 0018 after the renumber; both now point at 0019-immediate-migration-is-send-shaped.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every wallet/migration submodule declaration becomes pub(crate), so the re-export block in migration.rs is the module's whole public surface and a new public name is a deliberate act there rather than a side effect of pub in a submodule. Items inside the submodules keep plain pub under the ceiling, and helpers used only within their own file lose visibility entirely: estimated_unix_at, random_target_in_bucket, bucket_at_or_after, immediate_migration_fee, and the EXPIRY_MODULUS, EXPIRY_WINDOW, and ANCHOR_AGE_CAP constants are now private, and previous_boundary is test-gated, which the dead-code lint exposed once its pub mask came off. The facade sheds the names nothing outside the crate uses: due_now_parts, plan_schedule, upcoming_windows, and window_timeline demote to pub(crate) re-exports, immediate_migration_fee and estimated_unix_at leave the block, and bucket_index and PartAssessment join it, the former because the libtonode migration tests call it (their import moves off the now-capped schedule module path), the latter because ReconcileReport's public field already exposed it without a nameable path. Three items the ceiling cannot reach because their carriers are public tighten individually: PartRecord::anchor_bucket, PartRecord::unassign, and LightWallet::bound_note_confirmed_at become pub(crate). The compiler adjudicated every step: cargo check --workspace --all-targets, clippy, and fmt are clean, and an unreachable_pub sweep confirms the mobile-facing LightClient surface and its status, handle, plan, and report types keep their reachability unchanged. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rustc's unreachable_pub lint reported 43 pub items that no external crate could ever reach: 30 in zingolib/src/wallet/legacy.rs, whose parent module is pub(crate), and 13 in zingo-cli, whose commands module is private. Each item now carries the smallest visibility that keeps the crate compiling. In legacy.rs the split was decided by the one out-of-module consumer, the v0/v32 wallet-file readers in disk.rs: the types and readers they drive keep pub(crate), items that only appear in those signatures match them at pub(crate), and everything referenced solely within the module becomes private. In zingo-cli the bin target's actual imports decided: the five functions main.rs uses stay pub, three items lib.rs uses become pub(crate), and the rest become private. No demotion surfaced dead code, so nothing was deleted or test-gated. The change prepares the tree for the decent_exposure CI gate, which holds -D unreachable_pub over every package. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
rustc's missing_docs lint found six gaps: the libtonode-tests and zingolib_testutils crates had no crate-level documentation, and zingo-netutils left GrpcIndexer::new and the three GetClientError variants undocumented. Each now states what the item actually does, read from the code rather than assumed. libtonode-tests also gains the forbid(unsafe_code) attribute every sibling crate already carries. The change prepares the tree for the decent_exposure CI gate, which holds -D missing_docs over every package. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
decent_exposure joins the PR workflow as its privacy authority. The other jobs start optimistically in parallel with it and share warm build caches, but when it fails, its final step cancels the entire run, so every in-flight job is reaped and its runner returns to the pool. The job carries actions: write for exactly that cancellation. The nightly workflow inherits the arrangement by calling ci-pr.yaml. The job enforces maximum item privacy in three layers, in order: rustc's unreachable_pub at deny, so nothing is public by accident; rustc's missing_docs at deny, so publicity always costs a written sentence; and cargo public-api against per-package goldens, so a change to any public surface is a reviewed diff rather than a side effect. The driver lives in the workbench crate as decent-exposure. It derives the package list from the root workspace manifest and appends the two standalone workspaces, so a new root member is gated automatically. Each layer runs against every package's lib target. The goldens under tools/workbench/goldens/public-api/ pin the default-feature surface of all ten packages; regenerate them with `cargo run --manifest-path tools/workbench/Cargo.toml --bin decent-exposure -- --bless` and review the diff. CI pins cargo-public-api 0.50.2, the version the goldens were generated with, installed through the taiki-e/install-action already used by the coverage workflow. (cherry picked from commit 0e5172e and adapted to this branch) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The crate visibility ceiling on the migration submodules left their interior items plain pub, and rustc's unreachable_pub flags the 21 of them the facade does not re-export publicly. Each now carries its real reach: fifteen become pub(crate) because other modules in the crate call them (the schedule arithmetic parts.rs and reconcile.rs lean on, the store read/write pair disk.rs drives, and the facade's own pub(crate) re-exports), and five become private because only their own module uses them (AnchorFloor's bucket helpers, draw_anchor_age, the ProveOnce type alias, and the free plan_immediate_migration behind the LightClient method of the same name). The facade block in migration.rs is untouched, and no item visible through it changes. No demotion surfaced dead code. The change satisfies the decent_exposure gate's first layer on this branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The golden cherry-picked from dev pins dev's surface. On this branch the visibility ceiling and the interior demotions removed more public API than the mobile work added, so the re-pin nets 125 lines smaller: 322 items leave the pinned surface and 197 join it. The decent-exposure gate passes all three layers against the result. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Source crates — code
wallet/legacy.rs)forbid(unsafe_code)attribute and an import moveSource crates — documentation
Tooling and CI
decent-exposure(new binary)decent_exposurejob in ci-pr.yamlGrand total: 26 files, +2946 / −96.
This PR brings the
decent_exposureprivacy gate of #2541 to the mobile-API branch, so #2509's surface is policed by the same three layers before it merges: rustc'sunreachable_pubat deny, rustc'smissing_docsat deny, andcargo public-apiagainst per-package goldens. The CI arrangement is the one #2541 describes — the other jobs start optimistically in parallel and share warm caches, and a privacy failure reaps the entire run.The stack begins with the visibility-ceiling commit already prepared on
chore/2509-visibility: everywallet/migrationsubmodule declaration becomespub(crate), so the facade re-export block in migration.rs is the module's whole public surface. The gate's first layer then flagged the 21 interior items the ceiling left plainpubthat the facade does not re-export; a follow-up commit demotes each to its real reach — fifteen topub(crate)for their cross-module callers, five to private. No demotion surfaced dead code, and no item visible through the facade changes.The three gate commits are cherry-picks from #2541, and the final commit re-pins the zingolib golden for this branch: the ceiling and the demotions remove more public API than the mobile work adds, so the pinned surface nets 125 lines smaller — 322 items leave, 197 join. That golden diff is the reviewable record of exactly what #2509 plus this stack does to zingolib's public face. The gate passes all three layers locally on the result.
🤖 Generated with Claude Code