Found by a review pass over feat/rework-manager-api.
1. The schema parity test compares names only
implementation/src/manager/run_test.rs (request_schema_matches_the_rust_struct) destructures Request and diffs the field-name set against manager-api.yaml. That is real protection against field-name drift, but the test's comments read as though the schema is verified, and it does not check types, required, defaults, enum members, nested unsafe_overrides, or the MessageAllocationNode shape.
The gap already bites: manager-api.yaml describes wire values the decoder rejects.
:645, :671, :732 — a client following the schema calldata-encodes an address as a string, or chain_id / value / a bucket total as "1". Rust expects a calldata Address and numeric BigInt tags (crates/modules-interfaces/src/abi_stub.rs:51), so decoding fails with malformed_frame.
- The in-tree client gets it right (
tests/system/manager-socket/test.py:26 uses Address(...) and integers), which is why nothing caught it.
Either extend the test to types/required/enums, or narrow the comments to what it actually guarantees — the first is preferable.
2. Routed integration cases pin runner hashes with no refresh path
executors/v0.3.x/tests/integration/misc/routed_call/routed_call_to.py:1, tests/system/cross-major/test.py:27.
A contract reached through a nested call runs at debug_mode: Disabled, so the py-genlayer:test alias cannot resolve and the runner must be named by content hash. The current pins are correct.
But hash-updater.py updates runner metadata, not these literals, and an old hash can stay valid in all.json after a refresh. The routed case would then silently keep exercising an obsolete runner instead of failing.
Suggested fix: have test preparation read the selected executor's built data/latest.json and inject the content hash into the generated contract source. That keeps debug_mode: Disabled and content-addressing without hardcoded literals.
Found by a review pass over
feat/rework-manager-api.1. The schema parity test compares names only
implementation/src/manager/run_test.rs(request_schema_matches_the_rust_struct) destructuresRequestand diffs the field-name set againstmanager-api.yaml. That is real protection against field-name drift, but the test's comments read as though the schema is verified, and it does not check types,required, defaults, enum members, nestedunsafe_overrides, or theMessageAllocationNodeshape.The gap already bites:
manager-api.yamldescribes wire values the decoder rejects.:645,:671,:732— a client following the schema calldata-encodes an address as a string, orchain_id/value/ a bucket total as"1". Rust expects a calldataAddressand numericBigInttags (crates/modules-interfaces/src/abi_stub.rs:51), so decoding fails withmalformed_frame.tests/system/manager-socket/test.py:26usesAddress(...)and integers), which is why nothing caught it.Either extend the test to types/required/enums, or narrow the comments to what it actually guarantees — the first is preferable.
2. Routed integration cases pin runner hashes with no refresh path
executors/v0.3.x/tests/integration/misc/routed_call/routed_call_to.py:1,tests/system/cross-major/test.py:27.A contract reached through a nested call runs at
debug_mode: Disabled, so thepy-genlayer:testalias cannot resolve and the runner must be named by content hash. The current pins are correct.But
hash-updater.pyupdates runner metadata, not these literals, and an old hash can stay valid inall.jsonafter a refresh. The routed case would then silently keep exercising an obsolete runner instead of failing.Suggested fix: have test preparation read the selected executor's built
data/latest.jsonand inject the content hash into the generated contract source. That keepsdebug_mode: Disabledand content-addressing without hardcoded literals.