Successor to the delivered M3 epics #386, #391 and #394. These four are the residual review follow-ups.
Four follow-ups close M3 against origin/dev/m1@aec462a, verified after the M4 car block and #562 landed. Three M3 epics (#386, #391, #394) are delivered on the tree and close immediately.
The M5 three-repo split is redone after these land, so the "must settle before the carve" framing in #540, #543 and #544 no longer sets the clock. The reason to do them now is file overlap with each other, not the cleave.
Order
Wave 1, in parallel: #544 (relocate and rename the one-poll driver), #521 (scope the no_std claim to derive hygiene and prove the probe round-trip).
Wave 2, alone: #540 (retire the sweep vocabulary).
Wave 3, alone: #543 (bind Venue::ID to the adapter manifest name).
#544 and #540 rewrite the same seam. #544 edits crates/composable-cow/src/sweep.rs, crates/videre-sdk/src/keeper.rs and crates/videre-sdk/src/lib.rs; #540 renames the first and rewrites the other two. They do not parallelize. #544 goes first because it is mechanical and #540 is a rename over already-moved code.
Scope corrections verified at the tip
#544: the call sites are ten, not six. The M4 merges added three call-bearing files (crates/composable-cow/src/sweep.rs:138, modules/ethflow-watcher/src/strategy.rs:214, modules/examples/stop-loss/src/strategy.rs:91). The maintainer's Retrier decision applies to the composable-cow arm only; stop-loss hand-rolls its journal through host.set and has no Retrier, so its suspension arm needs a separate answer or an explicit carve-out. crates/videre-macros carries no keeper-vocabulary symbols, so #544 is the only issue of the four that touches the macro crate's emission path.
#540: the word sweep is also a Cargo feature (crates/composable-cow/Cargo.toml:33), a test-target name (:40), the module gate and re-export (crates/composable-cow/src/lib.rs:14,19,20), and a declared feature in a downstream manifest (modules/twap-monitor/Cargo.toml:12). Retiring the vocabulary edits three Cargo manifests and changes the public feature name of an L3 crate. Two exclusions: nexum-runtime's supervisor restart sweep is a different sweep and stays; docs/adr/0013 records an accepted decision and stays. The body's claim of a free run() in videre-sdk is wrong: the free run() is composable_cow::run, defined at crates/composable-cow/src/sweep.rs:40 and re-exported at lib.rs:20, so the rename produces run::run alongside Keeper::run.
#543: the maintainer's macro-generated-const decision is not implementable as written. #[videre_sdk::venue] is applied at crates/cow-venue/src/adapter.rs:473 under #[cfg_attr(target_arch = "wasm32", videre_sdk::venue)], so it does not run on host builds, and it sits in the adapter feature slice while CowVenue::ID sits in the client slice at crates/cow-venue/src/client.rs:26. A keeper links client and must never link adapter. The generated const is therefore invisible to every consumer that needs it. The manifest-selection worry in the earlier triage is moot: derive_venue_world at crates/videre-macros/src/lib.rs:218 opens a hardcoded module.toml and never reads module.load.toml or module.sepolia.toml. Settle the emission seam before implementation starts.
#521: option 1 is infeasible. crates/videre-sdk/src/client.rs:14-17 uses std::borrow::Cow, std::fmt, std::future::Future and std::marker::PhantomData, crates/videre-sdk/src/body.rs spells bare Vec off the std prelude, and the crate depends on nexum-sdk's wasi:http path. The blocker is not the export glue: crates/videre-sdk/src/adapter.rs:64-115 is a hand-written macro_rules!, so its ::std::vec::Vec spellings are a one-line-per-signature edit. Take the Alternative the body already offers: state the claim as derive hygiene only, and add the encode/decode round-trip to crates/no-std-probe. Nothing builds a bare-metal triple today and no consumer wants one.
Acceptance
No rt module in videre-sdk, poll_once returning Poll<F::Output> beside the VenueTransport seam, doc citing videre:venue/client@0.1.0.
No Sweep, SweepReport, Keeper::sweep or ConditionalSource symbols, and no sweep Cargo feature or test target.
A venue id cannot be hand-typed out of agreement with the manifest it registers under, by whatever seam survives the design pass.
The no_std claim is scoped to derive hygiene in prose, and no-std-probe exercises a round-trip rather than expansion alone.
Binding decisions, 2026-07-23
These settle the open design questions in the scope corrections above.
Cross-milestone order: M4's #538 and the detached next_poll_timestamp sliver land first, so crates/composable-cow/src/sweep.rs is edited under its current name before #540 renames it. M3's waves follow that, not the reverse.
#540 takes the full rename, module and Cargo feature included. sweep.rs becomes run.rs, the module re-export becomes run, and composable_cow::run::run alongside Keeper::run is accepted rather than worked around. The composable-cow Cargo feature sweep becomes run, and modules/twap-monitor/Cargo.toml follows the feature rename. nexum-runtime's supervisor restart sweep and docs/adr/0013 are untouched.
#543 takes an explicit id argument that the macro verifies, and is no longer design-blocked. #[videre_sdk::venue(id = "cow", body = CowIntentBody)] sits on the Venue impl in client.rs, expands on host and wasm regardless of feature slice, reads $CARGO_MANIFEST_DIR/module.toml at expansion and emits compile_error! when the id disagrees with [module] name. This mirrors sol!, which takes an explicit user argument and resolves a CARGO_MANIFEST_DIR-relative path at expansion, and our own module and keeper macros, which already read module.toml that way. The id stays greppable at the definition site, the manifest is checked rather than made authoritative, and the seam must stay opt-in so videre-sdk/tests/adapter.rs keeps compiling with hand-typed ids.
#544's stop-loss concern dissolves. modules/examples/stop-loss is being deleted, subsumed into the generic ComposableCoW monitor, so the stop-loss/src/strategy.rs:91 call site and the hand-rolled-journal carve-out both go with it. That drops #544's live call sites and removes the worst collision seam the M3 and M4 waves shared.
Four follow-ups close M3 against
origin/dev/m1@aec462a, verified after the M4 car block and #562 landed. Three M3 epics (#386, #391, #394) are delivered on the tree and close immediately.The M5 three-repo split is redone after these land, so the "must settle before the carve" framing in #540, #543 and #544 no longer sets the clock. The reason to do them now is file overlap with each other, not the cleave.
Order
Wave 1, in parallel: #544 (relocate and rename the one-poll driver), #521 (scope the no_std claim to derive hygiene and prove the probe round-trip).
Wave 2, alone: #540 (retire the sweep vocabulary).
Wave 3, alone: #543 (bind
Venue::IDto the adapter manifest name).#544 and #540 rewrite the same seam. #544 edits
crates/composable-cow/src/sweep.rs,crates/videre-sdk/src/keeper.rsandcrates/videre-sdk/src/lib.rs; #540 renames the first and rewrites the other two. They do not parallelize. #544 goes first because it is mechanical and #540 is a rename over already-moved code.Scope corrections verified at the tip
#544: the call sites are ten, not six. The M4 merges added three call-bearing files (
crates/composable-cow/src/sweep.rs:138,modules/ethflow-watcher/src/strategy.rs:214,modules/examples/stop-loss/src/strategy.rs:91). The maintainer'sRetrierdecision applies to the composable-cow arm only;stop-losshand-rolls its journal throughhost.setand has noRetrier, so its suspension arm needs a separate answer or an explicit carve-out.crates/videre-macroscarries no keeper-vocabulary symbols, so #544 is the only issue of the four that touches the macro crate's emission path.#540: the word
sweepis also a Cargo feature (crates/composable-cow/Cargo.toml:33), a test-target name (:40), the module gate and re-export (crates/composable-cow/src/lib.rs:14,19,20), and a declared feature in a downstream manifest (modules/twap-monitor/Cargo.toml:12). Retiring the vocabulary edits three Cargo manifests and changes the public feature name of an L3 crate. Two exclusions:nexum-runtime's supervisor restart sweep is a different sweep and stays;docs/adr/0013records an accepted decision and stays. The body's claim of a freerun()in videre-sdk is wrong: the freerun()iscomposable_cow::run, defined atcrates/composable-cow/src/sweep.rs:40and re-exported atlib.rs:20, so the rename producesrun::runalongsideKeeper::run.#543: the maintainer's macro-generated-const decision is not implementable as written.
#[videre_sdk::venue]is applied atcrates/cow-venue/src/adapter.rs:473under#[cfg_attr(target_arch = "wasm32", videre_sdk::venue)], so it does not run on host builds, and it sits in theadapterfeature slice whileCowVenue::IDsits in theclientslice atcrates/cow-venue/src/client.rs:26. A keeper linksclientand must never linkadapter. The generated const is therefore invisible to every consumer that needs it. The manifest-selection worry in the earlier triage is moot:derive_venue_worldatcrates/videre-macros/src/lib.rs:218opens a hardcodedmodule.tomland never readsmodule.load.tomlormodule.sepolia.toml. Settle the emission seam before implementation starts.#521: option 1 is infeasible.
crates/videre-sdk/src/client.rs:14-17usesstd::borrow::Cow,std::fmt,std::future::Futureandstd::marker::PhantomData,crates/videre-sdk/src/body.rsspells bareVecoff the std prelude, and the crate depends on nexum-sdk's wasi:http path. The blocker is not the export glue:crates/videre-sdk/src/adapter.rs:64-115is a hand-writtenmacro_rules!, so its::std::vec::Vecspellings are a one-line-per-signature edit. Take the Alternative the body already offers: state the claim as derive hygiene only, and add the encode/decode round-trip tocrates/no-std-probe. Nothing builds a bare-metal triple today and no consumer wants one.Acceptance
No
rtmodule in videre-sdk,poll_oncereturningPoll<F::Output>beside theVenueTransportseam, doc citingvidere:venue/client@0.1.0.No
Sweep,SweepReport,Keeper::sweeporConditionalSourcesymbols, and nosweepCargo feature or test target.A venue id cannot be hand-typed out of agreement with the manifest it registers under, by whatever seam survives the design pass.
The no_std claim is scoped to derive hygiene in prose, and
no-std-probeexercises a round-trip rather than expansion alone.Binding decisions, 2026-07-23
These settle the open design questions in the scope corrections above.
Cross-milestone order: M4's #538 and the detached
next_poll_timestampsliver land first, socrates/composable-cow/src/sweep.rsis edited under its current name before #540 renames it. M3's waves follow that, not the reverse.#540 takes the full rename, module and Cargo feature included.
sweep.rsbecomesrun.rs, the module re-export becomesrun, andcomposable_cow::run::runalongsideKeeper::runis accepted rather than worked around. Thecomposable-cowCargo featuresweepbecomesrun, andmodules/twap-monitor/Cargo.tomlfollows the feature rename.nexum-runtime's supervisor restart sweep anddocs/adr/0013are untouched.#543 takes an explicit id argument that the macro verifies, and is no longer design-blocked.
#[videre_sdk::venue(id = "cow", body = CowIntentBody)]sits on theVenueimpl inclient.rs, expands on host and wasm regardless of feature slice, reads$CARGO_MANIFEST_DIR/module.tomlat expansion and emitscompile_error!when the id disagrees with[module] name. This mirrorssol!, which takes an explicit user argument and resolves aCARGO_MANIFEST_DIR-relative path at expansion, and our own module and keeper macros, which already readmodule.tomlthat way. The id stays greppable at the definition site, the manifest is checked rather than made authoritative, and the seam must stay opt-in sovidere-sdk/tests/adapter.rskeeps compiling with hand-typed ids.#544's stop-loss concern dissolves.
modules/examples/stop-lossis being deleted, subsumed into the generic ComposableCoW monitor, so thestop-loss/src/strategy.rs:91call site and the hand-rolled-journal carve-out both go with it. That drops #544's live call sites and removes the worst collision seam the M3 and M4 waves shared.