workspace: fold the offchain crates into the root workspace - #4255
Merged
Conversation
bgm-malbeclabs
force-pushed
the
migrate/merge-workspaces
branch
from
September 1, 2026 21:16
2096806 to
090eac9
Compare
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
This PR is step 4 of the monorepo migration. It removes the standalone offchain/ Rust workspace and folds its crates into the root workspace so the repo builds against a single root lockfile and toolchain, while keeping solana/ excluded with its own lockfile to preserve reproducible program bytes.
Changes:
- Add the 15 offchain crates as root workspace members, and move their shared dependencies into root
[workspace.dependencies]. - Update offchain crate manifests to state
edition = "2024"and keepbincodeandreqwestpinned per-crate to avoid API and TLS-backend changes. - Rename the e2e sentinel binary to
dz-e2e-sentineland update e2e Docker builds to compile only the required binaries; update the revdist fixture generator to use path dependencies intosolana/.
File summaries
| File | Description |
|---|---|
| solana/programs/revenue-distribution/tests/initialize_distribution_test.rs | Import cleanup to match formatting after workspace changes. |
| solana/programs/revenue-distribution/src/state/distribution.rs | Import cleanup to match formatting after workspace changes. |
| solana/programs/revenue-distribution/src/state/contributor_rewards/mod.rs | Import cleanup to match formatting after workspace changes. |
| sdk/revdist/testdata/fixtures/generate-fixtures/Cargo.toml | Switch solana dependencies from git to local path dependencies. |
| sdk/revdist/testdata/fixtures/generate-fixtures/Cargo.lock | Remove git sources for the solana crates after path dependency switch. |
| offchain/scheduler/native/scheduler_doublezero/Cargo.toml | Move to edition 2024 and pin reqwest TLS backend; now part of root workspace. |
| offchain/rust-toolchain.toml | Delete offchain-scoped toolchain so offchain crates use the repo toolchain. |
| offchain/crates/validator-debt/src/worker/mod.rs | Minor clippy cleanup (remove redundant references in format args). |
| offchain/crates/validator-debt/src/validator_debt.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/validator-debt/src/rewards.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/validator-debt/src/jito.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/validator-debt/src/inflation.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/validator-debt/src/block.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/validator-debt/Cargo.toml | Set edition 2024; pin bincode/reqwest per-crate to avoid API/TLS changes. |
| offchain/crates/solana-sdk/Cargo.toml | Set explicit version and edition (avoid inheriting root workspace values). |
| offchain/crates/solana-interface/sol-conversion/Cargo.toml | Set edition 2024 explicitly. |
| offchain/crates/solana-fork/Cargo.toml | Set edition 2024 explicitly. |
| offchain/crates/solana-client-tools/Cargo.toml | Set explicit version and edition; pin bincode 1 per-crate. |
| offchain/crates/solana-cli/src/command/shreds/validator_client_rewards/show.rs | Clippy cleanup (remove redundant .into_iter() in zip). |
| offchain/crates/solana-cli/src/command/shreds/validator_client_rewards/init_holding.rs | Clippy cleanup (remove redundant .into_iter() in zip). |
| offchain/crates/solana-cli/src/command/shreds/list.rs | Clippy cleanup (remove redundant .into_iter() in zip). |
| offchain/crates/solana-cli/src/command/revenue_distribution/fetch/distribution.rs | Simplify match into guards (clippy cleanup). |
| offchain/crates/solana-cli/Cargo.toml | Set edition 2024; pin reqwest per-crate. |
| offchain/crates/solana-admin-cli/sol-conversion/Cargo.toml | Set edition 2024 explicitly. |
| offchain/crates/solana-admin-cli/revenue-distribution/Cargo.toml | Set edition 2024 explicitly. |
| offchain/crates/solana-admin-cli/passport/Cargo.toml | Set edition 2024 explicitly. |
| offchain/crates/slack-notifier/Cargo.toml | Set edition 2024; pin reqwest per-crate. |
| offchain/crates/sentinel/Cargo.toml | Set edition 2024; pin bincode/reqwest per-crate. |
| offchain/crates/scheduled-command/Cargo.toml | Set explicit version and edition (avoid inheriting root workspace values). |
| offchain/crates/passport-cli/Cargo.toml | Set explicit version and edition (avoid inheriting root workspace values). |
| offchain/crates/contributor-rewards/tests/test_s3_storage.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/tests/test_pvt_links.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/tests/test_pub_links.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/tests/test_historical_epoch.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/tests/common/mod.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/src/ingestor/inet_accumulator.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/src/ingestor/epoch.rs | Clippy unreadable_literal fixes in tests. |
| offchain/crates/contributor-rewards/src/ingestor/demand.rs | Import cleanup and use sort_by_key with Reverse. |
| offchain/crates/contributor-rewards/src/cli/inspect.rs | Simplify loop counter logic using (1u32..).zip(cities). |
| offchain/crates/contributor-rewards/src/calculator/shapley/handler.rs | Clippy unreadable_literal fix in tests. |
| offchain/crates/contributor-rewards/src/calculator/constants.rs | Clippy unreadable_literal fix for a constant. |
| offchain/crates/contributor-rewards/Cargo.toml | Set edition 2024 explicitly. |
| offchain/Cargo.toml | Delete the offchain workspace manifest now that crates are root members. |
| e2e/docker/sentinel/Dockerfile | Use the renamed dz-e2e-sentinel binary. |
| e2e/docker/base.dockerfile | Build only the four required binaries instead of --workspace. |
| crates/sentinel/Cargo.toml | Rename the e2e sentinel binary to avoid artifact name collisions. |
| CHANGELOG.md | Document the workspace merge and e2e sentinel rename. |
| Cargo.toml | Add offchain crates as workspace members; keep solana/ excluded; expand root workspace dependencies to cover offchain crates. |
| Cargo.lock | Large lockfile merge reflecting offchain dependency set in the root workspace. |
| .github/dependabot.yml | Remove offchain workspace scanning entry; keep solana excluded from dependabot cargo updates. |
Review details
- Files reviewed: 48/51 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
martinsander00
approved these changes
Sep 1, 2026
bgm-malbeclabs
force-pushed
the
migrate/merge-workspaces
branch
from
September 1, 2026 22:09
090eac9 to
aabc99c
Compare
bgm-malbeclabs
enabled auto-merge (squash)
September 1, 2026 22:12
bgm-malbeclabs
force-pushed
the
migrate/merge-workspaces
branch
from
September 1, 2026 22:43
825db3b to
cd063da
Compare
bgm-malbeclabs
disabled auto-merge
September 1, 2026 23:00
bgm-malbeclabs
enabled auto-merge (squash)
September 1, 2026 23:01
bgm-malbeclabs
force-pushed
the
migrate/merge-workspaces
branch
from
September 1, 2026 23:52
fd586f7 to
00d7caf
Compare
Step 4 of the monorepo migration. The offchain tree stops being its own workspace: `offchain/Cargo.toml`, `offchain/Cargo.lock` and `offchain/rust-toolchain.toml` are deleted and its 15 crates become root members, so everything resolves against one lockfile on 1.97.1 and the path dependencies from #4245 sit inside a single workspace. `solana/` stays excluded with its own manifest, lockfile and 1.91 toolchain. 62 of the 96 crates in the programs' build closure resolve differently here, which would change the compiled bytes and break `solana/programs/sha256sums_*.txt`. Two inherited keys had to be stated per crate. All 15 crates are edition 2024 and the root workspace is 2021, so an inherited edition would have moved them to 2021, where they do not build. Four of them also inherited the version, so an inherited version would have reversioned them from 0.0.1 to 0.38.0. `bincode` and `reqwest` are declared per crate in the offchain tree instead of coming from the workspace. This repo is on bincode 2, whose API differs, and on reqwest with its default TLS backend, while the offchain crates use bincode 1 and rustls with the OS root store. Unifying either is a code change, and the reqwest one would move `ip_proof`, a trust boundary, onto a different TLS stack. The e2e sentinel binary becomes `dz-e2e-sentinel`, because offchain ships a deb named `doublezero-sentinel` and two members cannot write the same file into `target/release`. The base image also names the four binaries it serves rather than building `--workspace`, which would now compile arrow, parquet and the AWS SDK on the way to a client and a sentinel. The revdist fixture generator reaches its two solana crates by path rather than by an unpinned git dependency. Its lockfile had drifted to solana#121 and the fixtures still regenerate byte-identical. Offchain's release profile (`lto = true`, `codegen-units = 1`) is not carried over. Profiles are workspace-wide, so keeping it would apply full link-time optimization to every release build in this repo. The spec's plan to convert solana's `>=2,<=3` ranges to exact pins is dropped. It was written when the programs were joining the workspace. D2 holds them back and doublezero-shreds still consumes them by git, so the ranges still earn their keep.
An unscoped `cargo test-sbf` resolves the whole workspace against the
platform-tools rustc, which reports itself as 1.89.0-dev. Folding the offchain
crates in brings `aws-sdk-s3`, which declares a minimum of 1.94.1, and
`rustler`, which declares 1.91, so resolution fails before anything is built:
error: rustc 1.89.0-dev is not supported by the following packages:
aws-sdk-s3@1.144.0 requires rustc 1.94.1
rustler@0.37.4 requires rustc 1.91
Neither crate is in any program's dependency graph. The failure comes from
resolving packages the command never builds.
Passing a `-p` list avoids that resolve and then fails differently: cargo
test-sbf builds the .so for the package in the current directory, and there is
no package here, so solana-program-test finds nothing in target/deploy and
every test panics with "Program file data not available".
Running from each program's directory, the way build-programs already does,
fixes both: the resolve covers one program, and each program's .so is built
before its tests run. Serviceability runs before telemetry, whose test helper
loads the serviceability .so through add_program with no processor.
Verified with the toolchain CI uses, platform-tools v1.54 and rustc 1.89.0:
`make test-sbf` from an emptied target/deploy passes 70 suites with no
failures.
It carried no version before the merge and none after, so cargo called it 0.0.0 either way. Nothing reads it, since the NIF is loaded by the mix release rather than by cargo, but every other crate in the tree names its own version and this one may as well.
bgm-malbeclabs
force-pushed
the
migrate/merge-workspaces
branch
from
September 1, 2026 23:52
00d7caf to
56cb7a0
Compare
bgm-malbeclabs
added a commit
that referenced
this pull request
Sep 2, 2026
`TestE2E_BackwardCompatibility` asks the GitHub API which client releases exist, so it knows which versions to test against. The e2e shard step sets only `DZ_E2E_NO_BUILD`, so that call goes out unauthenticated: **60 requests an hour, shared across every GitHub-hosted runner on the same address.** It usually gets through, and fails when the address is busy. It failed that way on #4255: ``` compatibility_test.go:657: Received unexpected error: GitHub API returned 403: {"message":"API rate limit exceeded for 34.202.172.237. ..."} ``` Both subtests failed in six seconds, before reaching a devnet, so shard 1 went red for reasons that had nothing to do with the pull request under test. ## Summary - The shard step passes `GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}`. That raises the limit from 60 an hour shared to 1,000 an hour for this repository. - **No new secret.** `secrets.GITHUB_TOKEN` is the workflow token GitHub mints per run. - **No code change.** `e2e/compatibility_test.go` already reads `GITHUB_TOKEN` and falls back to `GH_TOKEN`; nothing was setting either. Only shard 1 makes these calls, since `TestE2E_BackwardCompatibility` has its own dedicated shard, but the env belongs on the shared step rather than being conditioned on the shard number. ## Testing Verification - The failure is identified from its own error text rather than inferred: a 403 naming the rate limit and the runner's shared address, on `compatibility_test.go:657`, which is the `FetchGitHubClientReleaseTags` call. - `actionlint` on the changed workflow: no new findings.
bgm-malbeclabs
added a commit
that referenced
this pull request
Sep 2, 2026
Step 5 of the monorepo migration, per `docs/superpowers/specs/2026-08-27-monorepo-migration-design.md`. **Stacked on #4255** and based on that branch, so the diff shown here is step 5 alone. The 11 workflows that came with the two source repos are folded into this repo's set, and the imported `.github` directories are deleted. GitHub reads workflows only at the repository root, so nothing in those directories has ever run here. ## Where each imported workflow went | Imported | Fate | | --- | --- | | offchain `release.contributor-rewards.yml` | ported, `release.contributor-rewards.yml` | | offchain `release.doublezero-solana-cli.yml` | ported, `release.doublezero-solana-cli.yml` | | offchain `release.sentinel.yml` | ported, `release.offchain-sentinel.yml` | | offchain `release.solana-validator-debt.yml` | ported, `release.solana-validator-debt.yml` | | offchain `release.scheduler.yml` | ported, `release.offchain-scheduler.yml` | | offchain `local-validator.yml` | ported, `offchain.local-validator.yml`, two live jobs of four | | offchain `ci.yml` | dropped; `make rust-build`/`rust-lint`/`rust-test` cover those crates now | | offchain `changelog-reminder.yml` | merged into this repo's `changelog-reminder.yml` | | solana `rust.yml` + `verify-build.yml` | ported as one new `solana.yml` | | solana `local-validator.yml` | dropped; every job in it was `if: false` upstream | | — | new `elixir.yml`, which had no upstream equivalent in CI | ## Summary - **The five release workflows run goreleaser from the repository root**, not from `offchain/`. The merged workspace writes to the root `target/`, which is where goreleaser's rust builder looks for the binary it packages; running it from `offchain/` would send it looking in `offchain/target/`. Every relative path inside the five configs is rewritten to match, including the scheduler's four `mix` hooks and its `_build` source. - **`release.github.name` moves from `doublezero-offchain` to `doublezero`** in all five configs, so the releases land on this repository. The `owner` was already corrected during the org move. This repo already holds `CLOUDSMITH_TOKEN`, `GORELEASER_KEY` and `SLACK_BOTS_WEBHOOK`, so the spec's "copy three secrets" step is already done. - **New `solana` workflow, and it matters more than a port.** The `solana/` tree is an excluded nested workspace, so `rust.yml` never reaches it: without this, the two Solana L1 programs would sit in this repo with no CI at all. It runs that tree's own lint, library tests, docs and SBF tests for both networks, plus the checksum gate that rebuilds the artifacts and verifies them against `solana/programs/sha256sums_*.txt`. Path-scoped to `solana/**`. - **New `elixir` workflow**, path-scoped to `offchain/scheduler/**`: format check, compile with warnings as errors, credo, tests. Upstream these ran on a release tag only, so a pull request that broke the scheduler passed and the tag failed later. - **`offchain-local-validator` runs from the repository root**, because the fork scripts resolve their binaries as `target/debug/<name>` and create their keypairs and `test-ledger/` in the working directory, so all of it has to agree on one. Path-scoped to `offchain/**`, `solana/**` and the root manifests rather than running on every pull request as it did in a quieter repo. - **`rust-cli-static` covers all five released CLIs** instead of the client alone, which is what offchain's `rust-musl-static` job did for its four. Each package is built on its own so feature unification matches the release. The job keeps its name, since it is a required status check. - **`changelog-reminder` keeps offchain's per-crate check**, paths moved under `offchain/`. This is a union, not a dedupe: a change to one of those 13 subprojects now needs both the root `CHANGELOG.md` and that subproject's own. ## What is deliberately not carried over - **The `just ci` coverage floor** (`cargo llvm-cov nextest --fail-under-lines 25`). It measured a workspace that no longer exists, and running it over the merged workspace would both mean something different and cost a full instrumented build of 37 crates on every run. - **The two dead fork jobs**: one `if: false`, one commented out with a note about bringing it back. Both are in the imported history if wanted. - **`offchain/Justfile`'s Rust recipes.** From `offchain/` they would now run cargo over the whole workspace, and with a different fmt line (`group_imports=StdExternalCrate`) and clippy line than CI uses. The Elixir recipes stay, plus two fork-test recipes that cd to the root. ## Testing Verification - `actionlint` over every new and changed workflow: no errors. The only output is SC2086 info notes on `$SOLANA_CLI` and `$GITHUB_PATH`, the same pattern the existing `rust.yml` jobs already carry. - The shell body of the rewritten `changelog-reminder` check parses under `bash -n`, and `offchain/scripts/release-rc.sh` still parses after the path changes. - `just -l` in `offchain/` lists the trimmed recipe set. - `cd solana && make lint` passes, which is the job `solana.yml` runs first. Worth stating because step 4 reformatted three files in that tree with the root's `imports_granularity=Crate`: plain rustfmt preserves existing import grouping, so solana's own `cargo fmt --check` still agrees. - `NETWORK` is passed as `mainnet-beta` or `development` explicitly, never empty: `solana/Makefile` validates it and errors on anything else. - The three CI workflows here trigger on this pull request, so they prove themselves. The five release workflows only fire on a tag, so they stay unproven until the spec's own gate: a throwaway release candidate tag on the smallest component, confirming the release lands under malbeclabs and the package reaches Cloudsmith.
bgm-malbeclabs
added a commit
that referenced
this pull request
Sep 2, 2026
**Stacked on #4256**, top of the migration stack, so the diff shown here is the sync alone. #4240 captured `doublezero-offchain` at its #414. Three pull requests landed there afterwards, so the imported tree went in three commits stale. This replays them. ## Summary - **offchain#415** removes `doublezero-solana shreds pay`. `withdraw`, `list`, `payments` and `price` stay. This is the other half of #4248 in this repo, which removed the QA e2e that funded a seat through it. - **offchain#416** removes the fund-seat instruction from the offchain Solana SDK, while `shreds payments` keeps reading leftover fund-seat transactions so history stays legible. - **offchain#417** moves the solana-cli crate to 0.5.12. - Each commit keeps its original author, date and message. The bare `(#N)` references are rewritten to name `malbeclabs/doublezero-offchain`, exactly as the import rewrote its own 451, so a reader following a link does not land on an unrelated pull request in this repo. - `offchain/Cargo.lock` is left out of the replay, because #4255 deleted it. The version bump it carried lands in the root lockfile instead, which is where the crate resolves now. - **`solana/` needs no sync.** Its upstream tip is the tip that was imported. ## Testing Verification - `git diff` between `offchain/crates` here and the same tree at upstream `main` comes back to exactly the files steps 3, 4 and 5 changed, and nothing else: the manifests, the clippy fixes, and step 3's `feed_pks` compatibility change. Nothing upstream is missing and nothing extra crept in. - `cargo clippy -p doublezero-solana-cli -p doublezero-solana-sdk --all-targets` with this repo's lint line: clean. - `cargo test` for both crates: 161 passed. - Nothing outside `offchain/` referenced the removed command. The only match in the repo is a CHANGELOG line describing #4248, which is a historical note. ## Note for whoever reads the per-crate changelogs The changelog text these commits add still carries bare `(#N)` references, because the import rewrote commit messages only and left file contents alone. Every imported per-crate changelog is like this. Rewriting them is a separate job, if it is worth doing at all. --------- Co-authored-by: Martin Sander <69667393+martinsander00@users.noreply.github.com>
bgm-malbeclabs
added a commit
that referenced
this pull request
Sep 2, 2026
…4261) Step 6 of the monorepo migration, the half that lives in this repository. Archiving the two source repositories is an action on those repositories, and the text to use is below. **Stacked on #4257**, so the diff shown here is this change alone. ## Summary - **`offchain/CONTRIBUTING.md` is removed.** It told contributors to fork `doublezero-offchain` and to open pull requests and issues against it. Both stop being true the moment that repository is archived: an archived repository takes no issues and no pull requests. Everything else in the file repeated the root README, and the one thing the root lacked, the Contributor Covenant reference, moves there. - **DEVELOPMENT gains a section on the two imported trees**, naming what the root `make` targets do not reach: the Solana L1 programs, which keep their own workspace, lockfile and 1.91 toolchain so their bytes stay reproducible against `sha256sums_*.txt`, and the Elixir scheduler. Both now have their own path-scoped CI, which the section names. I checked the rest of both trees for pointers that stop being true after the archive. There is only one other class, and it should stay: the per-crate changelogs link to releases at `doublezero-offchain`. Those releases exist there and an archived repository still serves them, so the links keep working. Rewriting historical release links would make them wrong, not right. ## For the archive itself Both repositories keep their transfer redirects, their 11 forks and their old release download URLs, so archive them read-only rather than deleting. Suggested notice for the top of each README before archiving: > **This repository has moved.** The code now lives in > [malbeclabs/doublezero](https://github.com/malbeclabs/doublezero), under `offchain/`, > with its full history and its release tags. This repository is archived and read-only. > Open issues and pull requests against `malbeclabs/doublezero`. > > Existing releases and their download URLs continue to resolve here. New releases are > published from `malbeclabs/doublezero`. Same text for `doublezero-solana`, with `solana/` as the directory. Archiving is also what unblocks step 7, and the two are deliberately not the same day: an archived repository still serves reads, so `doublezero-shreds` keeps resolving `malbeclabs/doublezero-solana` at tag `revenue-distribution/v0.3.7`, and that tag imported here points at the same commit. Shreds can be repointed when it suits. ## Testing Verification - Searched both imported trees for links to the source repositories outside changelogs and release links. `offchain/CONTRIBUTING.md` was the only live pointer; `offchain/Cargo.toml` also carried `repository` and `homepage` fields naming the old repo, and #4255 deletes that file outright. --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.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.
Step 4 of the monorepo migration, per
docs/superpowers/specs/2026-08-27-monorepo-migration-design.md. Stacked on #4245 and based on that branch, so the diff shown here is step 4 alone. It retargets as the stack lands.The offchain tree stops being its own workspace.
offchain/Cargo.toml,offchain/Cargo.lockandoffchain/rust-toolchain.tomlare deleted, its 15 crates become root members, and everything resolves against one lockfile on the 1.97.1 toolchain.solana/stays excluded with its own three files, because 62 of the 96 crates in the programs' build closure resolve differently here and that would change the compiled bytes behindsolana/programs/sha256sums_*.txt.Summary
git+source for this repo or for doublezero-solana remains inCargo.lock; the only git dependency left isnetwork-shapley, which lives in another organization.bincodeandreqwestare declared per crate in the offchain tree. This repo is on bincode 2, whose API differs, and on reqwest with its default TLS backend, while the offchain crates use bincode 1 and rustls with the OS root store. Unifying either is a code change, not a manifest change, and the reqwest one would moveip_proof— a trust boundary — onto a different TLS stack. Everything else reconciles to the tighter requirement or the union of features.dz-e2e-sentinel(D4). Offchain ships a deb nameddoublezero-sentinel, and two members of one workspace cannot write the same file intotarget/release. The two images follow the new name. Both binaries now build side by side.--workspace, which would now compile arrow, parquet and the AWS SDK on the way to a client and a sentinel.unreadable_literal, which this repo's lint line adds and offchain's did not. The rest: a match that collapses into guards, three redundant.into_iter()calls inzip, a loop counter, and asort_bythat is asort_by_key.Two deliberate departures from the spec
lto = true,codegen-units = 1) is not carried over. Cargo profiles are workspace-wide, so keeping it would apply full link-time optimization to every release build here, including the ones e2e waits on. The offchain release binaries lose that optimization. Accepted, not deferred: step 5 has no profile work to do. A customrelease-ltoprofile would be the way back, and it would need care, because goreleaser's rust builder looks fortarget/<triple>/release.>=2,<=3ranges are left as ranges. The spec's instruction to pin them was written when the programs were joining the workspace. D2 holds them back and doublezero-shreds still consumes them by git, so the ranges still earn their keep for an external consumer.Testing Verification
cargo clippy --workspace --all-targetswith the Makefile's exclusions and-Dclippy::all -Dclippy::unreadable_literal -Dwarnings: clean.cargo test --workspace --all-featureswith the same exclusions: 439 passed. The one failure isip_proof::tests::probe_skips_a_local_address_that_cannot_reach_the_destination, in a root crate this branch does not touch. It asserts that the kernel rejects a loopback source toward a public address; the syscall reproduces on darwin as accepted for UDP, so the probe returnsBind. Linux only.test_aggregated_shapley_output_matches_goldenandtest_per_city_shapley_output_matches_goldenboth green, which is the risk the spec singles out as the serious one: contributor reward figures changing silently in a new lockfile.doublezero accountscompat check across all three environments: exit 0. Deployed program bytes are unaffected either way, sincecargo build-sbftakes features from each crate's own defaults rather than from workspace dependency entries.cd solana && cargo check --locked --workspace --all-targets: exit 0, and that lockfile needs no change.cargo build --workspace: exit 0.cargo +nightly fmt --all --check: clean, including three import blocks insolana/thatcargo fmt --allreaches through the new path dependencies.