Skip to content

refactor(vara): migrate polkadot-sdk to upstream stable2409#5471

Open
ukint-vs wants to merge 38 commits into
masterfrom
vs/polkadot-upstream-2409-proof
Open

refactor(vara): migrate polkadot-sdk to upstream stable2409#5471
ukint-vs wants to merge 38 commits into
masterfrom
vs/polkadot-upstream-2409-proof

Conversation

@ukint-vs
Copy link
Copy Markdown
Member

@ukint-vs ukint-vs commented May 19, 2026

Summary

Draft proof branch for removing Gear's dependency on the custom gear-tech/polkadot-sdk stable2409 fork and using upstream paritytech/polkadot-sdk instead.

  • switches workspace Polkadot SDK dependencies to paritytech/polkadot-sdk rev 298f676c91d64f15f38ea7fd78f125c5889ab09c
  • keeps Gear-specific fork deltas repo-local under substrate/: runtime executor, allocator, wasm interface common, and substrate wasm builder
  • patches local sc-executor, sc-executor-common, sc-executor-polkavm, sc-executor-wasmtime, and substrate-wasm-builder over upstream package identities
  • keeps publish-time crates.io rewrites separate from local smoke checks, including sandbox publish handling for the unpublished local sc-executor host-api edge
  • uses upstream-compatible dependency features for wasmtime 8.0.1 (default-features = false), matching canonical SDK expectations
  • refreshes vara/sdk/gsdk/vara_runtime.scale; upstream staking adds withdraw_overstake, so RuntimeCall metadata changes
  • keeps the temporary POLKADOT_UPSTREAM_2409_PROOF.md note out of the PR/main branch

Migration / deletion notes

  • Migrated: Polkadot SDK dependency source, local executor crates, wasm builder, allocator, wasm interface common, sandbox host-api glue, gsdk runtime metadata, and crates.io publish rewrites.
  • Moved: copied SDK crates now live under substrate/ without package renames or broad extra churn.
  • Deleted/pruned from the proof branch: temporary proof markdown, stale copied SDK license bulk where replaced by the shared notice, unused finality-grandpa proof copy, and unused wasmi executor wiring.
  • Not migrated: staking pallet fork code and nomination-pools fork-only try-state guards. Current evidence does not require a runtime storage migration.

Validation

  • rtk cargo fmt --check
  • rtk git diff --check
  • rtk cargo metadata --no-deps --format-version 1
  • rtk make workspace-hack
  • rtk make clippy
  • rtk cargo +stable clippy -p crates-io --all-targets --all-features -- -D warnings
  • rtk cargo +stable run --release -p crates-io publish --simulate --registry-path /tmp/cargo-http-registry
  • rtk ./scripts/gear.sh clippy gear --all-targets --all-features --locked
  • rtk cargo nextest run --profile ci -p sc-executor-wasmtime --all-targets --all-features test_stack_depth_reaching
  • rtk cargo nextest run --profile ci -p gsdk --all-targets --all-features set_code_succeed
  • failed gsdk CI tests re-run one by one under the CI profile: set_code_succeed, alloc_zero_pages, harmless_upload, set_code_failed, program_migration_fails_if_program_exists, program_with_gas_reservation_migrated_to_another_node, get_mailbox, program_migrated_to_another_node, memory_dump

Notes

  • Separate gear-service --features vara-native check was intentionally skipped.
  • Prior CI evidence showed build / try-runtime (debug) green on the Vara snapshot; no storage migration is indicated unless try-runtime regresses on the updated head.

Comment thread protocol/binary-merkle-tree/Cargo.toml Outdated
@ukint-vs ukint-vs force-pushed the vs/polkadot-upstream-2409-proof branch from 8c183d5 to 819d69e Compare May 19, 2026 07:40
@ukint-vs ukint-vs self-assigned this May 19, 2026
@ukint-vs ukint-vs force-pushed the vs/polkadot-upstream-2409-proof branch 2 times, most recently from 43c64a8 to 197ce22 Compare May 19, 2026 08:46
@ukint-vs ukint-vs force-pushed the vs/polkadot-upstream-2409-proof branch from 197ce22 to 6c85944 Compare May 19, 2026 08:57
@breathx breathx changed the title Migrate polkadot-sdk proof to upstream stable2409 refactor(vara): migrate polkadot-sdk to upstream stable2409 May 19, 2026
@ukint-vs ukint-vs marked this pull request as ready for review May 20, 2026 17:06
@ukint-vs ukint-vs added type: feat New functionality or user-visible improvement scope: vara Vara Network (Layer 1) priority: important High priority, should be addressed soon size: L Large task (several days) ai-friendly Suitable for AI-assisted implementation or review codex labels May 20, 2026
@gemini-code-assist
Copy link
Copy Markdown
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request migrates the Gear project's dependency on the custom gear-tech/polkadot-sdk fork to the upstream paritytech/polkadot-sdk (stable2409). The migration involves moving necessary fork deltas into the local substrate/ directory, updating workspace configurations, and ensuring compatibility with upstream package identities. This change reduces technical debt by aligning with the upstream SDK while maintaining necessary Gear-specific modifications.

Highlights

  • Dependency Migration: Migrated from the custom gear-tech/polkadot-sdk fork to the upstream paritytech/polkadot-sdk (stable2409, rev 298f676c).
  • Repository Restructuring: Moved Gear-specific fork deltas (executor, allocator, wasm interface, wasm builder) into the substrate/ directory.
  • Build System Updates: Updated Cargo.toml and hakari.toml to support the new upstream SDK structure and local crate overrides.
  • Runtime Metadata: Refreshed vara_runtime.scale metadata to account for upstream staking pallet changes.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/check.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize the Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counterproductive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request migrates Substrate-based dependencies from the Gear fork to the upstream paritytech/polkadot-sdk repository. It introduces several local crates in the substrate/ directory to house modified or copied logic from the SDK, including the runtime executor and WASM builder. The changes also involve extensive updates to Cargo.toml and Cargo.lock, refinement of build scripts, and adjustments to example projects. Review feedback points out an unnecessary deprecation attribute in the new executor code and a redundant manifest patch for the now-removed wasmi 0.13.2 dependency.

Comment thread substrate/runtime-executor/wasmtime/src/runtime.rs Outdated
Comment thread utils/crates-io/src/manifest.rs Outdated
@ukint-vs
Copy link
Copy Markdown
Member Author

@claude review

@ukint-vs
Copy link
Copy Markdown
Member Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request transitions the workspace's Polkadot SDK dependencies from the custom gear-tech fork to the upstream paritytech repository (revision 298f676c91d64f15f38ea7fd78f125c5889ab09c). To isolate the remaining fork delta, several Polkadot SDK crates (such as sc-executor, sp-allocator, and substrate-wasm-builder) have been copied locally into the substrate/ directory, and the workspace publishing utilities have been updated to handle these Gear-maintained aliases. Feedback on the changes highlights three correctness issues: a potential integer overflow in the allocator's bump function that could lead to memory corruption, a path-escaping issue on Windows when writing Wasmtime cache configurations to TOML, and an incorrect directory-removal call on files during local registry cleanup.

Comment thread substrate/sp-allocator/src/freeing_bump.rs
Comment thread substrate/runtime-executor/wasmtime/src/runtime.rs
Comment thread utils/crates-io/src/simulator.rs
@ukint-vs
Copy link
Copy Markdown
Member Author

ukint-vs commented Jun 1, 2026

@claude review

@claude
Copy link
Copy Markdown

claude Bot commented Jun 1, 2026

Claude finished @ukint-vs's task in 5m 11s —— View job


Code Review

  • Gather context and understand PR scope
  • Review new substrate/ crates (allocator, executor, wasm-builder)
  • Review Gemini-flagged issues (allocator overflow, Windows path, remove_dir_all)
  • Review remaining changed files (scripts, wasm-proc, crates-io, wasm-project)
  • Post final review findings

Gemini May-29 findings — all three are already resolved in the current code:

  • Allocator overflow (substrate/sp-allocator/src/freeing_bump.rs:507): The if required_size > u64::from(u32::MAX) guard is present before the cast, so the overflow path Gemini described cannot be reached.

  • Windows TOML path escaping (substrate/runtime-executor/wasmtime/src/runtime.rs:218-240): toml_basic_string() already handles \\\\\\ in a char-by-char match, and a dedicated unit test at line 247 verifies the exact Windows-backslash-and-quote case.

  • remove_dir_all on files (utils/crates-io/src/simulator.rs:122-126): The code checks entry.file_type()?.is_dir() and dispatches to fs::remove_file for non-directories. A test at line 152 covers both dir and file entries.

No action needed on any of these.


medium: sc-executor workspace patch survives into the publish manifest

patch_publish_workspace iterates GEAR_SUBSTRATE_DEPENDENCIES to strip local-path entries from [patch."https://github.com/paritytech/polkadot-sdk.git"]. Since sc-executor (the parent crate at substrate/runtime-executor) is intentionally excluded from that list, its sc-executor = { path = "substrate/runtime-executor" } patch entry is left in the generated publish-workspace manifest.

Any published Gear crate that transitively depends on sc-executor via the workspace would chain through the git dep → local-path patch, and cargo package would fail with a path-dependency error. The simulation currently passes because no published Gear package in PACKAGES/SAFE_DEPENDENCIES/STACKED_DEPENDENCIES pulls in sc-executor, and gear-sandbox-interface's patch explicitly strips its sc-executor dependency.

This is fine now, but the invariant — that no published Gear crate may transitively reach sc-executor — is invisible and not enforced anywhere. Adding a comment in patch_publish_workspace explaining that sc-executor is deliberately excluded because it's not in the publish set (and no published crate may depend on it) would prevent a future regression when the publish graph grows.

Fix this →


low: no_std_clippy hardcodes sc-executor exclusion (same as prior review)

scripts/src/clippy.sh:45 excludes sc-executor by name. This remains correct because sc-executor is the only new substrate crate that declares a std feature — the sub-crates (sc-executor-common, sc-executor-wasmtime, sc-executor-polkavm) have no std feature in their [features] table, so they're invisible to the select(.features | index("std")) filter. No change needed now, but the comment from the prior review still stands: if a std feature is ever added to another executor sub-crate, it would silently enter the no_std job and likely fail.


Confirmed correct — worth calling out:

  • prepare_publish / check refactor (publisher.rs): check correctly changed from self to &self so the caller can still call restore() after a failed check. The simulator.clear_cache() call before each package publish in the simulation loop correctly evicts stale cached packages from the local registry before the next cargo publish run.

  • add_owner now uses crates_io_name(name) (publisher.rs:224): The prior code would have called cargo owner --add with the local name (sc-executor-wasmtime) instead of the crates.io alias (gsc-executor-wasmtime). The fix is correct.

  • patch_workspace_alias / rename_aliases split: complete() now calls rename_aliases() (aliases only) and rename() (full workspace rename, including substrate fork patches) is deferred to prepare_publish(). This correctly separates the "version-pinning" phase from the "publish manifest rewrite" phase, so build-only callers don't need to run publish-specific rewrites.

  • sp-wasm-interface version pin in substrate::patch_workspace: The comment "stable2409 executor crates require the upstream 21.0.1 API" with removal of the old gp-wasm-interface alias correctly transitions from the Gear-published gp-wasm-interface 15.0.0 to upstream sp-wasm-interface 21.0.1 for all non-sandbox-interface crates.

  • sandbox_interface::patch dual-version handling: Stripping sc-executor from deps, host-api from defaults, and pinning sp-wasm-interface to gp-wasm-interface 15.0.0 is the right approach since gear-sandbox-interface is still paired with the old Gear runtime-interface stack. The comment explains the version mismatch.

  • remove_local_path_patches doc comment (addressed in 203b2d8): The explanation that sub-projects can't resolve workspace-relative paths is present and clear.

@ukint-vs
Copy link
Copy Markdown
Member Author

ukint-vs commented Jun 3, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request brings several Polkadot SDK crates locally into the workspace under the substrate/ directory to isolate fork deltas, updating Cargo.toml, Cargo.lock, and hakari configurations to patch these dependencies. It also adapts the WASM builder, optimizer, and processor to support these changes, alongside updates to helper scripts and third-party notices. The review identified several issues: an unstable let-chains syntax in wasm-proc that will fail compilation; an unused variable allow_undefined in wasm-optimizer that triggers a warning under -D warnings; an incorrect jq object query in clippy.sh; a type improvement for TOML tables in wasm-builder; and an inconsistency in THIRD_PARTY_NOTICES.md regarding the publishing status of sc-executor.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread sdk/wasm-proc/src/main.rs
Comment on lines +186 to +189
if let Payload::CustomSection(section) =
payload.map_err(|e| format!("Deserialization error: {e}"))?
&& section.name() == expected_section
{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The if let ... && ... syntax (let-chains) is an unstable Rust feature (RFC 2497). Unless #![feature(let_chains)] is explicitly enabled at the crate root, this will fail to compile on both stable and nightly compilers. It is safer and more compatible to use a nested if block instead.

        if let Payload::CustomSection(section) =
            payload.map_err(|e| format!("Deserialization error: {e}"))?
        {
            if section.name() == expected_section {
                return Ok(true);
            }
        }

Comment on lines 28 to +30
let allow_undefined = rustc_version.major == 1 && rustc_version.minor >= 96;

let mut rustc_flags = vec!["-Clink-arg=--import-memory"];
let mut rustc_flags = vec!["-Clink-arg=--import-memory", "-Clink-arg=--allow-undefined"];
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The allow_undefined variable is defined here but is never used because "-Clink-arg=--allow-undefined" was unconditionally added to rustc_flags on line 30. This will trigger an unused_variable warning, which will cause compilation to fail under -D warnings settings. Consider either conditionally adding the flag using allow_undefined or removing the unused variable.

        let allow_undefined = rustc_version.major == 1 && rustc_version.minor >= 96;
 
        let mut rustc_flags = vec!["-Clink-arg=--import-memory"];
        if allow_undefined {
            rustc_flags.push("-Clink-arg=--allow-undefined");
        }

Comment thread scripts/src/clippy.sh
mapfile -t no_std < <(
cargo metadata --no-deps --format-version=1 |
jq -r '.packages.[] | select(.features | index("std")) | "-p=" + .name'
jq -r '.workspace_members as $members | .packages.[] | . as $pkg | select($members | index($pkg.id)) | select(.features | index("std")) | select(.name != "sc-executor") | "-p=" + .name'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

In jq, .features is an object (map) representing the package's features. Using index("std") on an object is not standard and can lead to errors or unexpected behavior depending on the jq version. Using has("std") is the idiomatic and robust way to check for the presence of a key in a jq object.

Suggested change
jq -r '.workspace_members as $members | .packages.[] | . as $pkg | select($members | index($pkg.id)) | select(.features | index("std")) | select(.name != "sc-executor") | "-p=" + .name'
jq -r '.workspace_members as $members | .packages.[] | . as $pkg | select($members | index($pkg.id)) | select(.features | has("std")) | select(.name != "sc-executor") | "-p=" + .name'

///
/// The sub-project is written outside the workspace root, so workspace-relative
/// patch paths like local `substrate/` overrides cannot be resolved there.
fn remove_local_path_patches(patch: &mut BTreeMap<String, toml::Value>) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The remove_local_path_patches function currently takes &mut BTreeMap<String, toml::Value>. However, toml::value::Table (which is already imported as Table on line 16) is the canonical type for TOML tables and is defined as toml::map::Map in newer versions of the toml crate. Using &mut Table is more robust and avoids potential type mismatches if the underlying representation of Table changes.

Suggested change
fn remove_local_path_patches(patch: &mut BTreeMap<String, toml::Value>) {
fn remove_local_path_patches(patch: &mut Table) {

Comment thread THIRD_PARTY_NOTICES.md
- `substrate/runtime-executor/common` (`sc-executor-common`, published by Gear as `gsc-executor-common`)
- `substrate/runtime-executor/polkavm` (`sc-executor-polkavm`, published by Gear as `gsc-executor-polkavm`)
- `substrate/runtime-executor/wasmtime` (`sc-executor-wasmtime`, published by Gear as `gsc-executor-wasmtime`)
- `substrate/runtime-executor` (`sc-executor`, published by Gear as `gsc-executor`)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There is an inconsistency regarding the sc-executor crate. This file states that sc-executor is published by Gear as gsc-executor. However, substrate/README.md states that sc-executor is not published by Gear, and it is indeed excluded from GEAR_SUBSTRATE_DEPENDENCIES in utils/crates-io/src/lib.rs. Please update this notice to correctly reflect that sc-executor is not published.

Suggested change
- `substrate/runtime-executor` (`sc-executor`, published by Gear as `gsc-executor`)
- substrate/runtime-executor (sc-executor, not published by Gear)

@ukint-vs
Copy link
Copy Markdown
Member Author

ukint-vs commented Jun 3, 2026

@claude opus review

@claude
Copy link
Copy Markdown

claude Bot commented Jun 3, 2026

Claude finished @ukint-vs's task in 5m 12s —— View job


Code Review (Opus)

  • Gather context (diff vs origin/master, new substrate crates)
  • Review substrate/ executor + allocator + wasm-builder
  • Review scripts, wasm-proc, wasm-optimizer, crates-io
  • Verify Gemini June-03 findings status
  • Post final review

Focus is on the latest Gemini batch (June-03) plus anything new since the prior Opus reviews. I verified each Gemini point against the current code rather than taking it at face value — two of the five don't hold up, three are real (one is more serious than Gemini rated it).


medium — no_std_clippy's index("std") filter selects nothing; the sc-executor exclusion is therefore moot

File: scripts/src/clippy.sh line 45

jq -r '... | select(.features | index("std")) | select(.name != "sc-executor") | ...'

Gemini flagged index vs has as a style nit. It's actually functional. .features in cargo metadata is an object ({"std": [...], "default": [...]}), and index(s) only does membership on arrays/strings — on an object it returns null. I verified locally:

$ echo '{"name":"x","features":{"std":[],"default":["std"]}}' | jq -rc 'select(.features|index("std"))|.name'
            # (no output — selected nothing)
$ echo '{"features":{"std":[]}}' | jq -rc 'select(.features|has("std"))|"match"'
match

So select(.features | index("std")) evaluates falsy for every package and no_std ends up empty — cargo clippy "${no_std[@]}" … then runs with no -p targets. Note this index("std") predicate predates the PR (it's unchanged from master), so the no_std job may have been a partial no-op for a while; the change here only adds select(.name != "sc-executor") on top, which can never match anything while the upstream filter selects nothing. Worth fixing both together with has("std") and confirming in CI that the resolved -p= list is actually non-empty (and contains the intended substrate/ crates). If the CI runner's jq version happens to behave differently for index on objects, that itself is an argument for the portable has().

Fix this →


low — duplicate --allow-undefined once Rust reaches 1.96; the conditional block is now dead/redundant

File: sdk/wasm-optimizer/src/cargo_command.rs lines 28–51

The PR made --allow-undefined unconditional:

let mut rustc_flags = vec!["-Clink-arg=--import-memory", "-Clink-arg=--allow-undefined"]; // line 30 (added here)
...
if allow_undefined {                       // lines 45–51 (from master, #5533)
    rustc_flags.extend_from_slice(&["-C", "link-arg=--allow-undefined"]);
}

On the pinned nightly (minor < 96) allow_undefined is false, so the flag is added once and there's no unused_variable warning — i.e. Gemini's "high: unused variable" no longer applies. But the two changes (this PR's unconditional add + master's #5533 conditional add) collided in the merge: once the toolchain hits 1.96 the linker will receive --allow-undefined twice. lld tolerates the duplicate, so this isn't urgent, but the conditional block plus the allow_undefined gate are now redundant. Cleanest is to drop the if allow_undefined { … } block and the allow_undefined binding now that the flag is unconditional (or revert line 30 and keep only the gate) so the intent is unambiguous.

Fix this →


low — THIRD_PARTY_NOTICES.md says sc-executor is published as gsc-executor, contradicting the other two sources of truth

File: THIRD_PARTY_NOTICES.md line 11

- `substrate/runtime-executor` (`sc-executor`, published by Gear as `gsc-executor`)

But substrate/README.md lists substrate/runtime-executor"not published by Gear", and GEAR_SUBSTRATE_DEPENDENCIES in utils/crates-io/src/lib.rs:51 deliberately omits sc-executor (it has sc-executor-common/-polkavm/-wasmtime but not the parent). The prior Opus review (June-01) called out exactly this invariant — no published Gear crate may transitively reach sc-executor. The notice should match: sc-executor is not published.

Fix this →


Gemini June-03 findings I checked and would not act on

  • "critical: let-chains in wasm-proc/src/main.rs:189 won't compile"invalid. The crate is edition = "2024" (sdk/wasm-proc/Cargo.tomledition.workspace = true → workspace edition = "2024") and the toolchain is nightly-2025-10-20; let-chains (RFC 2497) are stable on edition 2024 since Rust 1.88. The if let … && … form compiles as-is — no nested if needed. (CI building this crate confirms it.)

  • "medium: use &mut Table instead of &mut BTreeMap<String, toml::Value> in wasm_project.rs:24" — cosmetic only. toml::value::Table is already imported, and it's an alias for BTreeMap<String, Value> with this crate's features, so the code compiles and behaves identically. Fine to switch for readability, but it's not a correctness issue and there's nothing to verify.


Confirmed-correct items from this batch

  • Allocator overflow guard (substrate/sp-allocator/src/freeing_bump.rs): the required_size > u64::from(u32::MAX) check is present before the u32 cast — the wraparound Gemini described on May-29 cannot occur. ✓
  • Windows TOML path escaping (runtime-executor/wasmtime/src/runtime.rs): handled by toml_basic_string() with a dedicated backslash/quote unit test. ✓
  • remove_dir_all on files (crates-io/src/simulator.rs): dispatches on file_type()?.is_dir() with test coverage for both. ✓

Net: three small fixes worth folding in (clippy has, the duplicated linker flag, the notices line); the two remaining Gemini items don't require changes. Nothing here blocks the migration — the substrate-fork isolation, patch wiring, and publish-rewrite logic all still look sound, consistent with the two prior Opus passes.
· branch vs/polkadot-upstream-2409-proof

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-friendly Suitable for AI-assisted implementation or review scope: vara Vara Network (Layer 1) type: feat New functionality or user-visible improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants