From 32a1b9f22f13c70fddb7777c811cb10db35ca88d Mon Sep 17 00:00:00 2001 From: mfw78 Date: Mon, 27 Jul 2026 00:58:44 +0000 Subject: [PATCH] refactor(packaging): reorganize into three-grouping path-dep workspace Move all workspace members into nexum/ (L1), videre/ (L2) and shepherd/ (L3) repo-root dirs as a single cargo workspace with intra-grouping path-deps, so the tree keeps building as one unit with a shared Cargo.lock right up to the physical carve (#407). This is the refactor-now-cut-later step of the gated three-repo split (M5). Add the carve-groups dep-sync gate (scripts/check-carve-groups.sh, CI job, justfile recipe) enforcing the acyclic nexum <- videre <- shepherd invariant from the physical layout, so no upward edge can become a circular repo dependency at the carve. Document the transitional cross-repo dependency medium (path-deps -> git-tag pins -> crates.io) in docs/design/carve-workspace.md. WIT stays in a single root wit/, resolved via the manifest-dir ancestor walk; the per-group wit/ + wit/deps split is deferred to the wit-deps flip (#404/#405). The hardcoded wit_bindgen::generate! path-lists were re-based one level deeper by the move. Align the justfile with the already-optimized CI: test/test-e2e/ci use cargo nextest run, ci runs doctests separately and appends -D warnings to RUSTFLAGS/RUSTDOCFLAGS instead of clobbering the devshell mold flags. sccache is already wired via the flake devshell and the CI workflow env. Fix the test workspace-root locators the move broke: replace every hardcoded CARGO_MANIFEST_DIR.parent().parent() (valid only at the old crates/ depth) with a workspace_root() that walks to the topmost ancestor carrying a Cargo.toml, and group-prefix the module manifests those e2e tests load. These had silently skipped locally (no CI env) into a hollow green; CI's fail-loud path caught them. Re-validated with CI=1. Closes #403. --- .github/workflows/ci.yml | 12 ++++ Cargo.toml | 70 +++++++++--------- Dockerfile | 12 ++-- README.md | 14 ++-- docs/00-overview.md | 4 +- docs/01-runtime-environment.md | 2 +- docs/02-modules-events-packaging.md | 4 +- docs/03-module-discovery.md | 2 +- docs/05-sdk-design.md | 12 ++-- docs/06-production-hardening.md | 4 +- docs/07-rpc-namespace-design.md | 2 +- docs/08-platform-generalisation.md | 2 +- ...01-engine-toml-separate-from-nexum-toml.md | 2 +- docs/adr/0009-host-trait-surface.md | 2 +- .../0013-composable-cow-structured-poll.md | 2 +- docs/deployment.md | 6 +- docs/deployment/multi-chain.md | 4 +- docs/design/carve-workspace.md | 47 ++++++++++++ docs/diagrams/diagrams.md | 2 +- docs/operations/load-testnet-runbook.md | 12 ++-- docs/operations/m2-testnet-runbook.md | 4 +- docs/operations/m3-testnet-runbook.md | 2 +- docs/sdk.md | 6 +- docs/testing-runtime-harness.md | 4 +- docs/tutorial-first-module.md | 16 ++--- engine.e2e.toml | 18 ++--- engine.example.toml | 2 +- engine.load.toml | 6 +- engine.m2.toml | 6 +- engine.m3.toml | 6 +- engine.soak.toml | 10 +-- justfile | 28 ++++++-- {crates => nexum/crates}/nexum-cli/Cargo.toml | 0 .../crates}/nexum-cli/src/main.rs | 0 .../crates}/nexum-launch/Cargo.toml | 0 .../crates}/nexum-launch/src/cli.rs | 0 .../crates}/nexum-launch/src/lib.rs | 0 .../crates}/nexum-module-macros/Cargo.toml | 0 .../crates}/nexum-module-macros/src/lib.rs | 0 .../crates}/nexum-runtime/Cargo.toml | 0 .../crates}/nexum-runtime/examples/embed.rs | 0 .../crates}/nexum-runtime/src/addons.rs | 0 .../crates}/nexum-runtime/src/bindings.rs | 2 +- .../crates}/nexum-runtime/src/bootstrap.rs | 0 .../crates}/nexum-runtime/src/builder.rs | 39 +++++----- .../nexum-runtime/src/engine_config.rs | 0 .../crates}/nexum-runtime/src/host/actor.rs | 0 .../src/host/component/builder.rs | 0 .../nexum-runtime/src/host/component/chain.rs | 0 .../nexum-runtime/src/host/component/mod.rs | 0 .../src/host/component/runtime_types.rs | 0 .../nexum-runtime/src/host/component/state.rs | 0 .../crates}/nexum-runtime/src/host/error.rs | 0 .../nexum-runtime/src/host/extension.rs | 0 .../crates}/nexum-runtime/src/host/http.rs | 0 .../nexum-runtime/src/host/impls/chain.rs | 0 .../nexum-runtime/src/host/impls/identity.rs | 0 .../src/host/impls/local_store.rs | 0 .../nexum-runtime/src/host/impls/logging.rs | 0 .../nexum-runtime/src/host/impls/messaging.rs | 0 .../nexum-runtime/src/host/impls/mod.rs | 0 .../src/host/impls/remote_store.rs | 0 .../nexum-runtime/src/host/impls/types.rs | 0 .../src/host/local_store_redb.rs | 0 .../src/host/local_store_redb/tests.rs | 0 .../nexum-runtime/src/host/logs/mod.rs | 0 .../nexum-runtime/src/host/logs/stdio.rs | 0 .../nexum-runtime/src/host/logs/store.rs | 0 .../crates}/nexum-runtime/src/host/mod.rs | 0 .../nexum-runtime/src/host/provider_pool.rs | 0 .../crates}/nexum-runtime/src/host/state.rs | 0 .../crates}/nexum-runtime/src/lib.rs | 0 .../src/manifest/capabilities.rs | 0 .../nexum-runtime/src/manifest/error.rs | 0 .../nexum-runtime/src/manifest/load.rs | 0 .../crates}/nexum-runtime/src/manifest/mod.rs | 0 .../nexum-runtime/src/manifest/types.rs | 0 .../crates}/nexum-runtime/src/preset.rs | 0 .../src/runtime/dispatch_rate.rs | 0 .../nexum-runtime/src/runtime/event_loop.rs | 0 .../nexum-runtime/src/runtime/limits.rs | 0 .../crates}/nexum-runtime/src/runtime/mod.rs | 0 .../src/runtime/poison_policy.rs | 0 .../src/runtime/restart_policy.rs | 0 .../crates}/nexum-runtime/src/supervisor.rs | 0 .../nexum-runtime/src/supervisor/tests.rs | 71 ++++++++----------- .../nexum-runtime/src/test_utils/builders.rs | 0 .../nexum-runtime/src/test_utils/chain.rs | 0 .../nexum-runtime/src/test_utils/clock.rs | 0 .../nexum-runtime/src/test_utils/harness.rs | 14 ++-- .../nexum-runtime/src/test_utils/mod.rs | 0 .../nexum-runtime/src/test_utils/store.rs | 0 .../nexum-runtime/src/test_utils/types.rs | 0 .../crates}/nexum-sdk-test/Cargo.toml | 0 .../crates}/nexum-sdk-test/src/lib.rs | 0 {crates => nexum/crates}/nexum-sdk/Cargo.toml | 0 .../crates}/nexum-sdk/src/address.rs | 0 .../crates}/nexum-sdk/src/chain/chainlink.rs | 0 .../crates}/nexum-sdk/src/chain/eth_call.rs | 0 .../crates}/nexum-sdk/src/chain/mod.rs | 0 .../crates}/nexum-sdk/src/chain/provider.rs | 0 .../crates}/nexum-sdk/src/chain/transport.rs | 0 .../crates}/nexum-sdk/src/config.rs | 0 .../crates}/nexum-sdk/src/events.rs | 0 .../crates}/nexum-sdk/src/host.rs | 0 .../crates}/nexum-sdk/src/http.rs | 0 .../crates}/nexum-sdk/src/keeper.rs | 0 {crates => nexum/crates}/nexum-sdk/src/lib.rs | 0 .../crates}/nexum-sdk/src/prelude.rs | 0 .../crates}/nexum-sdk/src/proptests.rs | 0 .../crates}/nexum-sdk/src/store.rs | 0 .../crates}/nexum-sdk/src/tracing.rs | 0 .../nexum-sdk/src/wit_bindgen_macro.rs | 0 .../crates}/nexum-sdk/tests/keeper.rs | 0 .../crates}/nexum-sdk/tests/store.rs | 0 .../crates}/nexum-tasks/Cargo.toml | 0 .../crates}/nexum-tasks/src/lib.rs | 0 .../crates}/nexum-tasks/src/manager.rs | 0 .../crates}/nexum-tasks/src/shutdown.rs | 0 .../crates}/nexum-tasks/src/task.rs | 0 .../crates}/nexum-world/Cargo.toml | 0 .../crates}/nexum-world/src/lib.rs | 0 {modules => nexum/modules}/example/Cargo.toml | 0 .../modules}/example/module.toml | 0 {modules => nexum/modules}/example/src/lib.rs | 0 .../examples/balance-tracker/Cargo.toml | 0 .../examples/balance-tracker/module.toml | 0 .../examples/balance-tracker/src/lib.rs | 0 .../examples/balance-tracker/src/logic.rs | 0 .../modules}/examples/http-probe/Cargo.toml | 0 .../modules}/examples/http-probe/module.toml | 0 .../modules}/examples/http-probe/src/lib.rs | 0 .../modules}/examples/http-probe/src/logic.rs | 0 .../modules}/examples/price-alert/Cargo.toml | 0 .../modules}/examples/price-alert/module.toml | 0 .../modules}/examples/price-alert/src/lib.rs | 0 .../examples/price-alert/src/logic.rs | 0 .../modules}/fixtures/clock-reader/Cargo.toml | 0 .../fixtures/clock-reader/module.toml | 0 .../modules}/fixtures/clock-reader/src/lib.rs | 2 +- .../modules}/fixtures/flaky-bomb/Cargo.toml | 0 .../modules}/fixtures/flaky-bomb/module.toml | 0 .../modules}/fixtures/flaky-bomb/src/lib.rs | 2 +- .../modules}/fixtures/fuel-bomb/Cargo.toml | 0 .../modules}/fixtures/fuel-bomb/module.toml | 0 .../modules}/fixtures/fuel-bomb/src/lib.rs | 2 +- .../modules}/fixtures/memory-bomb/Cargo.toml | 0 .../modules}/fixtures/memory-bomb/module.toml | 0 .../modules}/fixtures/memory-bomb/src/lib.rs | 2 +- .../modules}/fixtures/panic-bomb/Cargo.toml | 0 .../modules}/fixtures/panic-bomb/module.toml | 0 .../modules}/fixtures/panic-bomb/src/lib.rs | 2 +- .../modules}/fixtures/slow-host/Cargo.toml | 0 .../modules}/fixtures/slow-host/module.toml | 0 .../modules}/fixtures/slow-host/src/lib.rs | 2 +- {tools => nexum/tools}/load-gen/Cargo.toml | 0 {tools => nexum/tools}/load-gen/src/main.rs | 0 scripts/check-carve-groups.sh | 42 +++++++++++ scripts/check-cow-orderbook-only.sh | 8 +-- scripts/check-venue-agnostic.sh | 12 ++-- .../crates}/composable-cow/Cargo.toml | 6 +- .../crates}/composable-cow/src/body.rs | 0 .../crates}/composable-cow/src/lib.rs | 0 .../crates}/composable-cow/src/poll.rs | 0 .../crates}/composable-cow/src/run.rs | 0 .../crates}/composable-cow/tests/run.rs | 0 .../crates}/cow-venue/Cargo.toml | 6 +- .../crates}/cow-venue/build.rs | 0 .../cow-venue/data/classification.toml | 0 .../crates}/cow-venue/module.load.toml | 0 .../crates}/cow-venue/module.sepolia.toml | 0 .../crates}/cow-venue/module.toml | 0 .../crates}/cow-venue/src/adapter.rs | 0 .../crates}/cow-venue/src/assembly.rs | 0 .../crates}/cow-venue/src/body.rs | 0 .../crates}/cow-venue/src/classification.rs | 0 .../cow-venue/src/classification_data.rs | 0 .../crates}/cow-venue/src/client.rs | 0 .../crates}/cow-venue/src/lib.rs | 0 .../crates}/cow-venue/src/order.rs | 0 .../crates}/cow-venue/tests/conformance.rs | 0 .../tests/vectors/cow-header-goldens.json | 0 .../tests/vectors/cow-intent-body.json | 0 .../crates}/cow-venue/tests/wit_layering.rs | 2 +- .../crates}/shepherd/Cargo.toml | 6 +- .../crates}/shepherd/src/main.rs | 0 .../modules}/ethflow-watcher/Cargo.toml | 6 +- .../modules}/ethflow-watcher/module.toml | 0 .../modules}/ethflow-watcher/src/keeper.rs | 2 +- .../modules}/ethflow-watcher/src/lib.rs | 0 .../modules}/twap-monitor/Cargo.toml | 6 +- .../modules}/twap-monitor/module.toml | 0 .../modules}/twap-monitor/src/keeper.rs | 0 .../modules}/twap-monitor/src/lib.rs | 0 .../tools}/baseline-latency/.gitignore | 0 .../baseline-latency/baseline_latency.py | 0 .../baseline-latency/data/arbitrum_one.json | 0 .../tools}/baseline-latency/data/base.json | 0 .../tools}/baseline-latency/data/gnosis.json | 0 .../tools}/baseline-latency/data/mainnet.json | 0 .../tools}/baseline-latency/data/sepolia.json | 0 .../tools}/orderbook-mock/Cargo.toml | 0 .../tools}/orderbook-mock/src/main.rs | 0 .../crates}/no-std-probe/Cargo.toml | 0 .../crates}/no-std-probe/src/lib.rs | 0 .../crates}/videre-host/Cargo.toml | 6 +- .../crates}/videre-host/src/bindings.rs | 26 +++---- .../crates}/videre-host/src/client.rs | 0 .../crates}/videre-host/src/handshake.rs | 0 .../crates}/videre-host/src/lib.rs | 0 .../crates}/videre-host/src/registry.rs | 0 .../crates}/videre-host/tests/platform.rs | 42 +++++++---- .../crates}/videre-host/tests/zero_leak.rs | 22 +++--- .../crates}/videre-macros/Cargo.toml | 2 +- .../crates}/videre-macros/src/intent_body.rs | 0 .../crates}/videre-macros/src/keeper.rs | 0 .../crates}/videre-macros/src/lib.rs | 0 .../crates}/videre-macros/src/venue_marker.rs | 0 .../crates}/videre-macros/src/world.rs | 0 .../crates}/videre-sdk/Cargo.toml | 4 +- .../crates}/videre-sdk/src/adapter.rs | 0 .../crates}/videre-sdk/src/bindings.rs | 8 +-- .../crates}/videre-sdk/src/body.rs | 0 .../crates}/videre-sdk/src/client.rs | 0 .../crates}/videre-sdk/src/event.rs | 0 .../crates}/videre-sdk/src/faults.rs | 0 .../crates}/videre-sdk/src/keeper.rs | 0 .../crates}/videre-sdk/src/lib.rs | 0 .../crates}/videre-sdk/src/transport.rs | 0 .../crates}/videre-sdk/src/value_flow.rs | 0 .../crates}/videre-sdk/tests/adapter.rs | 0 .../crates}/videre-status-body/Cargo.toml | 0 .../crates}/videre-status-body/src/lib.rs | 0 .../crates}/videre-test/Cargo.toml | 4 +- .../videre-test/goldens/reference-header.json | 0 .../crates}/videre-test/src/codec.rs | 0 .../crates}/videre-test/src/fixture.rs | 0 .../crates}/videre-test/src/header.rs | 0 .../crates}/videre-test/src/lib.rs | 0 .../crates}/videre-test/src/reconcile.rs | 0 .../crates}/videre-test/src/reference.rs | 0 .../crates}/videre-test/src/report.rs | 0 .../crates}/videre-test/src/transport.rs | 0 .../crates}/videre-test/tests/conformance.rs | 0 .../videre-test/vectors/reference-body.json | 0 .../modules}/examples/echo-client/Cargo.toml | 2 +- .../modules}/examples/echo-client/module.toml | 0 .../modules}/examples/echo-client/src/lib.rs | 0 .../modules}/examples/echo-keeper/Cargo.toml | 2 +- .../modules}/examples/echo-keeper/module.toml | 0 .../modules}/examples/echo-keeper/src/lib.rs | 0 .../modules}/examples/echo-venue/Cargo.toml | 0 .../modules}/examples/echo-venue/module.toml | 0 .../modules}/examples/echo-venue/src/lib.rs | 0 .../modules}/fixtures/flaky-venue/Cargo.toml | 0 .../modules}/fixtures/flaky-venue/module.toml | 0 .../modules}/fixtures/flaky-venue/src/lib.rs | 0 257 files changed, 394 insertions(+), 283 deletions(-) create mode 100644 docs/design/carve-workspace.md rename {crates => nexum/crates}/nexum-cli/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-cli/src/main.rs (100%) rename {crates => nexum/crates}/nexum-launch/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-launch/src/cli.rs (100%) rename {crates => nexum/crates}/nexum-launch/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-module-macros/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-module-macros/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-runtime/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-runtime/examples/embed.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/addons.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/bindings.rs (95%) rename {crates => nexum/crates}/nexum-runtime/src/bootstrap.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/builder.rs (97%) rename {crates => nexum/crates}/nexum-runtime/src/engine_config.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/actor.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/component/builder.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/component/chain.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/component/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/component/runtime_types.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/component/state.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/error.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/extension.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/http.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/chain.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/identity.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/local_store.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/logging.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/messaging.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/remote_store.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/impls/types.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/local_store_redb.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/local_store_redb/tests.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/logs/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/logs/stdio.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/logs/store.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/provider_pool.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/host/state.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/manifest/capabilities.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/manifest/error.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/manifest/load.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/manifest/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/manifest/types.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/preset.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/dispatch_rate.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/event_loop.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/limits.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/poison_policy.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/runtime/restart_policy.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/supervisor.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/supervisor/tests.rs (97%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/builders.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/chain.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/clock.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/harness.rs (98%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/mod.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/store.rs (100%) rename {crates => nexum/crates}/nexum-runtime/src/test_utils/types.rs (100%) rename {crates => nexum/crates}/nexum-sdk-test/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-sdk-test/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-sdk/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-sdk/src/address.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/chain/chainlink.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/chain/eth_call.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/chain/mod.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/chain/provider.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/chain/transport.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/config.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/events.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/host.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/http.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/keeper.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/prelude.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/proptests.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/store.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/tracing.rs (100%) rename {crates => nexum/crates}/nexum-sdk/src/wit_bindgen_macro.rs (100%) rename {crates => nexum/crates}/nexum-sdk/tests/keeper.rs (100%) rename {crates => nexum/crates}/nexum-sdk/tests/store.rs (100%) rename {crates => nexum/crates}/nexum-tasks/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-tasks/src/lib.rs (100%) rename {crates => nexum/crates}/nexum-tasks/src/manager.rs (100%) rename {crates => nexum/crates}/nexum-tasks/src/shutdown.rs (100%) rename {crates => nexum/crates}/nexum-tasks/src/task.rs (100%) rename {crates => nexum/crates}/nexum-world/Cargo.toml (100%) rename {crates => nexum/crates}/nexum-world/src/lib.rs (100%) rename {modules => nexum/modules}/example/Cargo.toml (100%) rename {modules => nexum/modules}/example/module.toml (100%) rename {modules => nexum/modules}/example/src/lib.rs (100%) rename {modules => nexum/modules}/examples/balance-tracker/Cargo.toml (100%) rename {modules => nexum/modules}/examples/balance-tracker/module.toml (100%) rename {modules => nexum/modules}/examples/balance-tracker/src/lib.rs (100%) rename {modules => nexum/modules}/examples/balance-tracker/src/logic.rs (100%) rename {modules => nexum/modules}/examples/http-probe/Cargo.toml (100%) rename {modules => nexum/modules}/examples/http-probe/module.toml (100%) rename {modules => nexum/modules}/examples/http-probe/src/lib.rs (100%) rename {modules => nexum/modules}/examples/http-probe/src/logic.rs (100%) rename {modules => nexum/modules}/examples/price-alert/Cargo.toml (100%) rename {modules => nexum/modules}/examples/price-alert/module.toml (100%) rename {modules => nexum/modules}/examples/price-alert/src/lib.rs (100%) rename {modules => nexum/modules}/examples/price-alert/src/logic.rs (100%) rename {modules => nexum/modules}/fixtures/clock-reader/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/clock-reader/module.toml (100%) rename {modules => nexum/modules}/fixtures/clock-reader/src/lib.rs (97%) rename {modules => nexum/modules}/fixtures/flaky-bomb/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/flaky-bomb/module.toml (100%) rename {modules => nexum/modules}/fixtures/flaky-bomb/src/lib.rs (98%) rename {modules => nexum/modules}/fixtures/fuel-bomb/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/fuel-bomb/module.toml (100%) rename {modules => nexum/modules}/fixtures/fuel-bomb/src/lib.rs (97%) rename {modules => nexum/modules}/fixtures/memory-bomb/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/memory-bomb/module.toml (100%) rename {modules => nexum/modules}/fixtures/memory-bomb/src/lib.rs (97%) rename {modules => nexum/modules}/fixtures/panic-bomb/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/panic-bomb/module.toml (100%) rename {modules => nexum/modules}/fixtures/panic-bomb/src/lib.rs (97%) rename {modules => nexum/modules}/fixtures/slow-host/Cargo.toml (100%) rename {modules => nexum/modules}/fixtures/slow-host/module.toml (100%) rename {modules => nexum/modules}/fixtures/slow-host/src/lib.rs (97%) rename {tools => nexum/tools}/load-gen/Cargo.toml (100%) rename {tools => nexum/tools}/load-gen/src/main.rs (100%) create mode 100755 scripts/check-carve-groups.sh rename {crates => shepherd/crates}/composable-cow/Cargo.toml (86%) rename {crates => shepherd/crates}/composable-cow/src/body.rs (100%) rename {crates => shepherd/crates}/composable-cow/src/lib.rs (100%) rename {crates => shepherd/crates}/composable-cow/src/poll.rs (100%) rename {crates => shepherd/crates}/composable-cow/src/run.rs (100%) rename {crates => shepherd/crates}/composable-cow/tests/run.rs (100%) rename {crates => shepherd/crates}/cow-venue/Cargo.toml (94%) rename {crates => shepherd/crates}/cow-venue/build.rs (100%) rename {crates => shepherd/crates}/cow-venue/data/classification.toml (100%) rename {crates => shepherd/crates}/cow-venue/module.load.toml (100%) rename {crates => shepherd/crates}/cow-venue/module.sepolia.toml (100%) rename {crates => shepherd/crates}/cow-venue/module.toml (100%) rename {crates => shepherd/crates}/cow-venue/src/adapter.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/assembly.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/body.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/classification.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/classification_data.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/client.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/lib.rs (100%) rename {crates => shepherd/crates}/cow-venue/src/order.rs (100%) rename {crates => shepherd/crates}/cow-venue/tests/conformance.rs (100%) rename {crates => shepherd/crates}/cow-venue/tests/vectors/cow-header-goldens.json (100%) rename {crates => shepherd/crates}/cow-venue/tests/vectors/cow-intent-body.json (100%) rename {crates => shepherd/crates}/cow-venue/tests/wit_layering.rs (98%) rename {crates => shepherd/crates}/shepherd/Cargo.toml (57%) rename {crates => shepherd/crates}/shepherd/src/main.rs (100%) rename {modules => shepherd/modules}/ethflow-watcher/Cargo.toml (79%) rename {modules => shepherd/modules}/ethflow-watcher/module.toml (100%) rename {modules => shepherd/modules}/ethflow-watcher/src/keeper.rs (99%) rename {modules => shepherd/modules}/ethflow-watcher/src/lib.rs (100%) rename {modules => shepherd/modules}/twap-monitor/Cargo.toml (85%) rename {modules => shepherd/modules}/twap-monitor/module.toml (100%) rename {modules => shepherd/modules}/twap-monitor/src/keeper.rs (100%) rename {modules => shepherd/modules}/twap-monitor/src/lib.rs (100%) rename {tools => shepherd/tools}/baseline-latency/.gitignore (100%) rename {tools => shepherd/tools}/baseline-latency/baseline_latency.py (100%) rename {tools => shepherd/tools}/baseline-latency/data/arbitrum_one.json (100%) rename {tools => shepherd/tools}/baseline-latency/data/base.json (100%) rename {tools => shepherd/tools}/baseline-latency/data/gnosis.json (100%) rename {tools => shepherd/tools}/baseline-latency/data/mainnet.json (100%) rename {tools => shepherd/tools}/baseline-latency/data/sepolia.json (100%) rename {tools => shepherd/tools}/orderbook-mock/Cargo.toml (100%) rename {tools => shepherd/tools}/orderbook-mock/src/main.rs (100%) rename {crates => videre/crates}/no-std-probe/Cargo.toml (100%) rename {crates => videre/crates}/no-std-probe/src/lib.rs (100%) rename {crates => videre/crates}/videre-host/Cargo.toml (86%) rename {crates => videre/crates}/videre-host/src/bindings.rs (93%) rename {crates => videre/crates}/videre-host/src/client.rs (100%) rename {crates => videre/crates}/videre-host/src/handshake.rs (100%) rename {crates => videre/crates}/videre-host/src/lib.rs (100%) rename {crates => videre/crates}/videre-host/src/registry.rs (100%) rename {crates => videre/crates}/videre-host/tests/platform.rs (97%) rename {crates => videre/crates}/videre-host/tests/zero_leak.rs (90%) rename {crates => videre/crates}/videre-macros/Cargo.toml (86%) rename {crates => videre/crates}/videre-macros/src/intent_body.rs (100%) rename {crates => videre/crates}/videre-macros/src/keeper.rs (100%) rename {crates => videre/crates}/videre-macros/src/lib.rs (100%) rename {crates => videre/crates}/videre-macros/src/venue_marker.rs (100%) rename {crates => videre/crates}/videre-macros/src/world.rs (100%) rename {crates => videre/crates}/videre-sdk/Cargo.toml (94%) rename {crates => videre/crates}/videre-sdk/src/adapter.rs (100%) rename {crates => videre/crates}/videre-sdk/src/bindings.rs (88%) rename {crates => videre/crates}/videre-sdk/src/body.rs (100%) rename {crates => videre/crates}/videre-sdk/src/client.rs (100%) rename {crates => videre/crates}/videre-sdk/src/event.rs (100%) rename {crates => videre/crates}/videre-sdk/src/faults.rs (100%) rename {crates => videre/crates}/videre-sdk/src/keeper.rs (100%) rename {crates => videre/crates}/videre-sdk/src/lib.rs (100%) rename {crates => videre/crates}/videre-sdk/src/transport.rs (100%) rename {crates => videre/crates}/videre-sdk/src/value_flow.rs (100%) rename {crates => videre/crates}/videre-sdk/tests/adapter.rs (100%) rename {crates => videre/crates}/videre-status-body/Cargo.toml (100%) rename {crates => videre/crates}/videre-status-body/src/lib.rs (100%) rename {crates => videre/crates}/videre-test/Cargo.toml (91%) rename {crates => videre/crates}/videre-test/goldens/reference-header.json (100%) rename {crates => videre/crates}/videre-test/src/codec.rs (100%) rename {crates => videre/crates}/videre-test/src/fixture.rs (100%) rename {crates => videre/crates}/videre-test/src/header.rs (100%) rename {crates => videre/crates}/videre-test/src/lib.rs (100%) rename {crates => videre/crates}/videre-test/src/reconcile.rs (100%) rename {crates => videre/crates}/videre-test/src/reference.rs (100%) rename {crates => videre/crates}/videre-test/src/report.rs (100%) rename {crates => videre/crates}/videre-test/src/transport.rs (100%) rename {crates => videre/crates}/videre-test/tests/conformance.rs (100%) rename {crates => videre/crates}/videre-test/vectors/reference-body.json (100%) rename {modules => videre/modules}/examples/echo-client/Cargo.toml (92%) rename {modules => videre/modules}/examples/echo-client/module.toml (100%) rename {modules => videre/modules}/examples/echo-client/src/lib.rs (100%) rename {modules => videre/modules}/examples/echo-keeper/Cargo.toml (90%) rename {modules => videre/modules}/examples/echo-keeper/module.toml (100%) rename {modules => videre/modules}/examples/echo-keeper/src/lib.rs (100%) rename {modules => videre/modules}/examples/echo-venue/Cargo.toml (100%) rename {modules => videre/modules}/examples/echo-venue/module.toml (100%) rename {modules => videre/modules}/examples/echo-venue/src/lib.rs (100%) rename {modules => videre/modules}/fixtures/flaky-venue/Cargo.toml (100%) rename {modules => videre/modules}/fixtures/flaky-venue/module.toml (100%) rename {modules => videre/modules}/fixtures/flaky-venue/src/lib.rs (100%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 25f28ace..41c17199 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -166,3 +166,15 @@ jobs: with: tool: ripgrep - run: ./scripts/check-cow-orderbook-only.sh + + # Blocking dep-sync gate for the transitional three-grouping workspace: every + # crate is grouped under nexum/videre/shepherd and depends only within or below + # its tier, so no upward edge becomes a circular repo dependency at the carve + # (scripts/check-carve-groups.sh, M5 #403). + carve-groups: + name: carve-groups + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + - uses: ./.github/actions/rust-setup + - run: ./scripts/check-carve-groups.sh diff --git a/Cargo.toml b/Cargo.toml index 27461972..6f5a27d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,40 +1,40 @@ [workspace] members = [ - "crates/composable-cow", - "crates/cow-venue", - "crates/nexum-cli", - "crates/nexum-launch", - "crates/nexum-module-macros", - "crates/nexum-runtime", - "crates/nexum-sdk", - "crates/nexum-sdk-test", - "crates/nexum-tasks", - "crates/nexum-world", - "crates/no-std-probe", - "crates/shepherd", - "crates/videre-host", - "crates/videre-macros", - "crates/videre-sdk", - "crates/videre-status-body", - "crates/videre-test", - "modules/ethflow-watcher", - "modules/example", - "modules/examples/balance-tracker", - "modules/examples/echo-client", - "modules/examples/echo-keeper", - "modules/examples/echo-venue", - "modules/examples/http-probe", - "modules/examples/price-alert", - "modules/fixtures/clock-reader", - "modules/fixtures/flaky-bomb", - "modules/fixtures/flaky-venue", - "modules/fixtures/fuel-bomb", - "modules/fixtures/memory-bomb", - "modules/fixtures/panic-bomb", - "modules/fixtures/slow-host", - "modules/twap-monitor", - "tools/load-gen", - "tools/orderbook-mock", + "shepherd/crates/composable-cow", + "shepherd/crates/cow-venue", + "nexum/crates/nexum-cli", + "nexum/crates/nexum-launch", + "nexum/crates/nexum-module-macros", + "nexum/crates/nexum-runtime", + "nexum/crates/nexum-sdk", + "nexum/crates/nexum-sdk-test", + "nexum/crates/nexum-tasks", + "nexum/crates/nexum-world", + "videre/crates/no-std-probe", + "shepherd/crates/shepherd", + "videre/crates/videre-host", + "videre/crates/videre-macros", + "videre/crates/videre-sdk", + "videre/crates/videre-status-body", + "videre/crates/videre-test", + "shepherd/modules/ethflow-watcher", + "nexum/modules/example", + "nexum/modules/examples/balance-tracker", + "videre/modules/examples/echo-client", + "videre/modules/examples/echo-keeper", + "videre/modules/examples/echo-venue", + "nexum/modules/examples/http-probe", + "nexum/modules/examples/price-alert", + "nexum/modules/fixtures/clock-reader", + "nexum/modules/fixtures/flaky-bomb", + "videre/modules/fixtures/flaky-venue", + "nexum/modules/fixtures/fuel-bomb", + "nexum/modules/fixtures/memory-bomb", + "nexum/modules/fixtures/panic-bomb", + "nexum/modules/fixtures/slow-host", + "shepherd/modules/twap-monitor", + "nexum/tools/load-gen", + "shepherd/tools/orderbook-mock", ] resolver = "2" diff --git a/Dockerfile b/Dockerfile index 8cc4bf90..69a38621 100644 --- a/Dockerfile +++ b/Dockerfile @@ -121,17 +121,17 @@ COPY --from=build /src/target/wasm32-wasip2/release/*.wasm /opt/shepherd/modules # Module manifests (the `module.toml` next to each cdylib crate). The # engine resolves capability declarations + chain subscriptions from # these at supervisor boot. -COPY --from=build /src/modules/twap-monitor/module.toml /opt/shepherd/manifests/twap-monitor.toml -COPY --from=build /src/modules/ethflow-watcher/module.toml /opt/shepherd/manifests/ethflow-watcher.toml -COPY --from=build /src/modules/examples/price-alert/module.toml /opt/shepherd/manifests/price-alert.toml -COPY --from=build /src/modules/examples/balance-tracker/module.toml /opt/shepherd/manifests/balance-tracker.toml +COPY --from=build /src/shepherd/modules/twap-monitor/module.toml /opt/shepherd/manifests/twap-monitor.toml +COPY --from=build /src/shepherd/modules/ethflow-watcher/module.toml /opt/shepherd/manifests/ethflow-watcher.toml +COPY --from=build /src/nexum/modules/examples/price-alert/module.toml /opt/shepherd/manifests/price-alert.toml +COPY --from=build /src/nexum/modules/examples/balance-tracker/module.toml /opt/shepherd/manifests/balance-tracker.toml # The bundled cow venue adapter's manifests; installed via the # engine.toml [[adapters]] stanza, never compiled into the engine. # One manifest per chain: mainnet (cow-venue.toml) and Sepolia # (cow-venue.sepolia.toml); pick the one matching the run's chain. -COPY --from=build /src/crates/cow-venue/module.toml /opt/shepherd/manifests/cow-venue.toml -COPY --from=build /src/crates/cow-venue/module.sepolia.toml /opt/shepherd/manifests/cow-venue.sepolia.toml +COPY --from=build /src/shepherd/crates/cow-venue/module.toml /opt/shepherd/manifests/cow-venue.toml +COPY --from=build /src/shepherd/crates/cow-venue/module.sepolia.toml /opt/shepherd/manifests/cow-venue.sepolia.toml # Drop privileges. The engine never needs root at runtime: it only # reads /etc/shepherd/engine.toml, writes to /var/lib/shepherd, and diff --git a/README.md b/README.md index 95b7bdd4..f0b248cb 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,13 @@ A module built against `nexum:host` runs on any Nexum-compatible host. CoW order | Path | Purpose | | --- | --- | -| `crates/nexum-runtime/` | The engine: a wasmtime host implementing the `nexum:host` contract. | -| `crates/nexum-launch/` | Launcher library: shared CLI, config load, tracing, preset launch. | -| `crates/nexum-cli/` | The bare `nexum` binary: the core lattice, no extension payload. | -| `crates/shepherd/` | The `shepherd` binary: the cow composition root registering the videre venue platform and the Prometheus add-on. | -| `crates/nexum-sdk/` | Guest SDK: host trait seam, bind macro, chain/config/address helpers, `wasi:http` fetch, tracing facade. | -| `crates/videre-sdk/` | Venue-platform SDK: the `videre:venue` client and adapter contracts. | -| `crates/cow-venue/` | The bundled CoW venue adapter component. | +| `nexum/crates/nexum-runtime/` | The engine: a wasmtime host implementing the `nexum:host` contract. | +| `nexum/crates/nexum-launch/` | Launcher library: shared CLI, config load, tracing, preset launch. | +| `nexum/crates/nexum-cli/` | The bare `nexum` binary: the core lattice, no extension payload. | +| `shepherd/crates/shepherd/` | The `shepherd` binary: the cow composition root registering the videre venue platform and the Prometheus add-on. | +| `nexum/crates/nexum-sdk/` | Guest SDK: host trait seam, bind macro, chain/config/address helpers, `wasi:http` fetch, tracing facade. | +| `videre/crates/videre-sdk/` | Venue-platform SDK: the `videre:venue` client and adapter contracts. | +| `shepherd/crates/cow-venue/` | The bundled CoW venue adapter component. | | `wit/nexum-host/` | The `nexum:host` WIT package: the host/guest contract. | | `wit/videre-venue/` | The `videre:venue` WIT package: the venue-adapter contract. | | `wit/shepherd-cow/` | `cow-events.wit`: the CoW event ABIs of record. | diff --git a/docs/00-overview.md b/docs/00-overview.md index 3268dbf5..aa7b76aa 100755 --- a/docs/00-overview.md +++ b/docs/00-overview.md @@ -8,10 +8,10 @@ Nexum is a WASM Component Model runtime that provides secure, sandboxed executio | Term | What it is | Where you find it | |---|---|---| -| **engine** (`nexum`) | A concrete implementation that loads and runs WASM components. The 0.2 reference engine is a wasmtime-based server daemon. | `crates/nexum-runtime/`, the `nexum` binary, `cargo run -p nexum-cli` | +| **engine** (`nexum`) | A concrete implementation that loads and runs WASM components. The 0.2 reference engine is a wasmtime-based server daemon. | `nexum/crates/nexum-runtime/`, the `nexum` binary, `cargo run -p nexum-cli` | | **host** (`nexum:host`) | The WIT contract: the host-imported interfaces (chain, identity, local-store, ...), types, and worlds that every engine implements and every module imports. | `wit/nexum-host/`, `package nexum:host@0.1.0`, Rust path `nexum::host::*` | -An engine implements `nexum:host` so that modules built against `nexum:host` can run on it. The reference engine ships as two crates: the `nexum-runtime` library (embeddable, no CLI surface) and the `nexum` binary in `crates/nexum-cli`. A Rust embedder constructs an `EngineConfig` in code and calls `nexum_runtime::bootstrap::run_from_config`; see `crates/nexum-runtime/examples/embed.rs`. +An engine implements `nexum:host` so that modules built against `nexum:host` can run on it. The reference engine ships as two crates: the `nexum-runtime` library (embeddable, no CLI surface) and the `nexum` binary in `nexum/crates/nexum-cli`. A Rust embedder constructs an `EngineConfig` in code and calls `nexum_runtime::bootstrap::run_from_config`; see `nexum/crates/nexum-runtime/examples/embed.rs`. ## Architecture diff --git a/docs/01-runtime-environment.md b/docs/01-runtime-environment.md index 8d9ca094..250298f9 100755 --- a/docs/01-runtime-environment.md +++ b/docs/01-runtime-environment.md @@ -458,7 +458,7 @@ Both are needed: fuel for correctness, epochs for liveness. ## Resource Limits -A `ResourceLimiter` caps linear-memory growth per module store, enforced synchronously on every `memory.grow`. The cap is `[limits].memory_bytes` from `engine.toml` (default 64 MiB). Fuel, the per-dispatch wall-clock deadline, and the local-store byte quota are the other resolved caps (`fuel_per_event` 1B, `event_deadline_secs` 120, `state_bytes` 50 MiB); all live in `crates/nexum-runtime/src/engine_config.rs` and apply uniformly, per-module overrides being a 0.3 direction. +A `ResourceLimiter` caps linear-memory growth per module store, enforced synchronously on every `memory.grow`. The cap is `[limits].memory_bytes` from `engine.toml` (default 64 MiB). Fuel, the per-dispatch wall-clock deadline, and the local-store byte quota are the other resolved caps (`fuel_per_event` 1B, `event_deadline_secs` 120, `state_bytes` 50 MiB); all live in `nexum/crates/nexum-runtime/src/engine_config.rs` and apply uniformly, per-module overrides being a 0.3 direction. ## Async Integration diff --git a/docs/02-modules-events-packaging.md b/docs/02-modules-events-packaging.md index e9da3b92..23ad7621 100755 --- a/docs/02-modules-events-packaging.md +++ b/docs/02-modules-events-packaging.md @@ -56,11 +56,11 @@ Key design points: - **`component` is a content hash**, not a filename. The runtime resolves it via the content store (see below). - **`[[subscription]]` blocks are declarative.** The module doesn't set up its own subscriptions imperatively - the runtime reads the manifest and wires up event sources before calling `init`. The 0.1 spelling was `[[subscribe]]` with `type = ...`; 0.2 uses `[[subscription]]` with `kind = ...` because `type` is a reserved word in several binding languages. -- **`[capabilities]`** is new in 0.2 and now drives what the runtime links into the module's import space. A module that declares `http` imports the standard `wasi:http/outgoing-handler` interface - the SDK's `http::fetch` helper wraps it - and the host checks every outgoing request against the `[capabilities.http].allow` list; see `modules/examples/http-probe` for a complete example. +- **`[capabilities]`** is new in 0.2 and now drives what the runtime links into the module's import space. A module that declares `http` imports the standard `wasi:http/outgoing-handler` interface - the SDK's `http::fetch` helper wraps it - and the host checks every outgoing request against the `[capabilities.http].allow` list; see `nexum/modules/examples/http-probe` for a complete example. - **Chain ids are declared per-subscription**, not in a top-level `[chains]` table - each `[[subscription]]` names its own `chain_id`. If `engine.toml` has no `[chains.]` entry for a chain a subscription names, the engine bails at boot, before any events dispatch (fast, clear error). - **`config`** is opaque to the runtime. 0.2 keeps 0.1's stringly-typed shape (`list>`); the host flattens TOML scalars (numbers, booleans) to their string form on the way through. A typed `config-value` variant is on the 0.3 roadmap, bundled with the manifest-parser work. -> Resource caps are engine-global in 0.2, set in `engine.toml` `[limits]` (`fuel_per_event`, default 1B; `memory_bytes`, default 64 MiB; `state_bytes`, default 50 MiB; `event_deadline_secs`, default 120), resolved in `crates/nexum-runtime/src/engine_config.rs`. Per-module `[module.resources]` overrides, per-module restart policy, and `optional`-import trap stubs are 0.3 directions. +> Resource caps are engine-global in 0.2, set in `engine.toml` `[limits]` (`fuel_per_event`, default 1B; `memory_bytes`, default 64 MiB; `state_bytes`, default 50 MiB; `event_deadline_secs`, default 120), resolved in `nexum/crates/nexum-runtime/src/engine_config.rs`. Per-module `[module.resources]` overrides, per-module restart policy, and `optional`-import trap stubs are 0.3 directions. ### Bundle Format diff --git a/docs/03-module-discovery.md b/docs/03-module-discovery.md index 21812b02..2e7cd042 100755 --- a/docs/03-module-discovery.md +++ b/docs/03-module-discovery.md @@ -12,7 +12,7 @@ path = "/var/nexum/twap-monitor/twap_monitor.wasm" manifest = "/var/nexum/twap-monitor/module.toml" ``` -This is the whole of discovery in 0.2. Content-addressed resolution (Swarm / IPFS / OCI) and `[[content.sources]]` are not wired: `EngineConfig::modules` resolves a `(component.wasm, module.toml)` pair on disk, nothing more (see `crates/nexum-runtime/src/engine_config.rs`). +This is the whole of discovery in 0.2. Content-addressed resolution (Swarm / IPFS / OCI) and `[[content.sources]]` are not wired: `EngineConfig::modules` resolves a `(component.wasm, module.toml)` pair on disk, nothing more (see `nexum/crates/nexum-runtime/src/engine_config.rs`). ## 0.3 direction: ENS and on-chain registry diff --git a/docs/05-sdk-design.md b/docs/05-sdk-design.md index f12f02a3..ad5ff4cb 100755 --- a/docs/05-sdk-design.md +++ b/docs/05-sdk-design.md @@ -2,7 +2,7 @@ This document describes the guest-side SDK crates. There are two personas, and both are shipped: the **module author**, served by `nexum-sdk`, and the **venue persona**, served by `videre-sdk` - which covers both sides of a venue: the adapter author who speaks one venue's protocol, and the keeper author who drives venues through the typed client. -For the architectural decision behind the host-trait seam both personas build on, see [ADR-0009](adr/0009-host-trait-surface.md). For the rustdoc-level API reference, see [`sdk.md`](sdk.md) and the rustdoc under `crates/nexum-sdk/` and `crates/videre-sdk/`. +For the architectural decision behind the host-trait seam both personas build on, see [ADR-0009](adr/0009-host-trait-surface.md). For the rustdoc-level API reference, see [`sdk.md`](sdk.md) and the rustdoc under `nexum/crates/nexum-sdk/` and `videre/crates/videre-sdk/`. ## The two personas @@ -95,7 +95,7 @@ Every module keeps its own `wit_bindgen::generate!` call (the macro emits types `nexum-module-macros` ships one attribute macro, re-exported as `nexum_sdk::module`. Apply it to an inherent `impl` block whose methods are named event handlers - `init`, `on_block`, `on_chain_logs`, `on_tick`, `on_message` - and the macro reads the crate's `module.toml`, synthesizes the per-module world from its `[capabilities]`, and generates the `wit_bindgen::generate!` call for that world, the capability-selected `bind_host_via_wit_bindgen!` invocation, a `Guest` implementation whose `on_event` dispatches to whichever handlers are present (absent handlers become a no-op for that event), and `export!`: ```rust -// modules/examples/http-probe/src/lib.rs (shipped) +// nexum/modules/examples/http-probe/src/lib.rs (shipped) mod logic; use nexum::host::types; @@ -196,7 +196,7 @@ conforming `derive-header` projects from them. ## Walkthrough: authoring a venue on videre -The shipped reference pair is `modules/examples/echo-venue` (adapter) and `modules/examples/echo-keeper` (driver); the production instance of the same shape is `crates/cow-venue` driven by `modules/twap-monitor`. +The shipped reference pair is `videre/modules/examples/echo-venue` (adapter) and `videre/modules/examples/echo-keeper` (driver); the production instance of the same shape is `shepherd/crates/cow-venue` driven by `shepherd/modules/twap-monitor`. 1. **Declare the manifest.** A venue adapter is a component with a `module.toml` whose kind names it: @@ -249,7 +249,7 @@ goldens, and hold the adapter to them with `videre-test` in the crate's tests. N ```toml [[adapters]] path = "target/wasm32-wasip2/release/echo_venue.wasm" - manifest = "modules/examples/echo-venue/module.toml" + manifest = "videre/modules/examples/echo-venue/module.toml" http_allow = [] # the operator's outbound-HTTP grant ``` @@ -279,11 +279,11 @@ An accepted submit is watched implicitly: the registry polls the adapter's `stat CoW ships as the production instance of the persona, in two crates so the venue stays orderbook-only: - **`cow-venue`** - feature slices. `body` (default, `no_std`): the -order intent body types and codec, light enough for any keeper or adapter to carry. `client`: the typed `CowClient` bound to the CoW venue, the deterministic `intent_id` journal key, and the table-driven retry classification generated from the shipped `data/classification.toml`. `assembly`: the chain-edge order projections and orderbook submission bodies. `adapter`: the venue adapter component itself (`CowAdapter` under `#[videre_sdk::venue]`, manifest at `crates/cow-venue/module.toml`). +order intent body types and codec, light enough for any keeper or adapter to carry. `client`: the typed `CowClient` bound to the CoW venue, the deterministic `intent_id` journal key, and the table-driven retry classification generated from the shipped `data/classification.toml`. `assembly`: the chain-edge order projections and orderbook submission bodies. `adapter`: the venue adapter component itself (`CowAdapter` under `#[videre_sdk::venue]`, manifest at `shepherd/crates/cow-venue/module.toml`). - **`composable-cow`** - the ComposableCoW keeper machinery, kept out of the venue: the conditional-order `ComposableBody`, the structured poll seam (`Verdict`, with the deployed 1.x reverting wire quarantined behind `LegacyRevertAdapter`, per [ADR-0013](adr/0013-composable-cow-structured-poll.md)), and the `run` slice composing the poll loop over the typed `CowClient`. -The shipped CoW keepers - `modules/twap-monitor`, `modules/ethflow-watcher` - are ordinary `#[videre_sdk::keeper]` modules on this surface. +The shipped CoW keepers - `shepherd/modules/twap-monitor`, `shepherd/modules/ethflow-watcher` - are ordinary `#[videre_sdk::keeper]` modules on this surface. ## Non-Rust module and adapter authors diff --git a/docs/06-production-hardening.md b/docs/06-production-hardening.md index 1b66b4c9..d4299596 100755 --- a/docs/06-production-hardening.md +++ b/docs/06-production-hardening.md @@ -4,7 +4,7 @@ The design facts behind the runtime's resource enforcement, restart policy, RPC ## Resource enforcement -Four dimensions are capped per module. Caps come from `[limits]` in `engine.toml`, resolving to built-in defaults (`crates/nexum-runtime/src/engine_config.rs`). They apply uniformly to every module; per-module overrides land in 0.3. +Four dimensions are capped per module. Caps come from `[limits]` in `engine.toml`, resolving to built-in defaults (`nexum/crates/nexum-runtime/src/engine_config.rs`). They apply uniformly to every module; per-module overrides land in 0.3. ### Fuel @@ -37,7 +37,7 @@ A module that keeps trapping is a poison pill. After `max_failures` traps within ## RPC resilience -RPC I/O flows through one alloy provider per chain, opened from `engine.toml` at boot (`crates/nexum-runtime/src/host/provider_pool.rs`). Each chain has a single `rpc_url`; there is no secondary-endpoint failover. The `chain::request` host function forwards the typed method to the provider. +RPC I/O flows through one alloy provider per chain, opened from `engine.toml` at boot (`nexum/crates/nexum-runtime/src/host/provider_pool.rs`). Each chain has a single `rpc_url`; there is no secondary-endpoint failover. The `chain::request` host function forwards the typed method to the provider. Two layers harden it: diff --git a/docs/07-rpc-namespace-design.md b/docs/07-rpc-namespace-design.md index f89804b7..79e4ef33 100755 --- a/docs/07-rpc-namespace-design.md +++ b/docs/07-rpc-namespace-design.md @@ -71,7 +71,7 @@ A module that only needs raw JSON calls `host.request(chain_id, method, params)` ## Order submission -Submitting an order or intent is not a chain namespace. It is the `videre:venue` venue-adapter contract: a keeper calls `videre:venue/client`, and the installed venue adapter (for CoW, `crates/cow-venue`) speaks the orderbook wire. See [doc 08](08-platform-generalisation.md) for the layer model and [doc 05](05-sdk-design.md) for the venue SDK. +Submitting an order or intent is not a chain namespace. It is the `videre:venue` venue-adapter contract: a keeper calls `videre:venue/client`, and the installed venue adapter (for CoW, `shepherd/crates/cow-venue`) speaks the orderbook wire. See [doc 08](08-platform-generalisation.md) for the layer model and [doc 05](05-sdk-design.md) for the venue SDK. ## Testing diff --git a/docs/08-platform-generalisation.md b/docs/08-platform-generalisation.md index 20cb3867..2a42ee17 100755 --- a/docs/08-platform-generalisation.md +++ b/docs/08-platform-generalisation.md @@ -266,7 +266,7 @@ interface adapter { } ``` -The two faces meet in the host. The venue platform (`crates/videre-host`, one `nexum-runtime` extension registered at the composition root) holds the `VenueRegistry`, links `videre:venue/client` into keeper worlds, and routes each call: resolve the venue id to its installed adapter, run the advisory egress guard over the adapter's pure `derive-header` projection, then invoke the adapter face. Accepted submits go under a status watch; the platform polls the adapter's `status` and fans transitions back to subscribed modules as `intent-status` events. Intent bodies are opaque on this path; typing is a guest-side agreement between keeper and adapter over the venue's published `IntentBody` schema ([doc 05](05-sdk-design.md#bodies-the-intentbody-derive)). +The two faces meet in the host. The venue platform (`videre/crates/videre-host`, one `nexum-runtime` extension registered at the composition root) holds the `VenueRegistry`, links `videre:venue/client` into keeper worlds, and routes each call: resolve the venue id to its installed adapter, run the advisory egress guard over the adapter's pure `derive-header` projection, then invoke the adapter face. Accepted submits go under a status watch; the platform polls the adapter's `status` and fans transitions back to subscribed modules as `intent-status` events. Intent bodies are opaque on this path; typing is a guest-side agreement between keeper and adapter over the venue's published `IntentBody` schema ([doc 05](05-sdk-design.md#bodies-the-intentbody-derive)). A new domain adds a component and (usually) a body crate, never a WIT package or a host change: write the adapter with `#[videre_sdk::venue]`, publish its codec vectors and header goldens, and install it via the engine's `[[adapters]]` table. The `shepherd` binary is exactly this composition: the core lattice plus the videre platform, with CoW entering only as the bundled `cow-venue` adapter. diff --git a/docs/adr/0001-engine-toml-separate-from-nexum-toml.md b/docs/adr/0001-engine-toml-separate-from-nexum-toml.md index 11f584b1..bb51999f 100644 --- a/docs/adr/0001-engine-toml-separate-from-nexum-toml.md +++ b/docs/adr/0001-engine-toml-separate-from-nexum-toml.md @@ -20,5 +20,5 @@ The engine config carries each module's manifest path; the two files never colla ## Consequences - A deployment needs both files. A missing `engine.toml` falls back to no chains and the default `state_dir` (`./data`); the example logging module still runs, chain-backed capabilities report `unsupported`. -- A `module.toml` without a `[capabilities]` block triggers the 0.1-compat deprecation warning in `manifest::fallback_manifest` (`crates/nexum-runtime/src/manifest/load.rs`) and treats every linked capability as required. +- A `module.toml` without a `[capabilities]` block triggers the 0.1-compat deprecation warning in `manifest::fallback_manifest` (`nexum/crates/nexum-runtime/src/manifest/load.rs`) and treats every linked capability as required. - Module-bundle redistribution carries `module.toml` with the artifact; engines ship no templates. diff --git a/docs/adr/0009-host-trait-surface.md b/docs/adr/0009-host-trait-surface.md index 47ba0618..ebe59818 100644 --- a/docs/adr/0009-host-trait-surface.md +++ b/docs/adr/0009-host-trait-surface.md @@ -22,4 +22,4 @@ Three coupled choices: - Module code is testable in native Rust without `wasm32-wasip2`; every module ships a `MockHost` unit-test suite. - New capabilities add a new trait plus a `MockX` in `nexum-sdk-test`; modules that do not use a capability bound only on the subset they touch. -- The `#[nexum_sdk::module]` macro derives a per-module world from the manifest's `[capabilities]`, so a macro-built component's imports equal its declarations by construction and an undeclared capability is a compile-time error. `enforce_capabilities` (`crates/nexum-runtime/src/manifest/capabilities.rs`) is the boot-time backstop; a hand-rolled module compiled against the supertype world that imports an undeclared capability fails there rather than at compile time. +- The `#[nexum_sdk::module]` macro derives a per-module world from the manifest's `[capabilities]`, so a macro-built component's imports equal its declarations by construction and an undeclared capability is a compile-time error. `enforce_capabilities` (`nexum/crates/nexum-runtime/src/manifest/capabilities.rs`) is the boot-time backstop; a hand-rolled module compiled against the supertype world that imports an undeclared capability fails there rather than at compile time. diff --git a/docs/adr/0013-composable-cow-structured-poll.md b/docs/adr/0013-composable-cow-structured-poll.md index 49fa4ea9..ffb56ab3 100644 --- a/docs/adr/0013-composable-cow-structured-poll.md +++ b/docs/adr/0013-composable-cow-structured-poll.md @@ -24,7 +24,7 @@ The orderbook-API submit-error `errorType` table (the REST POST response) is a s ## Current state -The seam migration has shipped: `crates/composable-cow` exports the structured `Verdict`, the `run` sweep dispatches on it (`crates/composable-cow/src/run.rs`), and the deployed reverting wire is served by `LegacyRevertAdapter`. The fork is deployed on no target chain, so `LegacyRevertAdapter` is the live poll path; the structured non-reverting `PollResult` wire is not yet exercised in production. The wire-swap remains gated on the fork deploying. +The seam migration has shipped: `shepherd/crates/composable-cow` exports the structured `Verdict`, the `run` sweep dispatches on it (`shepherd/crates/composable-cow/src/run.rs`), and the deployed reverting wire is served by `LegacyRevertAdapter`. The fork is deployed on no target chain, so `LegacyRevertAdapter` is the live poll path; the structured non-reverting `PollResult` wire is not yet exercised in production. The wire-swap remains gated on the fork deploying. ## Consequences diff --git a/docs/deployment.md b/docs/deployment.md index c430ceaa..6cc400d8 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -56,11 +56,11 @@ The full `[limits.*]` subtables (`http`, `chain`, `logs`, `poison`, `dispatch`, ```toml [[modules]] path = "modules/twap-monitor.wasm" -manifest = "modules/twap-monitor/module.toml" # defaults to module.toml beside `path` +manifest = "shepherd/modules/twap-monitor/module.toml" # defaults to module.toml beside `path` [[adapters]] path = "target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "crates/cow-venue/module.toml" +manifest = "shepherd/crates/cow-venue/module.toml" http_allow = ["api.cow.fi"] # outbound wasi:http allowlist the operator grants ``` @@ -101,7 +101,7 @@ The single-module shortcut takes positional paths and synthesizes a one-module c ```sh cargo run -p shepherd -- \ target/wasm32-wasip2/release/twap_monitor.wasm \ - modules/twap-monitor/module.toml + shepherd/modules/twap-monitor/module.toml ``` At boot the engine creates `state_dir/local-store.redb`, opens RPC providers, loads components, calls `init`, and begins dispatching. Console output is `tracing` JSON, or pretty with `--pretty-logs`. For systemd runs see [`docs/production.md`](./production.md). diff --git a/docs/deployment/multi-chain.md b/docs/deployment/multi-chain.md index 36a1e138..bf1c4a47 100644 --- a/docs/deployment/multi-chain.md +++ b/docs/deployment/multi-chain.md @@ -53,7 +53,7 @@ environment: The `cow-venue` adapter resolves the orderbook base URL from its `[config] chain` using the canonical `https://api.cow.fi//` pattern. Override it per adapter in the adapter's `module.toml` to point at a barn (staging) instance or a local mock: ```toml -# crates/cow-venue/module.toml +# shepherd/crates/cow-venue/module.toml [config] chain = 11155111 orderbook-url = "https://barn.api.cow.fi/sepolia/" @@ -130,4 +130,4 @@ Each new chain adds one always-on block subscription, N log subscriptions (one p - [`docs/deployment.md`](../deployment.md): `engine.toml` reference and single-module quickstart. - [`docs/production.md`](../production.md): systemd, RPC selection, alerting. - [`docs/deployment/docker.md`](./docker.md): container image layout. -- `modules/twap-monitor/module.toml`, `modules/ethflow-watcher/module.toml`: canonical subscription examples. +- `shepherd/modules/twap-monitor/module.toml`, `shepherd/modules/ethflow-watcher/module.toml`: canonical subscription examples. diff --git a/docs/design/carve-workspace.md b/docs/design/carve-workspace.md new file mode 100644 index 00000000..39b93173 --- /dev/null +++ b/docs/design/carve-workspace.md @@ -0,0 +1,47 @@ +# Transitional three-grouping workspace (M5) + +The monorepo is reorganized into the three prospective repo roots as one cargo +workspace, so it keeps building as a single unit with a shared `Cargo.lock` up to +the physical carve (#407). This is the refactor-now-cut-later step (#403). + +## Groupings + +Each top-level dir is a future repo root. Tier order is `nexum <- videre <- shepherd`. + +| Dir | Tier | Repo | Contents | +|-------------|------|------------------|----------| +| `nexum/` | L1 | `nexum-runtime` | universal runtime, SDK, macros, launcher, `nexum-cli` bare bin; universal-package example modules and runtime fixtures | +| `videre/` | L2 | `videre` | intent/venue SDK, host, macros, status-body; the generic `echo` reference venue | +| `shepherd/` | L3 | `shepherd` | `cow-venue`, `composable-cow`, the `shepherd` composition-root bin, the cow reference modules | + +Layout within a group: `/crates/*`, `/modules/*`, `/tools/*`. + +## Dependency invariant + +A crate depends only within its own tier or a lower one. An upward edge (nexum on +videre, videre on shepherd) would become a circular repo dependency at the carve, +so it is rejected in CI by `scripts/check-carve-groups.sh` (job `carve-groups`). +The physical layout is the source of truth: a crate's group is its top-level dir, +and the check derives every edge's tier from cargo metadata. There is no separate +mapping to drift. + +## Cross-repo dependency medium + +Cross-group edges stay as intra-workspace path-deps in this transitional umbrella, +preserving the single hoisted dependency table and shared lockfile. The medium +converges in three steps: + +1. Path-deps (now) — one workspace, one `Cargo.lock`, atomic folds. +2. Git-tag pins (at carve, #407) — each repo pins its cross-repo deps to a tagged + release; the `carve-groups` gate is joined by a dep-sync check that the pins + resolve to the tagged versions. +3. crates.io (post-carve) — published semver releases replace the git-tag pins. + +## WIT resolution + +WIT stays in a single root `wit/` for this step. `resolve_wit_package` +(`nexum/crates/nexum-world`) walks manifest-dir ancestors to the nearest `wit/`, +so every crate resolves the shared tree regardless of depth. Splitting `wit/` into +per-group `wit/` + `wit/deps/` requires the crate-local wit-deps flip and is done +in #404/#405, not here. The hardcoded `wit_bindgen::generate!` path lists that +bypass the resolver were re-based one level deeper by the move. diff --git a/docs/diagrams/diagrams.md b/docs/diagrams/diagrams.md index 9e7d4914..2eec4e0b 100644 --- a/docs/diagrams/diagrams.md +++ b/docs/diagrams/diagrams.md @@ -423,7 +423,7 @@ flowchart TD |---|---| | **WASM Module** | The guest program. It calls imported WIT functions exactly like regular function calls - it has no visibility into the host machinery behind them. | | **wasmtime Linker** | `Linker` built once at startup. `wasmtime::component::bindgen!` generates a `Shepherd` world struct and one trait per WIT interface (e.g. `shepherd::cow::cow_api::Host`, `nexum::host::local_store::Host`). `Shepherd::add_to_linker(&mut linker, \|state\| state)` registers every trait method as a host function. After that, calls from WASM resolve with zero dynamic dispatch overhead - the vtable is built at link time, not per-call. | -| **HostState - manifest.required check** | In 0.2, capability enforcement is **link-time**, not per-call. At boot, `manifest::enforce_capabilities` (in `crates/nexum-runtime/src/manifest/capabilities.rs`) cross-checks every capability-bearing WIT import of the component against the `[capabilities].required` ∪ `[capabilities].optional` set in `module.toml`, with names validated against `KNOWN_CAPABILITIES`. A module that imports a capability it did not declare fails instantiation - it never reaches dispatch. This is structurally equivalent to per-call gating for the 0.2 capability set: an undeclared capability cannot link the relevant WIT, so unauthorised calls fail at component link rather than per-call dispatch. Per-call gating in `HostState` (returning `fault.denied` per invocation, useful for finer-grained policies or capability revocation at runtime) remains a future direction for 0.3+ if a richer threat model demands it; it is not in 0.2 scope. | +| **HostState - manifest.required check** | In 0.2, capability enforcement is **link-time**, not per-call. At boot, `manifest::enforce_capabilities` (in `nexum/crates/nexum-runtime/src/manifest/capabilities.rs`) cross-checks every capability-bearing WIT import of the component against the `[capabilities].required` ∪ `[capabilities].optional` set in `module.toml`, with names validated against `KNOWN_CAPABILITIES`. A module that imports a capability it did not declare fails instantiation - it never reaches dispatch. This is structurally equivalent to per-call gating for the 0.2 capability set: an undeclared capability cannot link the relevant WIT, so unauthorised calls fail at component link rather than per-call dispatch. Per-call gating in `HostState` (returning `fault.denied` per invocation, useful for finer-grained policies or capability revocation at runtime) remains a future direction for 0.3+ if a richer threat model demands it; it is not in 0.2 scope. | | **tracing::info!** | Every host call emits a structured trace event (capability name, chain id, etc.). Operators use `RUST_LOG=shepherd=debug` to see every call a module makes. | | **host backend Rust function** | `HostState` implements one generated trait per WIT interface. Each `async fn` in the trait receives `&mut self` (giving access to all host resources) and returns the WIT-mapped Rust type. There are no CoW-specific backends - only the universal ones plus `cow-api` (ADR-0006). | | **OrderBookPool** | Looks up the `OrderBookApi` client for the requested chain and calls `post_order`. Returns a 56-byte `OrderUid` on success or an `OrderPostError`-bearing host error on failure. | diff --git a/docs/operations/load-testnet-runbook.md b/docs/operations/load-testnet-runbook.md index 09d94c48..8062ab99 100644 --- a/docs/operations/load-testnet-runbook.md +++ b/docs/operations/load-testnet-runbook.md @@ -43,11 +43,11 @@ RPC_URL_SEPOLIA_HTTP=https://eth-sepolia.g.alchemy.com/v2/ The script: -1. Sources `scripts/load-bootstrap.sh`: starts Anvil (port 8545) and `tools/orderbook-mock` (port 9999). -2. Builds the two module `.wasm`, the `shepherd` binary, and `tools/load-gen`. +1. Sources `scripts/load-bootstrap.sh`: starts Anvil (port 8545) and `shepherd/tools/orderbook-mock` (port 9999). +2. Builds the two module `.wasm`, the `shepherd` binary, and `nexum/tools/load-gen`. 3. Starts the engine on `engine.load.toml`. 4. Snapshots `/metrics`. -5. Runs `tools/load-gen` for the requested duration. +5. Runs `nexum/tools/load-gen` for the requested duration. 6. Snapshots `/metrics` again. 7. Tears everything down and drops a report at `docs/operations/load-reports/load-NxM-YYYY-MM-DD.md`. @@ -56,9 +56,9 @@ Ctrl-C triggers `load_teardown`. If a child escapes, run `./scripts/load-teardow ## 2. Components - **Anvil (port 8545)**: `anvil --fork-url $RPC_URL_SEPOLIA_HTTP --port 8545 --block-time 1`. Forks Sepolia at the latest block, inheriting ComposableCoW, CoWSwapEthFlow, the TWAP handler, WETH9, and COW at their pinned addresses, so the test EOA calls real bytecode with no local deployment. -- **Mock orderbook (port 9999)**: `tools/orderbook-mock` serves `POST /api/v1/orders`, returning a synthetic 56-byte OrderUid. Knobs (env in `scripts/load-bootstrap.sh`): `--latency-ms` injects response latency; `--error-rate` returns a fraction as an `ApiError` envelope, alternating `InsufficientFee` (`TryNextBlock`) and `InvalidSignature` (`Drop`). Leave both 0 for the saturation probe to isolate the engine-side bottleneck. +- **Mock orderbook (port 9999)**: `shepherd/tools/orderbook-mock` serves `POST /api/v1/orders`, returning a synthetic 56-byte OrderUid. Knobs (env in `scripts/load-bootstrap.sh`): `--latency-ms` injects response latency; `--error-rate` returns a fraction as an `ApiError` envelope, alternating `InsufficientFee` (`TryNextBlock`) and `InvalidSignature` (`Drop`). Leave both 0 for the saturation probe to isolate the engine-side bottleneck. - **Engine (`engine.load.toml`)**: RPC `ws://localhost:8545`; cow orderbook URL `http://localhost:9999`; Prometheus on `127.0.0.1:9100`; `state_dir = ./data/load` (wiped each run); modules `twap-monitor` + `ethflow-watcher`. -- **Load generator (`tools/load-gen`)**: connects to the Anvil WS, calls `anvil_impersonateAccount` + `anvil_setBalance` on the pinned EOA, then each new block fires N `ComposableCoW.create(...)` + M `CoWSwapEthFlow.createOrder(...)` calls, each with a fresh counter-derived salt. +- **Load generator (`nexum/tools/load-gen`)**: connects to the Anvil WS, calls `anvil_impersonateAccount` + `anvil_setBalance` on the pinned EOA, then each new block fires N `ComposableCoW.create(...)` + M `CoWSwapEthFlow.createOrder(...)` calls, each with a fresh counter-derived salt. ## 3. Acceptance reading @@ -83,5 +83,5 @@ The report at `docs/operations/load-reports/load-NxM-YYYY-MM-DD.md` carries mock - Sister doc (live Sepolia E2E): `docs/operations/e2e-testnet-runbook.md` - Engine config: `engine.load.toml` -- Tools: `tools/orderbook-mock/`, `tools/load-gen/` +- Tools: `shepherd/tools/orderbook-mock/`, `nexum/tools/load-gen/` - Scripts: `scripts/load-bootstrap.sh`, `scripts/load-run.sh`, `scripts/load-teardown.sh` diff --git a/docs/operations/m2-testnet-runbook.md b/docs/operations/m2-testnet-runbook.md index 8891d17d..79ecf38c 100644 --- a/docs/operations/m2-testnet-runbook.md +++ b/docs/operations/m2-testnet-runbook.md @@ -108,6 +108,6 @@ The local store is a redb file with no standalone dump tool. Reboot the engine o ## 5. References -- Engine config schema: `crates/nexum-runtime/src/engine_config.rs` -- M2 modules: `modules/twap-monitor/`, `modules/ethflow-watcher/` +- Engine config schema: `nexum/crates/nexum-runtime/src/engine_config.rs` +- M2 modules: `shepherd/modules/twap-monitor/`, `shepherd/modules/ethflow-watcher/` - ADR-0005 (cow-api routing), ADR-0006 (twap + ethflow helpers), ADR-0009 (host trait surface) diff --git a/docs/operations/m3-testnet-runbook.md b/docs/operations/m3-testnet-runbook.md index 0c16cd27..ea655581 100644 --- a/docs/operations/m3-testnet-runbook.md +++ b/docs/operations/m3-testnet-runbook.md @@ -94,6 +94,6 @@ INFO stop-loss submitted submitted:0x ## 5. References - M3 modules: `modules/examples/{price-alert,balance-tracker,stop-loss}/` -- SDK chain helpers: `crates/nexum-sdk/src/chain/` +- SDK chain helpers: `nexum/crates/nexum-sdk/src/chain/` - ADR-0009 (host trait surface) - M2 runbook (sister doc): `docs/operations/m2-testnet-runbook.md` diff --git a/docs/sdk.md b/docs/sdk.md index 8f21fc8e..d3a5526e 100644 --- a/docs/sdk.md +++ b/docs/sdk.md @@ -54,14 +54,14 @@ JSON plumbing (in `nexum-sdk`): seam plus the SDK's host-neutral `Fault` vocabulary (same cases as wit-bindgen's, bridged via one-liner converters per module), in `nexum-sdk`. `config` and `address` parsing helpers sit alongside it. - [`http`](../target/doc/nexum_sdk/http/index.html) - outbound -HTTP over wasi:http, in `nexum-sdk`. `http::fetch` performs one synchronous request from a `wasm32-wasip2` guest; requests and responses are the standard `http` crate's `Request` / `Response` types, and the SDK's `Fetch` trait seam, `FetchError` taxonomy, and per-phase `FetchOptions` timeouts compile on every target for host-free module tests. The module must declare the `http` capability and list the hosts it may contact in `[capabilities.http].allow` in its `module.toml`; an off-list host surfaces as the matchable `FetchError::Denied`, distinct from timeouts and transport failures. See `modules/examples/http-probe` for a complete module. +HTTP over wasi:http, in `nexum-sdk`. `http::fetch` performs one synchronous request from a `wasm32-wasip2` guest; requests and responses are the standard `http` crate's `Request` / `Response` types, and the SDK's `Fetch` trait seam, `FetchError` taxonomy, and per-phase `FetchOptions` timeouts compile on every target for host-free module tests. The module must declare the `http` capability and list the hosts it may contact in `[capabilities.http].allow` in its `module.toml`; an off-list host surfaces as the matchable `FetchError::Denied`, distinct from timeouts and transport failures. See `nexum/modules/examples/http-probe` for a complete module. ## Companions: nexum-sdk-test and videre-test -Add `nexum-sdk-test` as a dev-dep on the module crate to write module tests against in-memory mocks; its `MockHost` covers the chain, local store and logging seams. `videre-test` is the venue-side kit: codec vectors and header goldens for conformance runs, plus transport mocks such as `MockFetch`. See the crate docs ([nexum-sdk-test](../crates/nexum-sdk-test/src/lib.rs), [videre-test](../crates/videre-test/src/lib.rs)) for the usage pattern. +Add `nexum-sdk-test` as a dev-dep on the module crate to write module tests against in-memory mocks; its `MockHost` covers the chain, local store and logging seams. `videre-test` is the venue-side kit: codec vectors and header goldens for conformance runs, plus transport mocks such as `MockFetch`. See the crate docs ([nexum-sdk-test](../nexum/crates/nexum-sdk-test/src/lib.rs), [videre-test](../videre/crates/videre-test/src/lib.rs)) for the usage pattern. ## Versioning -The SDK crates are currently `0.1.0` and live at `crates/nexum-sdk/` and `crates/videre-sdk/` in the shepherd monorepo. They are not yet published to crates.io; modules depend on them via workspace paths. +The SDK crates are currently `0.1.0` and live at `nexum/crates/nexum-sdk/` and `videre/crates/videre-sdk/` in the shepherd monorepo. They are not yet published to crates.io; modules depend on them via workspace paths. The `cowprotocol` crate is published to crates.io; the workspace declares `cowprotocol = "0.2.0"` in `[workspace.dependencies]`, with a temporary `[patch.crates-io]` git override to `nullislabs/cow-rs` pending a release that ships the hash-only `OrderCreationAppData` constructor (see the comment above the patch block in the root `Cargo.toml`). Module Cargo.toml files that inherit from the workspace pick it up automatically. diff --git a/docs/testing-runtime-harness.md b/docs/testing-runtime-harness.md index b61a8c02..8c268ec1 100644 --- a/docs/testing-runtime-harness.md +++ b/docs/testing-runtime-harness.md @@ -13,7 +13,7 @@ test only needs "given input X the module does Y", it belongs in the module's pu ## What `test-utils` provides -`crates/nexum-runtime`'s `test_utils` module (gated behind the `test-utils` cargo feature) ships two layers: +`nexum/crates/nexum-runtime`'s `test_utils` module (gated behind the `test-utils` cargo feature) ships two layers: - **The bare mock backends** - `MockChainProvider`, `MockStateStore`, and `MockTypes` implement the engine's component-seam traits with no network and no disk. `mock_components` / `mock_components_from` bundle them into a `Components` ready for `Supervisor::boot`. Use these when a test needs to drive the supervisor directly - multi-module scenarios, custom extensions, or checking host-interface wiring the harness below doesn't expose. @@ -25,7 +25,7 @@ the same mocks: launch *one* module through the real public `RuntimeBuilder` pat `test_utils` only compiles under the `test-utils` feature (it pulls `tempfile`, needed for manifest staging): ```toml -# crates/nexum-runtime/Cargo.toml +# nexum/crates/nexum-runtime/Cargo.toml [features] test-utils = ["dep:tempfile"] diff --git a/docs/tutorial-first-module.md b/docs/tutorial-first-module.md index ad7b108a..2147b86a 100644 --- a/docs/tutorial-first-module.md +++ b/docs/tutorial-first-module.md @@ -1,6 +1,6 @@ # Build your first module -A walkthrough of the shipped `price-alert` example: a module that polls a Chainlink oracle on every block and logs when the price crosses a threshold. It exercises the three load-bearing patterns of a module: a block subscription, a `chain` read with ABI decode, and `[config]`-driven behaviour. Read the real files alongside this page under [`modules/examples/price-alert`](../modules/examples/price-alert). +A walkthrough of the shipped `price-alert` example: a module that polls a Chainlink oracle on every block and logs when the price crosses a threshold. It exercises the three load-bearing patterns of a module: a block subscription, a `chain` read with ABI decode, and `[config]`-driven behaviour. Read the real files alongside this page under [`nexum/modules/examples/price-alert`](../nexum/modules/examples/price-alert). Venue submission (signing and posting an order to a venue such as CoW) is a separate concern layered on `videre-sdk`; see [Where to go from here](#where-to-go-from-here). @@ -18,7 +18,7 @@ Build and run the minimal `example` module to confirm the engine works: cargo build --target wasm32-wasip2 --release -p example cargo run -p nexum-cli -- \ target/wasm32-wasip2/release/example.wasm \ - modules/example/module.toml + nexum/modules/example/module.toml ``` You should see the example module's `init` log line. Triage the build before continuing if it does not appear. @@ -86,7 +86,7 @@ every_n_blocks = "1" ``` - `required` lists the host capabilities the module imports. The engine enforces the list at instantiation: missing a used capability is a hard error. -- `[capabilities.http].allow` is empty because `price-alert` makes no outbound HTTP. A module that needs it declares the `http` capability, lists the hosts it may contact, and calls `nexum_sdk::http::fetch`; an off-list host returns the matchable `FetchError::Denied`. See [`modules/examples/http-probe`](../modules/examples/http-probe). +- `[capabilities.http].allow` is empty because `price-alert` makes no outbound HTTP. A module that needs it declares the `http` capability, lists the hosts it may contact, and calls `nexum_sdk::http::fetch`; an off-list host returns the matchable `FetchError::Denied`. See [`nexum/modules/examples/http-probe`](../nexum/modules/examples/http-probe). - `[config]` values are strings. `init` parses them into a typed `Settings`. ## The pure logic @@ -212,7 +212,7 @@ Run the engine over the module, supplying the chain config: ```sh cargo run -p nexum-cli -- \ target/wasm32-wasip2/release/price_alert.wasm \ - modules/examples/price-alert/module.toml \ + nexum/modules/examples/price-alert/module.toml \ --engine-config engine.toml ``` @@ -220,9 +220,9 @@ You should see the `init` line, then one `price-alert: ok` or `price-alert: TRIG ## Where to go from here -- Venue submission: a module that signs and posts orders to a venue depends on `videre-sdk` and a venue adapter crate (`cow-venue` for CoW), and uses `#[videre_sdk::keeper]` rather than `#[nexum_sdk::module]`. See [`modules/twap-monitor`](../modules/twap-monitor) and [docs/sdk.md](sdk.md). -- Local state: declare `local-store` and persist through `host.set`/`host.get`; see [`modules/examples/balance-tracker`](../modules/examples/balance-tracker). -- Outbound HTTP: [`modules/examples/http-probe`](../modules/examples/http-probe). +- Venue submission: a module that signs and posts orders to a venue depends on `videre-sdk` and a venue adapter crate (`cow-venue` for CoW), and uses `#[videre_sdk::keeper]` rather than `#[nexum_sdk::module]`. See [`shepherd/modules/twap-monitor`](../shepherd/modules/twap-monitor) and [docs/sdk.md](sdk.md). +- Local state: declare `local-store` and persist through `host.set`/`host.get`; see [`nexum/modules/examples/balance-tracker`](../nexum/modules/examples/balance-tracker). +- Outbound HTTP: [`nexum/modules/examples/http-probe`](../nexum/modules/examples/http-probe). - Resource limits: [docs/deployment.md](deployment.md). ## Reference @@ -231,4 +231,4 @@ You should see the `init` line, then one `price-alert: ok` or `price-alert: TRIG - Deployment: [docs/deployment.md](deployment.md) - ADR-0001 (`engine.toml` vs `module.toml` split) - ADR-0006 (TWAP and EthFlow as guest modules, no specialised WIT interfaces) -- Worked examples: [`price-alert`](../modules/examples/price-alert/), [`balance-tracker`](../modules/examples/balance-tracker/), [`twap-monitor`](../modules/twap-monitor/), [`ethflow-watcher`](../modules/ethflow-watcher/) +- Worked examples: [`price-alert`](../nexum/modules/examples/price-alert/), [`balance-tracker`](../nexum/modules/examples/balance-tracker/), [`twap-monitor`](../shepherd/modules/twap-monitor/), [`ethflow-watcher`](../shepherd/modules/ethflow-watcher/) diff --git a/engine.e2e.toml b/engine.e2e.toml index 3b664336..e3a7d26b 100644 --- a/engine.e2e.toml +++ b/engine.e2e.toml @@ -3,10 +3,10 @@ # Boots all 4 production + example modules on Sepolia simultaneously # for the 4-6 h E2E run: # -# - twap-monitor (modules/twap-monitor) -# - ethflow-watcher (modules/ethflow-watcher) -# - price-alert (modules/examples/price-alert) -# - balance-tracker (modules/examples/balance-tracker) +# - twap-monitor (shepherd/modules/twap-monitor) +# - ethflow-watcher (shepherd/modules/ethflow-watcher) +# - price-alert (nexum/modules/examples/price-alert) +# - balance-tracker (nexum/modules/examples/balance-tracker) # # This is the integration step between the M3 single-chain runbook # (`engine.m3.toml`, 2 modules) and the 7-day soak @@ -47,19 +47,19 @@ rpc_url = "wss://ethereum-sepolia-rpc.publicnode.com" [[modules]] path = "target/wasm32-wasip2/release/twap_monitor.wasm" -manifest = "modules/twap-monitor/module.toml" +manifest = "shepherd/modules/twap-monitor/module.toml" [[modules]] path = "target/wasm32-wasip2/release/ethflow_watcher.wasm" -manifest = "modules/ethflow-watcher/module.toml" +manifest = "shepherd/modules/ethflow-watcher/module.toml" [[modules]] path = "target/wasm32-wasip2/release/price_alert.wasm" -manifest = "modules/examples/price-alert/module.toml" +manifest = "nexum/modules/examples/price-alert/module.toml" [[modules]] path = "target/wasm32-wasip2/release/balance_tracker.wasm" -manifest = "modules/examples/balance-tracker/module.toml" +manifest = "nexum/modules/examples/balance-tracker/module.toml" # --- adapters --------------------------------------------------------- @@ -68,5 +68,5 @@ manifest = "modules/examples/balance-tracker/module.toml" # match the chain twap indexes. [[adapters]] path = "target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "crates/cow-venue/module.sepolia.toml" +manifest = "shepherd/crates/cow-venue/module.sepolia.toml" http_allow = ["api.cow.fi"] diff --git a/engine.example.toml b/engine.example.toml index 69184ca4..748fd86e 100644 --- a/engine.example.toml +++ b/engine.example.toml @@ -113,5 +113,5 @@ rpc_url = "${BASE_RPC_URL}" # [[adapters]] # path = "target/wasm32-wasip2/release/cow_venue.wasm" -# manifest = "crates/cow-venue/module.toml" +# manifest = "shepherd/crates/cow-venue/module.toml" # http_allow = ["api.cow.fi"] diff --git a/engine.load.toml b/engine.load.toml index 4f8072b2..4c837856 100644 --- a/engine.load.toml +++ b/engine.load.toml @@ -35,16 +35,16 @@ rpc_url = "ws://localhost:8545" [[modules]] path = "./target/wasm32-wasip2/release/twap_monitor.wasm" -manifest = "./modules/twap-monitor/module.toml" +manifest = "./shepherd/modules/twap-monitor/module.toml" # The cow venue adapter twap-monitor submits through (`just # build-cow-venue`). Load-variant manifest: Sepolia chain id with the # orderbook re-pointed at tools/orderbook-mock. [[adapters]] path = "./target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "./crates/cow-venue/module.load.toml" +manifest = "./shepherd/crates/cow-venue/module.load.toml" http_allow = ["localhost"] [[modules]] path = "./target/wasm32-wasip2/release/ethflow_watcher.wasm" -manifest = "./modules/ethflow-watcher/module.toml" +manifest = "./shepherd/modules/ethflow-watcher/module.toml" diff --git a/engine.m2.toml b/engine.m2.toml index 11f29389..5a45e4cd 100644 --- a/engine.m2.toml +++ b/engine.m2.toml @@ -28,16 +28,16 @@ rpc_url = "wss://ethereum-sepolia-rpc.publicnode.com" [[modules]] path = "target/wasm32-wasip2/release/twap_monitor.wasm" -manifest = "modules/twap-monitor/module.toml" +manifest = "shepherd/modules/twap-monitor/module.toml" [[modules]] path = "target/wasm32-wasip2/release/ethflow_watcher.wasm" -manifest = "modules/ethflow-watcher/module.toml" +manifest = "shepherd/modules/ethflow-watcher/module.toml" # The cow venue adapter twap-monitor submits through (`just # build-cow-venue`). Sepolia manifest: the adapter's orderbook must # match the chain twap indexes. [[adapters]] path = "target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "crates/cow-venue/module.sepolia.toml" +manifest = "shepherd/crates/cow-venue/module.sepolia.toml" http_allow = ["api.cow.fi"] diff --git a/engine.m3.toml b/engine.m3.toml index 8889dd4b..5a1ee826 100644 --- a/engine.m3.toml +++ b/engine.m3.toml @@ -25,11 +25,11 @@ rpc_url = "wss://ethereum-sepolia-rpc.publicnode.com" [[modules]] path = "target/wasm32-wasip2/release/price_alert.wasm" -manifest = "modules/examples/price-alert/module.toml" +manifest = "nexum/modules/examples/price-alert/module.toml" [[modules]] path = "target/wasm32-wasip2/release/balance_tracker.wasm" -manifest = "modules/examples/balance-tracker/module.toml" +manifest = "nexum/modules/examples/balance-tracker/module.toml" # --- adapters --------------------------------------------------------- @@ -38,5 +38,5 @@ manifest = "modules/examples/balance-tracker/module.toml" # match the chain the oracle is read on. [[adapters]] path = "target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "crates/cow-venue/module.sepolia.toml" +manifest = "shepherd/crates/cow-venue/module.sepolia.toml" http_allow = ["api.cow.fi"] diff --git a/engine.soak.toml b/engine.soak.toml index 567be71b..07f337ea 100644 --- a/engine.soak.toml +++ b/engine.soak.toml @@ -51,19 +51,19 @@ rpc_url = "wss://ethereum-sepolia-rpc.publicnode.com" [[modules]] path = "target/wasm32-wasip2/release/twap_monitor.wasm" -manifest = "modules/twap-monitor/module.toml" +manifest = "shepherd/modules/twap-monitor/module.toml" [[modules]] path = "target/wasm32-wasip2/release/ethflow_watcher.wasm" -manifest = "modules/ethflow-watcher/module.toml" +manifest = "shepherd/modules/ethflow-watcher/module.toml" [[modules]] path = "target/wasm32-wasip2/release/price_alert.wasm" -manifest = "modules/examples/price-alert/module.toml" +manifest = "nexum/modules/examples/price-alert/module.toml" [[modules]] path = "target/wasm32-wasip2/release/balance_tracker.wasm" -manifest = "modules/examples/balance-tracker/module.toml" +manifest = "nexum/modules/examples/balance-tracker/module.toml" # --- adapters --------------------------------------------------------- @@ -72,5 +72,5 @@ manifest = "modules/examples/balance-tracker/module.toml" # match the chain twap indexes. [[adapters]] path = "target/wasm32-wasip2/release/cow_venue.wasm" -manifest = "crates/cow-venue/module.sepolia.toml" +manifest = "shepherd/crates/cow-venue/module.sepolia.toml" http_allow = ["api.cow.fi"] diff --git a/justfile b/justfile index 47d2d3d0..58c06824 100644 --- a/justfile +++ b/justfile @@ -24,15 +24,15 @@ build: build-engine build-module # module's module.toml — without it the engine prints the 0.1-compat # deprecation warning and proceeds with empty capabilities/config. run: build-module build-engine - cargo run -p nexum-cli -- target/wasm32-wasip2/release/example.wasm modules/example/module.toml + cargo run -p nexum-cli -- target/wasm32-wasip2/release/example.wasm nexum/modules/example/module.toml # Run host engine unit tests test: - cargo test -p nexum-runtime + cargo nextest run -p nexum-runtime # Build module + engine, then run E2E integration tests test-e2e: build-module build-engine - cargo test -p nexum-runtime supervisor::tests::e2e + cargo nextest run -p nexum-runtime supervisor::tests::e2e # Build the M2 modules (twap-monitor + ethflow-watcher) for wasm32-wasip2. build-m2: @@ -87,6 +87,12 @@ check-venue-agnostic: check-cow-orderbook-only: ./scripts/check-cow-orderbook-only.sh +# Dep-sync gate: every crate is grouped under nexum/videre/shepherd and +# depends only within or below its tier, so no upward edge becomes a +# circular repo dependency at the carve. Blocking in CI (M5 #403). +check-carve-groups: + ./scripts/check-carve-groups.sh + # Check the entire workspace check: cargo check --target wasm32-wasip2 -p example @@ -96,14 +102,19 @@ check: # Run the full CI series locally before pushing. Mirrors # .github/workflows/ci.yml one-to-one: rustfmt, clippy, rustdoc, the # module wasms the integration tests need, and the workspace test -# suite, all under the `-D warnings` the CI workflow sets globally. +# suite via nextest plus the doctests, all under the `-D warnings` the +# CI workflow sets globally. ci: #!/usr/bin/env bash set -euo pipefail - export RUSTFLAGS="-D warnings" - export RUSTDOCFLAGS="-D warnings" + # Append -D warnings without clobbering the devshell's flags (mold linker, + # set in flake.nix), so the local run keeps fast native linking. RUSTC_WRAPPER + # is already sccache from the devshell shellHook. + export RUSTFLAGS="${RUSTFLAGS:-} -D warnings" + export RUSTDOCFLAGS="${RUSTDOCFLAGS:-} -D warnings" cargo fmt --all --check cargo clippy --workspace --all-targets --all-features -- -D warnings + ./scripts/check-carve-groups.sh cargo doc --workspace --no-deps cargo build --release --target wasm32-wasip2 \ -p example -p twap-monitor -p ethflow-watcher -p price-alert \ @@ -114,4 +125,7 @@ ci: # twap-monitor's cow-venue dep; rebuild the adapter component over it # (as CI does) so the platform e2e tests load the adapter, not the stub. cargo build --release --target wasm32-wasip2 -p cow-venue --features adapter - cargo test --workspace --all-features --no-fail-fast + # nextest for the suite (as CI does); doctests run separately since nextest + # does not cover them. + cargo nextest run --workspace --all-features --no-fail-fast + cargo test --doc --workspace --all-features diff --git a/crates/nexum-cli/Cargo.toml b/nexum/crates/nexum-cli/Cargo.toml similarity index 100% rename from crates/nexum-cli/Cargo.toml rename to nexum/crates/nexum-cli/Cargo.toml diff --git a/crates/nexum-cli/src/main.rs b/nexum/crates/nexum-cli/src/main.rs similarity index 100% rename from crates/nexum-cli/src/main.rs rename to nexum/crates/nexum-cli/src/main.rs diff --git a/crates/nexum-launch/Cargo.toml b/nexum/crates/nexum-launch/Cargo.toml similarity index 100% rename from crates/nexum-launch/Cargo.toml rename to nexum/crates/nexum-launch/Cargo.toml diff --git a/crates/nexum-launch/src/cli.rs b/nexum/crates/nexum-launch/src/cli.rs similarity index 100% rename from crates/nexum-launch/src/cli.rs rename to nexum/crates/nexum-launch/src/cli.rs diff --git a/crates/nexum-launch/src/lib.rs b/nexum/crates/nexum-launch/src/lib.rs similarity index 100% rename from crates/nexum-launch/src/lib.rs rename to nexum/crates/nexum-launch/src/lib.rs diff --git a/crates/nexum-module-macros/Cargo.toml b/nexum/crates/nexum-module-macros/Cargo.toml similarity index 100% rename from crates/nexum-module-macros/Cargo.toml rename to nexum/crates/nexum-module-macros/Cargo.toml diff --git a/crates/nexum-module-macros/src/lib.rs b/nexum/crates/nexum-module-macros/src/lib.rs similarity index 100% rename from crates/nexum-module-macros/src/lib.rs rename to nexum/crates/nexum-module-macros/src/lib.rs diff --git a/crates/nexum-runtime/Cargo.toml b/nexum/crates/nexum-runtime/Cargo.toml similarity index 100% rename from crates/nexum-runtime/Cargo.toml rename to nexum/crates/nexum-runtime/Cargo.toml diff --git a/crates/nexum-runtime/examples/embed.rs b/nexum/crates/nexum-runtime/examples/embed.rs similarity index 100% rename from crates/nexum-runtime/examples/embed.rs rename to nexum/crates/nexum-runtime/examples/embed.rs diff --git a/crates/nexum-runtime/src/addons.rs b/nexum/crates/nexum-runtime/src/addons.rs similarity index 100% rename from crates/nexum-runtime/src/addons.rs rename to nexum/crates/nexum-runtime/src/addons.rs diff --git a/crates/nexum-runtime/src/bindings.rs b/nexum/crates/nexum-runtime/src/bindings.rs similarity index 95% rename from crates/nexum-runtime/src/bindings.rs rename to nexum/crates/nexum-runtime/src/bindings.rs index 5789985f..e79803af 100644 --- a/crates/nexum-runtime/src/bindings.rs +++ b/nexum/crates/nexum-runtime/src/bindings.rs @@ -9,7 +9,7 @@ //! so extension services can compare event payloads. wasmtime::component::bindgen!({ - path: ["../../wit/nexum-host"], + path: ["../../../wit/nexum-host"], world: "nexum:host/event-module", imports: { default: async }, exports: { default: async }, diff --git a/crates/nexum-runtime/src/bootstrap.rs b/nexum/crates/nexum-runtime/src/bootstrap.rs similarity index 100% rename from crates/nexum-runtime/src/bootstrap.rs rename to nexum/crates/nexum-runtime/src/bootstrap.rs diff --git a/crates/nexum-runtime/src/builder.rs b/nexum/crates/nexum-runtime/src/builder.rs similarity index 97% rename from crates/nexum-runtime/src/builder.rs rename to nexum/crates/nexum-runtime/src/builder.rs index d01b1674..195cefdc 100644 --- a/crates/nexum-runtime/src/builder.rs +++ b/nexum/crates/nexum-runtime/src/builder.rs @@ -680,6 +680,17 @@ mod tests { use crate::test_utils::Prebuilt; use wasmtime::component::Linker; + /// Workspace root: the topmost ancestor with a `Cargo.toml`. + fn workspace_root() -> std::path::PathBuf { + let manifest = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); + manifest + .ancestors() + .filter(|d| d.join("Cargo.toml").is_file()) + .last() + .unwrap_or(manifest) + .to_path_buf() + } + /// The preset shortcut reaches the supervisor boot, which bails on the /// default config's empty module set. #[tokio::test] @@ -907,11 +918,7 @@ mod tests { /// module fixture is not built (`just build-module`). #[tokio::test] async fn e2e_preset_with_components_launches_through_overridden_logs() { - let repo_root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .expect("crates dir") - .parent() - .expect("repo root"); + let repo_root = workspace_root(); let wasm = repo_root.join("target/wasm32-wasip2/release/example.wasm"); if !wasm.exists() { eprintln!( @@ -920,7 +927,7 @@ mod tests { ); return; } - let manifest = repo_root.join("modules/example/module.toml"); + let manifest = repo_root.join("nexum/modules/example/module.toml"); let dir = tempfile::tempdir().expect("tempdir"); let mut config = EngineConfig::default(); @@ -947,12 +954,7 @@ mod tests { /// Every module failing `init` aborts launch instead of idling. #[tokio::test] async fn launch_bails_when_all_modules_fail_init() { - let wasm = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .expect("crates dir") - .parent() - .expect("repo root") - .join("target/wasm32-wasip2/release/price_alert.wasm"); + let wasm = workspace_root().join("target/wasm32-wasip2/release/price_alert.wasm"); if !wasm.exists() { eprintln!( "SKIP: {} not found - build with `cargo build -p price-alert --target wasm32-wasip2 --release`", @@ -1068,12 +1070,7 @@ every_n_blocks = "1" /// fixture is not built (`just build-module`). #[tokio::test] async fn e2e_builder_launch_exposes_logs_and_stops_on_shutdown() { - let wasm = std::path::Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .expect("crates dir") - .parent() - .expect("repo root") - .join("target/wasm32-wasip2/release/example.wasm"); + let wasm = workspace_root().join("target/wasm32-wasip2/release/example.wasm"); if !wasm.exists() { eprintln!( "SKIP: {} not found - run `just build-module` to enable E2E tests", @@ -1081,11 +1078,7 @@ every_n_blocks = "1" ); return; } - let manifest = wasm - .ancestors() - .nth(3) - .expect("repo root") - .join("modules/example/module.toml"); + let manifest = workspace_root().join("nexum/modules/example/module.toml"); let dir = tempfile::tempdir().expect("tempdir"); let mut config = EngineConfig::default(); diff --git a/crates/nexum-runtime/src/engine_config.rs b/nexum/crates/nexum-runtime/src/engine_config.rs similarity index 100% rename from crates/nexum-runtime/src/engine_config.rs rename to nexum/crates/nexum-runtime/src/engine_config.rs diff --git a/crates/nexum-runtime/src/host/actor.rs b/nexum/crates/nexum-runtime/src/host/actor.rs similarity index 100% rename from crates/nexum-runtime/src/host/actor.rs rename to nexum/crates/nexum-runtime/src/host/actor.rs diff --git a/crates/nexum-runtime/src/host/component/builder.rs b/nexum/crates/nexum-runtime/src/host/component/builder.rs similarity index 100% rename from crates/nexum-runtime/src/host/component/builder.rs rename to nexum/crates/nexum-runtime/src/host/component/builder.rs diff --git a/crates/nexum-runtime/src/host/component/chain.rs b/nexum/crates/nexum-runtime/src/host/component/chain.rs similarity index 100% rename from crates/nexum-runtime/src/host/component/chain.rs rename to nexum/crates/nexum-runtime/src/host/component/chain.rs diff --git a/crates/nexum-runtime/src/host/component/mod.rs b/nexum/crates/nexum-runtime/src/host/component/mod.rs similarity index 100% rename from crates/nexum-runtime/src/host/component/mod.rs rename to nexum/crates/nexum-runtime/src/host/component/mod.rs diff --git a/crates/nexum-runtime/src/host/component/runtime_types.rs b/nexum/crates/nexum-runtime/src/host/component/runtime_types.rs similarity index 100% rename from crates/nexum-runtime/src/host/component/runtime_types.rs rename to nexum/crates/nexum-runtime/src/host/component/runtime_types.rs diff --git a/crates/nexum-runtime/src/host/component/state.rs b/nexum/crates/nexum-runtime/src/host/component/state.rs similarity index 100% rename from crates/nexum-runtime/src/host/component/state.rs rename to nexum/crates/nexum-runtime/src/host/component/state.rs diff --git a/crates/nexum-runtime/src/host/error.rs b/nexum/crates/nexum-runtime/src/host/error.rs similarity index 100% rename from crates/nexum-runtime/src/host/error.rs rename to nexum/crates/nexum-runtime/src/host/error.rs diff --git a/crates/nexum-runtime/src/host/extension.rs b/nexum/crates/nexum-runtime/src/host/extension.rs similarity index 100% rename from crates/nexum-runtime/src/host/extension.rs rename to nexum/crates/nexum-runtime/src/host/extension.rs diff --git a/crates/nexum-runtime/src/host/http.rs b/nexum/crates/nexum-runtime/src/host/http.rs similarity index 100% rename from crates/nexum-runtime/src/host/http.rs rename to nexum/crates/nexum-runtime/src/host/http.rs diff --git a/crates/nexum-runtime/src/host/impls/chain.rs b/nexum/crates/nexum-runtime/src/host/impls/chain.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/chain.rs rename to nexum/crates/nexum-runtime/src/host/impls/chain.rs diff --git a/crates/nexum-runtime/src/host/impls/identity.rs b/nexum/crates/nexum-runtime/src/host/impls/identity.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/identity.rs rename to nexum/crates/nexum-runtime/src/host/impls/identity.rs diff --git a/crates/nexum-runtime/src/host/impls/local_store.rs b/nexum/crates/nexum-runtime/src/host/impls/local_store.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/local_store.rs rename to nexum/crates/nexum-runtime/src/host/impls/local_store.rs diff --git a/crates/nexum-runtime/src/host/impls/logging.rs b/nexum/crates/nexum-runtime/src/host/impls/logging.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/logging.rs rename to nexum/crates/nexum-runtime/src/host/impls/logging.rs diff --git a/crates/nexum-runtime/src/host/impls/messaging.rs b/nexum/crates/nexum-runtime/src/host/impls/messaging.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/messaging.rs rename to nexum/crates/nexum-runtime/src/host/impls/messaging.rs diff --git a/crates/nexum-runtime/src/host/impls/mod.rs b/nexum/crates/nexum-runtime/src/host/impls/mod.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/mod.rs rename to nexum/crates/nexum-runtime/src/host/impls/mod.rs diff --git a/crates/nexum-runtime/src/host/impls/remote_store.rs b/nexum/crates/nexum-runtime/src/host/impls/remote_store.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/remote_store.rs rename to nexum/crates/nexum-runtime/src/host/impls/remote_store.rs diff --git a/crates/nexum-runtime/src/host/impls/types.rs b/nexum/crates/nexum-runtime/src/host/impls/types.rs similarity index 100% rename from crates/nexum-runtime/src/host/impls/types.rs rename to nexum/crates/nexum-runtime/src/host/impls/types.rs diff --git a/crates/nexum-runtime/src/host/local_store_redb.rs b/nexum/crates/nexum-runtime/src/host/local_store_redb.rs similarity index 100% rename from crates/nexum-runtime/src/host/local_store_redb.rs rename to nexum/crates/nexum-runtime/src/host/local_store_redb.rs diff --git a/crates/nexum-runtime/src/host/local_store_redb/tests.rs b/nexum/crates/nexum-runtime/src/host/local_store_redb/tests.rs similarity index 100% rename from crates/nexum-runtime/src/host/local_store_redb/tests.rs rename to nexum/crates/nexum-runtime/src/host/local_store_redb/tests.rs diff --git a/crates/nexum-runtime/src/host/logs/mod.rs b/nexum/crates/nexum-runtime/src/host/logs/mod.rs similarity index 100% rename from crates/nexum-runtime/src/host/logs/mod.rs rename to nexum/crates/nexum-runtime/src/host/logs/mod.rs diff --git a/crates/nexum-runtime/src/host/logs/stdio.rs b/nexum/crates/nexum-runtime/src/host/logs/stdio.rs similarity index 100% rename from crates/nexum-runtime/src/host/logs/stdio.rs rename to nexum/crates/nexum-runtime/src/host/logs/stdio.rs diff --git a/crates/nexum-runtime/src/host/logs/store.rs b/nexum/crates/nexum-runtime/src/host/logs/store.rs similarity index 100% rename from crates/nexum-runtime/src/host/logs/store.rs rename to nexum/crates/nexum-runtime/src/host/logs/store.rs diff --git a/crates/nexum-runtime/src/host/mod.rs b/nexum/crates/nexum-runtime/src/host/mod.rs similarity index 100% rename from crates/nexum-runtime/src/host/mod.rs rename to nexum/crates/nexum-runtime/src/host/mod.rs diff --git a/crates/nexum-runtime/src/host/provider_pool.rs b/nexum/crates/nexum-runtime/src/host/provider_pool.rs similarity index 100% rename from crates/nexum-runtime/src/host/provider_pool.rs rename to nexum/crates/nexum-runtime/src/host/provider_pool.rs diff --git a/crates/nexum-runtime/src/host/state.rs b/nexum/crates/nexum-runtime/src/host/state.rs similarity index 100% rename from crates/nexum-runtime/src/host/state.rs rename to nexum/crates/nexum-runtime/src/host/state.rs diff --git a/crates/nexum-runtime/src/lib.rs b/nexum/crates/nexum-runtime/src/lib.rs similarity index 100% rename from crates/nexum-runtime/src/lib.rs rename to nexum/crates/nexum-runtime/src/lib.rs diff --git a/crates/nexum-runtime/src/manifest/capabilities.rs b/nexum/crates/nexum-runtime/src/manifest/capabilities.rs similarity index 100% rename from crates/nexum-runtime/src/manifest/capabilities.rs rename to nexum/crates/nexum-runtime/src/manifest/capabilities.rs diff --git a/crates/nexum-runtime/src/manifest/error.rs b/nexum/crates/nexum-runtime/src/manifest/error.rs similarity index 100% rename from crates/nexum-runtime/src/manifest/error.rs rename to nexum/crates/nexum-runtime/src/manifest/error.rs diff --git a/crates/nexum-runtime/src/manifest/load.rs b/nexum/crates/nexum-runtime/src/manifest/load.rs similarity index 100% rename from crates/nexum-runtime/src/manifest/load.rs rename to nexum/crates/nexum-runtime/src/manifest/load.rs diff --git a/crates/nexum-runtime/src/manifest/mod.rs b/nexum/crates/nexum-runtime/src/manifest/mod.rs similarity index 100% rename from crates/nexum-runtime/src/manifest/mod.rs rename to nexum/crates/nexum-runtime/src/manifest/mod.rs diff --git a/crates/nexum-runtime/src/manifest/types.rs b/nexum/crates/nexum-runtime/src/manifest/types.rs similarity index 100% rename from crates/nexum-runtime/src/manifest/types.rs rename to nexum/crates/nexum-runtime/src/manifest/types.rs diff --git a/crates/nexum-runtime/src/preset.rs b/nexum/crates/nexum-runtime/src/preset.rs similarity index 100% rename from crates/nexum-runtime/src/preset.rs rename to nexum/crates/nexum-runtime/src/preset.rs diff --git a/crates/nexum-runtime/src/runtime/dispatch_rate.rs b/nexum/crates/nexum-runtime/src/runtime/dispatch_rate.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/dispatch_rate.rs rename to nexum/crates/nexum-runtime/src/runtime/dispatch_rate.rs diff --git a/crates/nexum-runtime/src/runtime/event_loop.rs b/nexum/crates/nexum-runtime/src/runtime/event_loop.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/event_loop.rs rename to nexum/crates/nexum-runtime/src/runtime/event_loop.rs diff --git a/crates/nexum-runtime/src/runtime/limits.rs b/nexum/crates/nexum-runtime/src/runtime/limits.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/limits.rs rename to nexum/crates/nexum-runtime/src/runtime/limits.rs diff --git a/crates/nexum-runtime/src/runtime/mod.rs b/nexum/crates/nexum-runtime/src/runtime/mod.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/mod.rs rename to nexum/crates/nexum-runtime/src/runtime/mod.rs diff --git a/crates/nexum-runtime/src/runtime/poison_policy.rs b/nexum/crates/nexum-runtime/src/runtime/poison_policy.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/poison_policy.rs rename to nexum/crates/nexum-runtime/src/runtime/poison_policy.rs diff --git a/crates/nexum-runtime/src/runtime/restart_policy.rs b/nexum/crates/nexum-runtime/src/runtime/restart_policy.rs similarity index 100% rename from crates/nexum-runtime/src/runtime/restart_policy.rs rename to nexum/crates/nexum-runtime/src/runtime/restart_policy.rs diff --git a/crates/nexum-runtime/src/supervisor.rs b/nexum/crates/nexum-runtime/src/supervisor.rs similarity index 100% rename from crates/nexum-runtime/src/supervisor.rs rename to nexum/crates/nexum-runtime/src/supervisor.rs diff --git a/crates/nexum-runtime/src/supervisor/tests.rs b/nexum/crates/nexum-runtime/src/supervisor/tests.rs similarity index 97% rename from crates/nexum-runtime/src/supervisor/tests.rs rename to nexum/crates/nexum-runtime/src/supervisor/tests.rs index 80b4dd58..a16ae712 100644 --- a/crates/nexum-runtime/src/supervisor/tests.rs +++ b/nexum/crates/nexum-runtime/src/supervisor/tests.rs @@ -290,24 +290,24 @@ async fn run_drains_reconnect_tasks_cleanly_on_shutdown() { // ── E2E helpers ─────────────────────────────────────────────────────── +/// Workspace root: the topmost ancestor with a `Cargo.toml`. +fn workspace_root() -> PathBuf { + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + manifest + .ancestors() + .filter(|d| d.join("Cargo.toml").is_file()) + .last() + .unwrap_or(manifest) + .to_path_buf() +} + /// Path to the pre-built example WASM component. fn example_wasm() -> PathBuf { - // CARGO_MANIFEST_DIR → crates/nexum-runtime - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() - .join("target/wasm32-wasip2/release/example.wasm") + workspace_root().join("target/wasm32-wasip2/release/example.wasm") } fn example_module_toml() -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() - .join("modules/example/module.toml") + workspace_root().join("nexum/modules/example/module.toml") } /// Returns `None` and prints a skip message if the fixture isn't built. @@ -580,16 +580,10 @@ chain_id = 1 const SEPOLIA: u64 = 11_155_111; -/// Path to a production module's `.wasm` artefact under the workspace -/// target dir, with hyphens in the name replaced by underscores. +/// A production module's built `.wasm`; hyphens in the name become underscores. fn module_wasm(module_name: &str) -> PathBuf { let artifact = module_name.replace('-', "_"); - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() - .join(format!("target/wasm32-wasip2/release/{artifact}.wasm")) + workspace_root().join(format!("target/wasm32-wasip2/release/{artifact}.wasm")) } fn module_wasm_or_skip(module_name: &str) -> Option { @@ -615,12 +609,7 @@ fn module_wasm_or_skip(module_name: &str) -> Option { /// Resolve the real `module.toml` for one of the production modules. fn production_module_toml(relative_path: &str) -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() - .join(relative_path) + workspace_root().join(relative_path) } fn synthetic_sepolia_block() -> nexum::host::types::Block { @@ -662,7 +651,7 @@ async fn e2e_price_alert_block_dispatch() { let Some(wasm) = module_wasm_or_skip("price-alert") else { return; }; - let manifest = production_module_toml("modules/examples/price-alert/module.toml"); + let manifest = production_module_toml("nexum/modules/examples/price-alert/module.toml"); let engine = make_wasmtime_engine(); let linker = make_linker(&engine); let (_dir, store) = temp_local_store(); @@ -678,7 +667,7 @@ async fn e2e_balance_tracker_block_dispatch() { let Some(wasm) = module_wasm_or_skip("balance-tracker") else { return; }; - let manifest = production_module_toml("modules/examples/balance-tracker/module.toml"); + let manifest = production_module_toml("nexum/modules/examples/balance-tracker/module.toml"); let engine = make_wasmtime_engine(); let linker = make_linker(&engine); let (_dir, store) = temp_local_store(); @@ -1083,7 +1072,7 @@ async fn dispatch_deadline_cuts_off_a_blocked_host_call_and_recovers() { let components = crate::test_utils::mock_components_from(chain, crate::test_utils::MockStateStore::new()); - let manifest = fixture_module_toml("modules/fixtures/slow-host/module.toml"); + let manifest = fixture_module_toml("nexum/modules/fixtures/slow-host/module.toml"); // 1s is the floor the resolver saturates up to; short enough to keep // the test quick, long enough to prove the call was cut off (the park // is an hour) rather than never started. @@ -1164,12 +1153,7 @@ async fn dispatch_deadline_cuts_off_a_blocked_host_call_and_recovers() { // changes to the supervisor cannot silently bypass the limits. fn fixture_module_toml(relative_path: &str) -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .unwrap() - .parent() - .unwrap() - .join(relative_path) + workspace_root().join(relative_path) } /// Boot a single fixture (`.wasm` + `module.toml`) under the supervisor. @@ -1199,7 +1183,7 @@ async fn resource_limit_fuel_bomb_traps_and_marks_module_dead() { let Some(wasm) = module_wasm_or_skip("fuel-bomb") else { return; }; - let mut supervisor = boot_fixture(&wasm, "modules/fixtures/fuel-bomb/module.toml").await; + let mut supervisor = boot_fixture(&wasm, "nexum/modules/fixtures/fuel-bomb/module.toml").await; assert_eq!(supervisor.module_count(), 1); assert_eq!(supervisor.alive_count(), 1, "loads alive"); @@ -1287,7 +1271,7 @@ chain_id = 1 crate::engine_config::ModuleEntry { path: bomb_wasm.clone(), manifest: Some(fixture_module_toml( - "modules/fixtures/fuel-bomb/module.toml", + "nexum/modules/fixtures/fuel-bomb/module.toml", )), }, crate::engine_config::ModuleEntry { @@ -1340,7 +1324,8 @@ async fn resource_limit_memory_bomb_traps_and_marks_module_dead() { let Some(wasm) = module_wasm_or_skip("memory-bomb") else { return; }; - let mut supervisor = boot_fixture(&wasm, "modules/fixtures/memory-bomb/module.toml").await; + let mut supervisor = + boot_fixture(&wasm, "nexum/modules/fixtures/memory-bomb/module.toml").await; assert_eq!(supervisor.module_count(), 1); assert_eq!(supervisor.alive_count(), 1); @@ -1484,7 +1469,7 @@ async fn poison_pill_quarantines_module_after_threshold() { let Some(wasm) = module_wasm_or_skip("fuel-bomb") else { return; }; - let manifest = production_module_toml("modules/fixtures/fuel-bomb/module.toml"); + let manifest = production_module_toml("nexum/modules/fixtures/fuel-bomb/module.toml"); let engine = make_wasmtime_engine(); let linker = make_linker(&engine); let (_dir, store) = temp_local_store(); @@ -1652,7 +1637,7 @@ async fn dying_run_leaves_a_panic_record() { let linker = make_linker(&engine); let (_dir, store) = temp_local_store(); let (components, logs) = components_with_logs(store); - let manifest = fixture_module_toml("modules/fixtures/fuel-bomb/module.toml"); + let manifest = fixture_module_toml("nexum/modules/fixtures/fuel-bomb/module.toml"); let limits = ModuleLimits::default(); let mut supervisor = Supervisor::boot_single( &engine, @@ -1707,7 +1692,7 @@ async fn facade_panic_leaves_stderr_host_interface_and_panic_records() { let linker = make_linker(&engine); let (_dir, store) = temp_local_store(); let (components, logs) = components_with_logs(store); - let manifest = fixture_module_toml("modules/fixtures/panic-bomb/module.toml"); + let manifest = fixture_module_toml("nexum/modules/fixtures/panic-bomb/module.toml"); let limits = ModuleLimits::default(); let mut supervisor = Supervisor::boot_single( &engine, @@ -2075,7 +2060,7 @@ chain_id = 100 crate::engine_config::ModuleEntry { path: bomb_wasm, manifest: Some(fixture_module_toml( - "modules/fixtures/fuel-bomb/module.toml", + "nexum/modules/fixtures/fuel-bomb/module.toml", )), }, crate::engine_config::ModuleEntry { diff --git a/crates/nexum-runtime/src/test_utils/builders.rs b/nexum/crates/nexum-runtime/src/test_utils/builders.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/builders.rs rename to nexum/crates/nexum-runtime/src/test_utils/builders.rs diff --git a/crates/nexum-runtime/src/test_utils/chain.rs b/nexum/crates/nexum-runtime/src/test_utils/chain.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/chain.rs rename to nexum/crates/nexum-runtime/src/test_utils/chain.rs diff --git a/crates/nexum-runtime/src/test_utils/clock.rs b/nexum/crates/nexum-runtime/src/test_utils/clock.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/clock.rs rename to nexum/crates/nexum-runtime/src/test_utils/clock.rs diff --git a/crates/nexum-runtime/src/test_utils/harness.rs b/nexum/crates/nexum-runtime/src/test_utils/harness.rs similarity index 98% rename from crates/nexum-runtime/src/test_utils/harness.rs rename to nexum/crates/nexum-runtime/src/test_utils/harness.rs index b53355a6..3dc1d021 100644 --- a/crates/nexum-runtime/src/test_utils/harness.rs +++ b/nexum/crates/nexum-runtime/src/test_utils/harness.rs @@ -271,12 +271,14 @@ mod tests { /// The pre-built module wasm named `file`, or `None` with a skip note. fn module_wasm_or_skip(file: &str) -> Option { - let wasm = Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .and_then(Path::parent) - .expect("repo root") - .join("target/wasm32-wasip2/release") - .join(file); + // Workspace root: the topmost ancestor with a `Cargo.toml`. + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + let root = manifest + .ancestors() + .filter(|d| d.join("Cargo.toml").is_file()) + .last() + .unwrap_or(manifest); + let wasm = root.join("target/wasm32-wasip2/release").join(file); if wasm.exists() { Some(wasm) } else { diff --git a/crates/nexum-runtime/src/test_utils/mod.rs b/nexum/crates/nexum-runtime/src/test_utils/mod.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/mod.rs rename to nexum/crates/nexum-runtime/src/test_utils/mod.rs diff --git a/crates/nexum-runtime/src/test_utils/store.rs b/nexum/crates/nexum-runtime/src/test_utils/store.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/store.rs rename to nexum/crates/nexum-runtime/src/test_utils/store.rs diff --git a/crates/nexum-runtime/src/test_utils/types.rs b/nexum/crates/nexum-runtime/src/test_utils/types.rs similarity index 100% rename from crates/nexum-runtime/src/test_utils/types.rs rename to nexum/crates/nexum-runtime/src/test_utils/types.rs diff --git a/crates/nexum-sdk-test/Cargo.toml b/nexum/crates/nexum-sdk-test/Cargo.toml similarity index 100% rename from crates/nexum-sdk-test/Cargo.toml rename to nexum/crates/nexum-sdk-test/Cargo.toml diff --git a/crates/nexum-sdk-test/src/lib.rs b/nexum/crates/nexum-sdk-test/src/lib.rs similarity index 100% rename from crates/nexum-sdk-test/src/lib.rs rename to nexum/crates/nexum-sdk-test/src/lib.rs diff --git a/crates/nexum-sdk/Cargo.toml b/nexum/crates/nexum-sdk/Cargo.toml similarity index 100% rename from crates/nexum-sdk/Cargo.toml rename to nexum/crates/nexum-sdk/Cargo.toml diff --git a/crates/nexum-sdk/src/address.rs b/nexum/crates/nexum-sdk/src/address.rs similarity index 100% rename from crates/nexum-sdk/src/address.rs rename to nexum/crates/nexum-sdk/src/address.rs diff --git a/crates/nexum-sdk/src/chain/chainlink.rs b/nexum/crates/nexum-sdk/src/chain/chainlink.rs similarity index 100% rename from crates/nexum-sdk/src/chain/chainlink.rs rename to nexum/crates/nexum-sdk/src/chain/chainlink.rs diff --git a/crates/nexum-sdk/src/chain/eth_call.rs b/nexum/crates/nexum-sdk/src/chain/eth_call.rs similarity index 100% rename from crates/nexum-sdk/src/chain/eth_call.rs rename to nexum/crates/nexum-sdk/src/chain/eth_call.rs diff --git a/crates/nexum-sdk/src/chain/mod.rs b/nexum/crates/nexum-sdk/src/chain/mod.rs similarity index 100% rename from crates/nexum-sdk/src/chain/mod.rs rename to nexum/crates/nexum-sdk/src/chain/mod.rs diff --git a/crates/nexum-sdk/src/chain/provider.rs b/nexum/crates/nexum-sdk/src/chain/provider.rs similarity index 100% rename from crates/nexum-sdk/src/chain/provider.rs rename to nexum/crates/nexum-sdk/src/chain/provider.rs diff --git a/crates/nexum-sdk/src/chain/transport.rs b/nexum/crates/nexum-sdk/src/chain/transport.rs similarity index 100% rename from crates/nexum-sdk/src/chain/transport.rs rename to nexum/crates/nexum-sdk/src/chain/transport.rs diff --git a/crates/nexum-sdk/src/config.rs b/nexum/crates/nexum-sdk/src/config.rs similarity index 100% rename from crates/nexum-sdk/src/config.rs rename to nexum/crates/nexum-sdk/src/config.rs diff --git a/crates/nexum-sdk/src/events.rs b/nexum/crates/nexum-sdk/src/events.rs similarity index 100% rename from crates/nexum-sdk/src/events.rs rename to nexum/crates/nexum-sdk/src/events.rs diff --git a/crates/nexum-sdk/src/host.rs b/nexum/crates/nexum-sdk/src/host.rs similarity index 100% rename from crates/nexum-sdk/src/host.rs rename to nexum/crates/nexum-sdk/src/host.rs diff --git a/crates/nexum-sdk/src/http.rs b/nexum/crates/nexum-sdk/src/http.rs similarity index 100% rename from crates/nexum-sdk/src/http.rs rename to nexum/crates/nexum-sdk/src/http.rs diff --git a/crates/nexum-sdk/src/keeper.rs b/nexum/crates/nexum-sdk/src/keeper.rs similarity index 100% rename from crates/nexum-sdk/src/keeper.rs rename to nexum/crates/nexum-sdk/src/keeper.rs diff --git a/crates/nexum-sdk/src/lib.rs b/nexum/crates/nexum-sdk/src/lib.rs similarity index 100% rename from crates/nexum-sdk/src/lib.rs rename to nexum/crates/nexum-sdk/src/lib.rs diff --git a/crates/nexum-sdk/src/prelude.rs b/nexum/crates/nexum-sdk/src/prelude.rs similarity index 100% rename from crates/nexum-sdk/src/prelude.rs rename to nexum/crates/nexum-sdk/src/prelude.rs diff --git a/crates/nexum-sdk/src/proptests.rs b/nexum/crates/nexum-sdk/src/proptests.rs similarity index 100% rename from crates/nexum-sdk/src/proptests.rs rename to nexum/crates/nexum-sdk/src/proptests.rs diff --git a/crates/nexum-sdk/src/store.rs b/nexum/crates/nexum-sdk/src/store.rs similarity index 100% rename from crates/nexum-sdk/src/store.rs rename to nexum/crates/nexum-sdk/src/store.rs diff --git a/crates/nexum-sdk/src/tracing.rs b/nexum/crates/nexum-sdk/src/tracing.rs similarity index 100% rename from crates/nexum-sdk/src/tracing.rs rename to nexum/crates/nexum-sdk/src/tracing.rs diff --git a/crates/nexum-sdk/src/wit_bindgen_macro.rs b/nexum/crates/nexum-sdk/src/wit_bindgen_macro.rs similarity index 100% rename from crates/nexum-sdk/src/wit_bindgen_macro.rs rename to nexum/crates/nexum-sdk/src/wit_bindgen_macro.rs diff --git a/crates/nexum-sdk/tests/keeper.rs b/nexum/crates/nexum-sdk/tests/keeper.rs similarity index 100% rename from crates/nexum-sdk/tests/keeper.rs rename to nexum/crates/nexum-sdk/tests/keeper.rs diff --git a/crates/nexum-sdk/tests/store.rs b/nexum/crates/nexum-sdk/tests/store.rs similarity index 100% rename from crates/nexum-sdk/tests/store.rs rename to nexum/crates/nexum-sdk/tests/store.rs diff --git a/crates/nexum-tasks/Cargo.toml b/nexum/crates/nexum-tasks/Cargo.toml similarity index 100% rename from crates/nexum-tasks/Cargo.toml rename to nexum/crates/nexum-tasks/Cargo.toml diff --git a/crates/nexum-tasks/src/lib.rs b/nexum/crates/nexum-tasks/src/lib.rs similarity index 100% rename from crates/nexum-tasks/src/lib.rs rename to nexum/crates/nexum-tasks/src/lib.rs diff --git a/crates/nexum-tasks/src/manager.rs b/nexum/crates/nexum-tasks/src/manager.rs similarity index 100% rename from crates/nexum-tasks/src/manager.rs rename to nexum/crates/nexum-tasks/src/manager.rs diff --git a/crates/nexum-tasks/src/shutdown.rs b/nexum/crates/nexum-tasks/src/shutdown.rs similarity index 100% rename from crates/nexum-tasks/src/shutdown.rs rename to nexum/crates/nexum-tasks/src/shutdown.rs diff --git a/crates/nexum-tasks/src/task.rs b/nexum/crates/nexum-tasks/src/task.rs similarity index 100% rename from crates/nexum-tasks/src/task.rs rename to nexum/crates/nexum-tasks/src/task.rs diff --git a/crates/nexum-world/Cargo.toml b/nexum/crates/nexum-world/Cargo.toml similarity index 100% rename from crates/nexum-world/Cargo.toml rename to nexum/crates/nexum-world/Cargo.toml diff --git a/crates/nexum-world/src/lib.rs b/nexum/crates/nexum-world/src/lib.rs similarity index 100% rename from crates/nexum-world/src/lib.rs rename to nexum/crates/nexum-world/src/lib.rs diff --git a/modules/example/Cargo.toml b/nexum/modules/example/Cargo.toml similarity index 100% rename from modules/example/Cargo.toml rename to nexum/modules/example/Cargo.toml diff --git a/modules/example/module.toml b/nexum/modules/example/module.toml similarity index 100% rename from modules/example/module.toml rename to nexum/modules/example/module.toml diff --git a/modules/example/src/lib.rs b/nexum/modules/example/src/lib.rs similarity index 100% rename from modules/example/src/lib.rs rename to nexum/modules/example/src/lib.rs diff --git a/modules/examples/balance-tracker/Cargo.toml b/nexum/modules/examples/balance-tracker/Cargo.toml similarity index 100% rename from modules/examples/balance-tracker/Cargo.toml rename to nexum/modules/examples/balance-tracker/Cargo.toml diff --git a/modules/examples/balance-tracker/module.toml b/nexum/modules/examples/balance-tracker/module.toml similarity index 100% rename from modules/examples/balance-tracker/module.toml rename to nexum/modules/examples/balance-tracker/module.toml diff --git a/modules/examples/balance-tracker/src/lib.rs b/nexum/modules/examples/balance-tracker/src/lib.rs similarity index 100% rename from modules/examples/balance-tracker/src/lib.rs rename to nexum/modules/examples/balance-tracker/src/lib.rs diff --git a/modules/examples/balance-tracker/src/logic.rs b/nexum/modules/examples/balance-tracker/src/logic.rs similarity index 100% rename from modules/examples/balance-tracker/src/logic.rs rename to nexum/modules/examples/balance-tracker/src/logic.rs diff --git a/modules/examples/http-probe/Cargo.toml b/nexum/modules/examples/http-probe/Cargo.toml similarity index 100% rename from modules/examples/http-probe/Cargo.toml rename to nexum/modules/examples/http-probe/Cargo.toml diff --git a/modules/examples/http-probe/module.toml b/nexum/modules/examples/http-probe/module.toml similarity index 100% rename from modules/examples/http-probe/module.toml rename to nexum/modules/examples/http-probe/module.toml diff --git a/modules/examples/http-probe/src/lib.rs b/nexum/modules/examples/http-probe/src/lib.rs similarity index 100% rename from modules/examples/http-probe/src/lib.rs rename to nexum/modules/examples/http-probe/src/lib.rs diff --git a/modules/examples/http-probe/src/logic.rs b/nexum/modules/examples/http-probe/src/logic.rs similarity index 100% rename from modules/examples/http-probe/src/logic.rs rename to nexum/modules/examples/http-probe/src/logic.rs diff --git a/modules/examples/price-alert/Cargo.toml b/nexum/modules/examples/price-alert/Cargo.toml similarity index 100% rename from modules/examples/price-alert/Cargo.toml rename to nexum/modules/examples/price-alert/Cargo.toml diff --git a/modules/examples/price-alert/module.toml b/nexum/modules/examples/price-alert/module.toml similarity index 100% rename from modules/examples/price-alert/module.toml rename to nexum/modules/examples/price-alert/module.toml diff --git a/modules/examples/price-alert/src/lib.rs b/nexum/modules/examples/price-alert/src/lib.rs similarity index 100% rename from modules/examples/price-alert/src/lib.rs rename to nexum/modules/examples/price-alert/src/lib.rs diff --git a/modules/examples/price-alert/src/logic.rs b/nexum/modules/examples/price-alert/src/logic.rs similarity index 100% rename from modules/examples/price-alert/src/logic.rs rename to nexum/modules/examples/price-alert/src/logic.rs diff --git a/modules/fixtures/clock-reader/Cargo.toml b/nexum/modules/fixtures/clock-reader/Cargo.toml similarity index 100% rename from modules/fixtures/clock-reader/Cargo.toml rename to nexum/modules/fixtures/clock-reader/Cargo.toml diff --git a/modules/fixtures/clock-reader/module.toml b/nexum/modules/fixtures/clock-reader/module.toml similarity index 100% rename from modules/fixtures/clock-reader/module.toml rename to nexum/modules/fixtures/clock-reader/module.toml diff --git a/modules/fixtures/clock-reader/src/lib.rs b/nexum/modules/fixtures/clock-reader/src/lib.rs similarity index 97% rename from modules/fixtures/clock-reader/src/lib.rs rename to nexum/modules/fixtures/clock-reader/src/lib.rs index 21ee7b01..a79b3e1a 100644 --- a/modules/fixtures/clock-reader/src/lib.rs +++ b/nexum/modules/fixtures/clock-reader/src/lib.rs @@ -13,7 +13,7 @@ use std::time::{SystemTime, UNIX_EPOCH}; wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/modules/fixtures/flaky-bomb/Cargo.toml b/nexum/modules/fixtures/flaky-bomb/Cargo.toml similarity index 100% rename from modules/fixtures/flaky-bomb/Cargo.toml rename to nexum/modules/fixtures/flaky-bomb/Cargo.toml diff --git a/modules/fixtures/flaky-bomb/module.toml b/nexum/modules/fixtures/flaky-bomb/module.toml similarity index 100% rename from modules/fixtures/flaky-bomb/module.toml rename to nexum/modules/fixtures/flaky-bomb/module.toml diff --git a/modules/fixtures/flaky-bomb/src/lib.rs b/nexum/modules/fixtures/flaky-bomb/src/lib.rs similarity index 98% rename from modules/fixtures/flaky-bomb/src/lib.rs rename to nexum/modules/fixtures/flaky-bomb/src/lib.rs index 49df3817..91a82bbb 100644 --- a/modules/fixtures/flaky-bomb/src/lib.rs +++ b/nexum/modules/fixtures/flaky-bomb/src/lib.rs @@ -10,7 +10,7 @@ wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/modules/fixtures/fuel-bomb/Cargo.toml b/nexum/modules/fixtures/fuel-bomb/Cargo.toml similarity index 100% rename from modules/fixtures/fuel-bomb/Cargo.toml rename to nexum/modules/fixtures/fuel-bomb/Cargo.toml diff --git a/modules/fixtures/fuel-bomb/module.toml b/nexum/modules/fixtures/fuel-bomb/module.toml similarity index 100% rename from modules/fixtures/fuel-bomb/module.toml rename to nexum/modules/fixtures/fuel-bomb/module.toml diff --git a/modules/fixtures/fuel-bomb/src/lib.rs b/nexum/modules/fixtures/fuel-bomb/src/lib.rs similarity index 97% rename from modules/fixtures/fuel-bomb/src/lib.rs rename to nexum/modules/fixtures/fuel-bomb/src/lib.rs index 6ab9e741..3fd1bfd8 100644 --- a/modules/fixtures/fuel-bomb/src/lib.rs +++ b/nexum/modules/fixtures/fuel-bomb/src/lib.rs @@ -9,7 +9,7 @@ wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/modules/fixtures/memory-bomb/Cargo.toml b/nexum/modules/fixtures/memory-bomb/Cargo.toml similarity index 100% rename from modules/fixtures/memory-bomb/Cargo.toml rename to nexum/modules/fixtures/memory-bomb/Cargo.toml diff --git a/modules/fixtures/memory-bomb/module.toml b/nexum/modules/fixtures/memory-bomb/module.toml similarity index 100% rename from modules/fixtures/memory-bomb/module.toml rename to nexum/modules/fixtures/memory-bomb/module.toml diff --git a/modules/fixtures/memory-bomb/src/lib.rs b/nexum/modules/fixtures/memory-bomb/src/lib.rs similarity index 97% rename from modules/fixtures/memory-bomb/src/lib.rs rename to nexum/modules/fixtures/memory-bomb/src/lib.rs index 02426ab8..b09f54f0 100644 --- a/modules/fixtures/memory-bomb/src/lib.rs +++ b/nexum/modules/fixtures/memory-bomb/src/lib.rs @@ -10,7 +10,7 @@ wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/modules/fixtures/panic-bomb/Cargo.toml b/nexum/modules/fixtures/panic-bomb/Cargo.toml similarity index 100% rename from modules/fixtures/panic-bomb/Cargo.toml rename to nexum/modules/fixtures/panic-bomb/Cargo.toml diff --git a/modules/fixtures/panic-bomb/module.toml b/nexum/modules/fixtures/panic-bomb/module.toml similarity index 100% rename from modules/fixtures/panic-bomb/module.toml rename to nexum/modules/fixtures/panic-bomb/module.toml diff --git a/modules/fixtures/panic-bomb/src/lib.rs b/nexum/modules/fixtures/panic-bomb/src/lib.rs similarity index 97% rename from modules/fixtures/panic-bomb/src/lib.rs rename to nexum/modules/fixtures/panic-bomb/src/lib.rs index 8d9e823c..e0e711ac 100644 --- a/modules/fixtures/panic-bomb/src/lib.rs +++ b/nexum/modules/fixtures/panic-bomb/src/lib.rs @@ -11,7 +11,7 @@ wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/modules/fixtures/slow-host/Cargo.toml b/nexum/modules/fixtures/slow-host/Cargo.toml similarity index 100% rename from modules/fixtures/slow-host/Cargo.toml rename to nexum/modules/fixtures/slow-host/Cargo.toml diff --git a/modules/fixtures/slow-host/module.toml b/nexum/modules/fixtures/slow-host/module.toml similarity index 100% rename from modules/fixtures/slow-host/module.toml rename to nexum/modules/fixtures/slow-host/module.toml diff --git a/modules/fixtures/slow-host/src/lib.rs b/nexum/modules/fixtures/slow-host/src/lib.rs similarity index 97% rename from modules/fixtures/slow-host/src/lib.rs rename to nexum/modules/fixtures/slow-host/src/lib.rs index 7d3f405a..f5ce7b09 100644 --- a/modules/fixtures/slow-host/src/lib.rs +++ b/nexum/modules/fixtures/slow-host/src/lib.rs @@ -13,7 +13,7 @@ wit_bindgen::generate!({ path: [ - "../../../wit/nexum-host", + "../../../../wit/nexum-host", ], world: "nexum:host/event-module", generate_all, diff --git a/tools/load-gen/Cargo.toml b/nexum/tools/load-gen/Cargo.toml similarity index 100% rename from tools/load-gen/Cargo.toml rename to nexum/tools/load-gen/Cargo.toml diff --git a/tools/load-gen/src/main.rs b/nexum/tools/load-gen/src/main.rs similarity index 100% rename from tools/load-gen/src/main.rs rename to nexum/tools/load-gen/src/main.rs diff --git a/scripts/check-carve-groups.sh b/scripts/check-carve-groups.sh new file mode 100755 index 00000000..b5c35af7 --- /dev/null +++ b/scripts/check-carve-groups.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Dep-sync gate for the transitional three-grouping workspace (M5, #403). +# +# The physical layout is the source of truth: every workspace crate lives under +# exactly one group dir (nexum/ = L1, videre/ = L2, shepherd/ = L3). A crate may +# depend only within its own tier or a lower one (nexum <- videre <- shepherd). +# An upward edge (e.g. nexum depending on videre) would become a circular repo +# dependency the moment the groups are carved into separate repos, so it is +# rejected here rather than discovered at the cut. +set -euo pipefail +cd "$(dirname "${BASH_SOURCE[0]}")/.." + +meta="$(cargo metadata --format-version 1 --no-deps)" + +# Emit "|" lines for every violation, then gate on the count. +violations="$(printf '%s' "$meta" | jq -r ' + .workspace_root as $root + | (["nexum","videre","shepherd"]) as $tiers + | def grp($p): ($p | ltrimstr($root + "/") | split("/")[0]); + def tier($p): ($tiers | index(grp($p))); + .packages[] + | select(.manifest_path | startswith($root + "/")) + | .name as $n + | (.manifest_path | rtrimstr("/Cargo.toml")) as $self + | if (tier($self) == null) + then "\($n)|not under a group dir (nexum/videre/shepherd): \(grp($self))" + else + (tier($self)) as $st + | .dependencies[] + | select(.path != null and (.path | startswith($root + "/"))) + | select((tier(.path)) != null and (tier(.path)) > $st) + | "\($n)|upward dep on \(.name) (\(grp($self)) -> \(grp(.path)))" + end +')" + +if [ -n "$violations" ]; then + echo "carve-groups: FAIL — grouping invariant violated:" >&2 + printf '%s\n' "$violations" | sed 's/^/ /; s/|/: /' >&2 + exit 1 +fi + +echo "carve-groups: OK — every workspace crate is grouped and depends only within or below its tier" diff --git a/scripts/check-cow-orderbook-only.sh b/scripts/check-cow-orderbook-only.sh index 52229ed2..e6fee9cb 100755 --- a/scripts/check-cow-orderbook-only.sh +++ b/scripts/check-cow-orderbook-only.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# Orderbook-only check for the CoW venue crate: crates/cow-venue carries +# Orderbook-only check for the CoW venue crate: shepherd/crates/cow-venue carries # no composable symbol (Composable*, getTradeableOrder*, the # IConditionalOrder revert selectors, LegacyRevertAdapter) and no # dependency edge to the composable-cow keeper crate - the Cargo.toml @@ -19,11 +19,11 @@ command -v rg >/dev/null || { echo "ripgrep (rg) is required" >&2; exit 2; } status=0 symbols='composable|getTradeableOrder|IConditionalOrder|LegacyRevertAdapter|\bVerdict\b|OrderNotValid|PollTryNextBlock|PollTryAtBlock|PollTryAtEpoch|PollNever' -rg -in --no-heading -e "$symbols" crates/cow-venue +rg -in --no-heading -e "$symbols" shepherd/crates/cow-venue case $? in - 0) fail "composable symbols leak into crates/cow-venue" ;; + 0) fail "composable symbols leak into shepherd/crates/cow-venue" ;; 1) pass "cow-venue symbol scan empty" ;; - *) fail "symbol scan errored (crates/cow-venue missing?)" ;; + *) fail "symbol scan errored (shepherd/crates/cow-venue missing?)" ;; esac exit "$status" diff --git a/scripts/check-venue-agnostic.sh b/scripts/check-venue-agnostic.sh index fe52c029..4b317a8d 100755 --- a/scripts/check-venue-agnostic.sh +++ b/scripts/check-venue-agnostic.sh @@ -58,11 +58,11 @@ else fail "cargo tree failed for nexum-sdk" fi sdk_charter='intent-status|IntentStatusUpdate|INTENT_STATUS_KIND|[Ss]tatus[Bb]ody|status[-_]body' -rg -n --no-heading -e "$sdk_charter" crates/nexum-sdk/src +rg -n --no-heading -e "$sdk_charter" nexum/crates/nexum-sdk/src case $? in 0) fail "venue status-codec vocabulary leaks into nexum-sdk" ;; 1) pass "nexum-sdk carries no venue status-codec vocabulary" ;; - *) fail "nexum-sdk scan errored (crates/nexum-sdk/src missing?)" ;; + *) fail "nexum-sdk scan errored (nexum/crates/nexum-sdk/src missing?)" ;; esac # 2. Symbol scan: the charter set (the current venue vocabulary that would @@ -70,22 +70,22 @@ esac # guard). Section 1 guards dependency edges; this scan stays curated to # the live post-rename names so opaque extension payloads never false-flag. charter='videre:|videre_host|Venue[A-Z]|EgressGuard|synthesize_venue|value-flow' -rg -n --no-heading -e "$charter" crates/nexum-runtime/src +rg -n --no-heading -e "$charter" nexum/crates/nexum-runtime/src case $? in 0) fail "charter symbols leak into nexum-runtime" ;; 1) pass "symbol scan empty" ;; - *) fail "symbol scan errored (crates/nexum-runtime/src missing?)" ;; + *) fail "symbol scan errored (nexum/crates/nexum-runtime/src missing?)" ;; esac # 3. Privileged-field scan: the venue registry rides the extension # service map; no `VenueRegistry` router field may return to the # runtime. (The charter scan above also catches the type; this stays # as the named guard for that specific invariant.) -rg -n --no-heading -e 'VenueRegistry' crates/nexum-runtime/src +rg -n --no-heading -e 'VenueRegistry' nexum/crates/nexum-runtime/src case $? in 0) fail "a privileged router field returned to nexum-runtime" ;; 1) pass "no privileged router field" ;; - *) fail "field scan errored (crates/nexum-runtime/src missing?)" ;; + *) fail "field scan errored (nexum/crates/nexum-runtime/src missing?)" ;; esac # 4. WIT surface: nexum:host is a leaf. No foreign package named diff --git a/crates/composable-cow/Cargo.toml b/shepherd/crates/composable-cow/Cargo.toml similarity index 86% rename from crates/composable-cow/Cargo.toml rename to shepherd/crates/composable-cow/Cargo.toml index 6d7c29e5..e692c1a7 100644 --- a/crates/composable-cow/Cargo.toml +++ b/shepherd/crates/composable-cow/Cargo.toml @@ -20,11 +20,11 @@ alloy-primitives = { workspace = true, features = ["borsh"] } alloy-sol-types.workspace = true borsh.workspace = true cowprotocol = { version = "0.2.0", default-features = false } -nexum-sdk = { path = "../nexum-sdk" } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk" } # `run` slice: the keeper run over the typed CoW client on the # `videre:venue/client` seam. cow-venue = { path = "../cow-venue", features = ["client", "assembly"], optional = true } -videre-sdk = { path = "../videre-sdk", optional = true } +videre-sdk = { path = "../../../videre/crates/videre-sdk", optional = true } tracing = { workspace = true, optional = true } [features] @@ -34,7 +34,7 @@ run = ["dep:cow-venue", "dep:videre-sdk", "dep:tracing"] [dev-dependencies] proptest.workspace = true -nexum-sdk-test = { path = "../nexum-sdk-test" } +nexum-sdk-test = { path = "../../../nexum/crates/nexum-sdk-test" } [[test]] name = "run" diff --git a/crates/composable-cow/src/body.rs b/shepherd/crates/composable-cow/src/body.rs similarity index 100% rename from crates/composable-cow/src/body.rs rename to shepherd/crates/composable-cow/src/body.rs diff --git a/crates/composable-cow/src/lib.rs b/shepherd/crates/composable-cow/src/lib.rs similarity index 100% rename from crates/composable-cow/src/lib.rs rename to shepherd/crates/composable-cow/src/lib.rs diff --git a/crates/composable-cow/src/poll.rs b/shepherd/crates/composable-cow/src/poll.rs similarity index 100% rename from crates/composable-cow/src/poll.rs rename to shepherd/crates/composable-cow/src/poll.rs diff --git a/crates/composable-cow/src/run.rs b/shepherd/crates/composable-cow/src/run.rs similarity index 100% rename from crates/composable-cow/src/run.rs rename to shepherd/crates/composable-cow/src/run.rs diff --git a/crates/composable-cow/tests/run.rs b/shepherd/crates/composable-cow/tests/run.rs similarity index 100% rename from crates/composable-cow/tests/run.rs rename to shepherd/crates/composable-cow/tests/run.rs diff --git a/crates/cow-venue/Cargo.toml b/shepherd/crates/cow-venue/Cargo.toml similarity index 94% rename from crates/cow-venue/Cargo.toml rename to shepherd/crates/cow-venue/Cargo.toml index 9a110ea4..9c1bb291 100644 --- a/crates/cow-venue/Cargo.toml +++ b/shepherd/crates/cow-venue/Cargo.toml @@ -23,12 +23,12 @@ workspace = true borsh = { workspace = true, optional = true } # Source of the `IntentBody` derive and trait the version enum implements, # and the typed intent client the `client` slice binds to the CoW venue. -videre-sdk = { path = "../videre-sdk", optional = true } +videre-sdk = { path = "../../../videre/crates/videre-sdk", optional = true } # `client` slice only: the keeper `RetryAction` the generated # classification table maps each errorType to. The TOML parse happens in # `build.rs`, so serde/toml/thiserror are build- and dev-only and never # reach a guest that links this slice. -nexum-sdk = { path = "../nexum-sdk", optional = true } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk", optional = true } # `assembly` slice: the chain-edge order projections and orderbook # submission bodies. The `client` slice also enables it for the typed # `OrderbookApiErrorType` classifier boundary. Express-declared (not @@ -61,7 +61,7 @@ serde = { workspace = true } toml = { workspace = true } thiserror = { workspace = true } # The conformance kit: holds the body codec to its published vector set. -videre-test = { path = "../videre-test" } +videre-test = { path = "../../../videre/crates/videre-test" } # Parity tests: the upstream `retry_hint()` the shipped table is # reconciled against. cowprotocol = { version = "0.2.0", default-features = false } diff --git a/crates/cow-venue/build.rs b/shepherd/crates/cow-venue/build.rs similarity index 100% rename from crates/cow-venue/build.rs rename to shepherd/crates/cow-venue/build.rs diff --git a/crates/cow-venue/data/classification.toml b/shepherd/crates/cow-venue/data/classification.toml similarity index 100% rename from crates/cow-venue/data/classification.toml rename to shepherd/crates/cow-venue/data/classification.toml diff --git a/crates/cow-venue/module.load.toml b/shepherd/crates/cow-venue/module.load.toml similarity index 100% rename from crates/cow-venue/module.load.toml rename to shepherd/crates/cow-venue/module.load.toml diff --git a/crates/cow-venue/module.sepolia.toml b/shepherd/crates/cow-venue/module.sepolia.toml similarity index 100% rename from crates/cow-venue/module.sepolia.toml rename to shepherd/crates/cow-venue/module.sepolia.toml diff --git a/crates/cow-venue/module.toml b/shepherd/crates/cow-venue/module.toml similarity index 100% rename from crates/cow-venue/module.toml rename to shepherd/crates/cow-venue/module.toml diff --git a/crates/cow-venue/src/adapter.rs b/shepherd/crates/cow-venue/src/adapter.rs similarity index 100% rename from crates/cow-venue/src/adapter.rs rename to shepherd/crates/cow-venue/src/adapter.rs diff --git a/crates/cow-venue/src/assembly.rs b/shepherd/crates/cow-venue/src/assembly.rs similarity index 100% rename from crates/cow-venue/src/assembly.rs rename to shepherd/crates/cow-venue/src/assembly.rs diff --git a/crates/cow-venue/src/body.rs b/shepherd/crates/cow-venue/src/body.rs similarity index 100% rename from crates/cow-venue/src/body.rs rename to shepherd/crates/cow-venue/src/body.rs diff --git a/crates/cow-venue/src/classification.rs b/shepherd/crates/cow-venue/src/classification.rs similarity index 100% rename from crates/cow-venue/src/classification.rs rename to shepherd/crates/cow-venue/src/classification.rs diff --git a/crates/cow-venue/src/classification_data.rs b/shepherd/crates/cow-venue/src/classification_data.rs similarity index 100% rename from crates/cow-venue/src/classification_data.rs rename to shepherd/crates/cow-venue/src/classification_data.rs diff --git a/crates/cow-venue/src/client.rs b/shepherd/crates/cow-venue/src/client.rs similarity index 100% rename from crates/cow-venue/src/client.rs rename to shepherd/crates/cow-venue/src/client.rs diff --git a/crates/cow-venue/src/lib.rs b/shepherd/crates/cow-venue/src/lib.rs similarity index 100% rename from crates/cow-venue/src/lib.rs rename to shepherd/crates/cow-venue/src/lib.rs diff --git a/crates/cow-venue/src/order.rs b/shepherd/crates/cow-venue/src/order.rs similarity index 100% rename from crates/cow-venue/src/order.rs rename to shepherd/crates/cow-venue/src/order.rs diff --git a/crates/cow-venue/tests/conformance.rs b/shepherd/crates/cow-venue/tests/conformance.rs similarity index 100% rename from crates/cow-venue/tests/conformance.rs rename to shepherd/crates/cow-venue/tests/conformance.rs diff --git a/crates/cow-venue/tests/vectors/cow-header-goldens.json b/shepherd/crates/cow-venue/tests/vectors/cow-header-goldens.json similarity index 100% rename from crates/cow-venue/tests/vectors/cow-header-goldens.json rename to shepherd/crates/cow-venue/tests/vectors/cow-header-goldens.json diff --git a/crates/cow-venue/tests/vectors/cow-intent-body.json b/shepherd/crates/cow-venue/tests/vectors/cow-intent-body.json similarity index 100% rename from crates/cow-venue/tests/vectors/cow-intent-body.json rename to shepherd/crates/cow-venue/tests/vectors/cow-intent-body.json diff --git a/crates/cow-venue/tests/wit_layering.rs b/shepherd/crates/cow-venue/tests/wit_layering.rs similarity index 98% rename from crates/cow-venue/tests/wit_layering.rs rename to shepherd/crates/cow-venue/tests/wit_layering.rs index 4ccf59ed..6e26e1c7 100644 --- a/crates/cow-venue/tests/wit_layering.rs +++ b/shepherd/crates/cow-venue/tests/wit_layering.rs @@ -6,7 +6,7 @@ use std::path::Path; #[test] fn generic_wit_packages_never_reference_shepherd_cow() { - let wit_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../wit"); + let wit_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("../../../wit"); for pkg in std::fs::read_dir(&wit_root).expect("wit dir") { let pkg = pkg.expect("wit dir entry").path(); if pkg.file_name().is_some_and(|n| n == "shepherd-cow") { diff --git a/crates/shepherd/Cargo.toml b/shepherd/crates/shepherd/Cargo.toml similarity index 57% rename from crates/shepherd/Cargo.toml rename to shepherd/crates/shepherd/Cargo.toml index 1de15410..c5ed1b75 100644 --- a/crates/shepherd/Cargo.toml +++ b/shepherd/crates/shepherd/Cargo.toml @@ -13,9 +13,9 @@ name = "shepherd" path = "src/main.rs" [dependencies] -nexum-launch = { path = "../nexum-launch" } -nexum-runtime = { path = "../nexum-runtime" } -videre-host = { path = "../videre-host" } +nexum-launch = { path = "../../../nexum/crates/nexum-launch" } +nexum-runtime = { path = "../../../nexum/crates/nexum-runtime" } +videre-host = { path = "../../../videre/crates/videre-host" } anyhow.workspace = true tokio.workspace = true diff --git a/crates/shepherd/src/main.rs b/shepherd/crates/shepherd/src/main.rs similarity index 100% rename from crates/shepherd/src/main.rs rename to shepherd/crates/shepherd/src/main.rs diff --git a/modules/ethflow-watcher/Cargo.toml b/shepherd/modules/ethflow-watcher/Cargo.toml similarity index 79% rename from modules/ethflow-watcher/Cargo.toml rename to shepherd/modules/ethflow-watcher/Cargo.toml index 1902df84..790e747e 100644 --- a/modules/ethflow-watcher/Cargo.toml +++ b/shepherd/modules/ethflow-watcher/Cargo.toml @@ -10,8 +10,8 @@ repository.workspace = true crate-type = ["cdylib"] [dependencies] -nexum-sdk = { path = "../../crates/nexum-sdk" } -videre-sdk = { path = "../../crates/videre-sdk" } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk" } +videre-sdk = { path = "../../../videre/crates/videre-sdk" } cow-venue = { path = "../../crates/cow-venue", features = ["client", "assembly"] } cowprotocol = { version = "0.2.0", default-features = false } alloy-primitives = { version = "1.6", default-features = false, features = ["std"] } @@ -20,4 +20,4 @@ tracing = { version = "0.1", default-features = false } wit-bindgen = { version = "0.59", default-features = false, features = ["macros", "realloc"] } [dev-dependencies] -nexum-sdk-test = { path = "../../crates/nexum-sdk-test" } +nexum-sdk-test = { path = "../../../nexum/crates/nexum-sdk-test" } diff --git a/modules/ethflow-watcher/module.toml b/shepherd/modules/ethflow-watcher/module.toml similarity index 100% rename from modules/ethflow-watcher/module.toml rename to shepherd/modules/ethflow-watcher/module.toml diff --git a/modules/ethflow-watcher/src/keeper.rs b/shepherd/modules/ethflow-watcher/src/keeper.rs similarity index 99% rename from modules/ethflow-watcher/src/keeper.rs rename to shepherd/modules/ethflow-watcher/src/keeper.rs index 56bca16f..deed6689 100644 --- a/modules/ethflow-watcher/src/keeper.rs +++ b/shepherd/modules/ethflow-watcher/src/keeper.rs @@ -563,7 +563,7 @@ mod tests { /// EthFlow event. #[test] fn topic0_matches_the_cow_events_package_of_record() { - let wit = include_str!("../../../wit/shepherd-cow/cow-events.wit"); + let wit = include_str!("../../../../wit/shepherd-cow/cow-events.wit"); let expected = format!("{:#x}", OrderPlacement::SIGNATURE_HASH); assert!( wit.contains(&expected), diff --git a/modules/ethflow-watcher/src/lib.rs b/shepherd/modules/ethflow-watcher/src/lib.rs similarity index 100% rename from modules/ethflow-watcher/src/lib.rs rename to shepherd/modules/ethflow-watcher/src/lib.rs diff --git a/modules/twap-monitor/Cargo.toml b/shepherd/modules/twap-monitor/Cargo.toml similarity index 85% rename from modules/twap-monitor/Cargo.toml rename to shepherd/modules/twap-monitor/Cargo.toml index a9a91c9d..0b89463a 100644 --- a/modules/twap-monitor/Cargo.toml +++ b/shepherd/modules/twap-monitor/Cargo.toml @@ -11,8 +11,8 @@ crate-type = ["cdylib"] [dependencies] composable-cow = { path = "../../crates/composable-cow", features = ["run"] } cow-venue = { path = "../../crates/cow-venue", features = ["client"] } -nexum-sdk = { path = "../../crates/nexum-sdk" } -videre-sdk = { path = "../../crates/videre-sdk" } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk" } +videre-sdk = { path = "../../../videre/crates/videre-sdk" } cowprotocol = { version = "0.2.0", default-features = false } alloy-primitives = { version = "1.6", default-features = false, features = ["std"] } alloy-sol-types = { version = "1.6", default-features = false, features = ["std"] } @@ -25,4 +25,4 @@ serde_json = { version = "1", default-features = false, features = ["alloc"] } # Parses the shipped `module.toml` so the subscription parity test reads the # real `event_signature` value rather than scanning the file text. toml.workspace = true -nexum-sdk-test = { path = "../../crates/nexum-sdk-test" } +nexum-sdk-test = { path = "../../../nexum/crates/nexum-sdk-test" } diff --git a/modules/twap-monitor/module.toml b/shepherd/modules/twap-monitor/module.toml similarity index 100% rename from modules/twap-monitor/module.toml rename to shepherd/modules/twap-monitor/module.toml diff --git a/modules/twap-monitor/src/keeper.rs b/shepherd/modules/twap-monitor/src/keeper.rs similarity index 100% rename from modules/twap-monitor/src/keeper.rs rename to shepherd/modules/twap-monitor/src/keeper.rs diff --git a/modules/twap-monitor/src/lib.rs b/shepherd/modules/twap-monitor/src/lib.rs similarity index 100% rename from modules/twap-monitor/src/lib.rs rename to shepherd/modules/twap-monitor/src/lib.rs diff --git a/tools/baseline-latency/.gitignore b/shepherd/tools/baseline-latency/.gitignore similarity index 100% rename from tools/baseline-latency/.gitignore rename to shepherd/tools/baseline-latency/.gitignore diff --git a/tools/baseline-latency/baseline_latency.py b/shepherd/tools/baseline-latency/baseline_latency.py similarity index 100% rename from tools/baseline-latency/baseline_latency.py rename to shepherd/tools/baseline-latency/baseline_latency.py diff --git a/tools/baseline-latency/data/arbitrum_one.json b/shepherd/tools/baseline-latency/data/arbitrum_one.json similarity index 100% rename from tools/baseline-latency/data/arbitrum_one.json rename to shepherd/tools/baseline-latency/data/arbitrum_one.json diff --git a/tools/baseline-latency/data/base.json b/shepherd/tools/baseline-latency/data/base.json similarity index 100% rename from tools/baseline-latency/data/base.json rename to shepherd/tools/baseline-latency/data/base.json diff --git a/tools/baseline-latency/data/gnosis.json b/shepherd/tools/baseline-latency/data/gnosis.json similarity index 100% rename from tools/baseline-latency/data/gnosis.json rename to shepherd/tools/baseline-latency/data/gnosis.json diff --git a/tools/baseline-latency/data/mainnet.json b/shepherd/tools/baseline-latency/data/mainnet.json similarity index 100% rename from tools/baseline-latency/data/mainnet.json rename to shepherd/tools/baseline-latency/data/mainnet.json diff --git a/tools/baseline-latency/data/sepolia.json b/shepherd/tools/baseline-latency/data/sepolia.json similarity index 100% rename from tools/baseline-latency/data/sepolia.json rename to shepherd/tools/baseline-latency/data/sepolia.json diff --git a/tools/orderbook-mock/Cargo.toml b/shepherd/tools/orderbook-mock/Cargo.toml similarity index 100% rename from tools/orderbook-mock/Cargo.toml rename to shepherd/tools/orderbook-mock/Cargo.toml diff --git a/tools/orderbook-mock/src/main.rs b/shepherd/tools/orderbook-mock/src/main.rs similarity index 100% rename from tools/orderbook-mock/src/main.rs rename to shepherd/tools/orderbook-mock/src/main.rs diff --git a/crates/no-std-probe/Cargo.toml b/videre/crates/no-std-probe/Cargo.toml similarity index 100% rename from crates/no-std-probe/Cargo.toml rename to videre/crates/no-std-probe/Cargo.toml diff --git a/crates/no-std-probe/src/lib.rs b/videre/crates/no-std-probe/src/lib.rs similarity index 100% rename from crates/no-std-probe/src/lib.rs rename to videre/crates/no-std-probe/src/lib.rs diff --git a/crates/videre-host/Cargo.toml b/videre/crates/videre-host/Cargo.toml similarity index 86% rename from crates/videre-host/Cargo.toml rename to videre/crates/videre-host/Cargo.toml index e45d28d3..f2fd4a08 100644 --- a/crates/videre-host/Cargo.toml +++ b/videre/crates/videre-host/Cargo.toml @@ -11,7 +11,7 @@ workspace = true [dependencies] # The runtime seam this crate plugs into; the only nexum crate edge. -nexum-runtime = { path = "../nexum-runtime" } +nexum-runtime = { path = "../../../nexum/crates/nexum-runtime" } # Encoder for the opaque status body the host event stream carries; the # registry lowers an adapter-reported status through it. videre-status-body = { path = "../videre-status-body" } @@ -38,6 +38,6 @@ test-utils = [] # so `cargo test -p videre-host` sees `install_for_test` without every # invocation passing `--features test-utils`. videre-host = { path = ".", features = ["test-utils"] } -nexum-runtime = { path = "../nexum-runtime", features = ["test-utils"] } -nexum-tasks = { path = "../nexum-tasks" } +nexum-runtime = { path = "../../../nexum/crates/nexum-runtime", features = ["test-utils"] } +nexum-tasks = { path = "../../../nexum/crates/nexum-tasks" } tempfile.workspace = true diff --git a/crates/videre-host/src/bindings.rs b/videre/crates/videre-host/src/bindings.rs similarity index 93% rename from crates/videre-host/src/bindings.rs rename to videre/crates/videre-host/src/bindings.rs index 4ab7f121..df0a3625 100644 --- a/crates/videre-host/src/bindings.rs +++ b/videre/crates/videre-host/src/bindings.rs @@ -10,10 +10,10 @@ mod venue_adapter { wasmtime::component::bindgen!({ path: [ - "../../wit/videre-value-flow", - "../../wit/videre-types", - "../../wit/nexum-host", - "../../wit/videre-venue", + "../../../wit/videre-value-flow", + "../../../wit/videre-types", + "../../../wit/nexum-host", + "../../../wit/videre-venue", ], world: "videre:venue/venue-adapter", imports: { default: async }, @@ -42,10 +42,10 @@ mod client_host { } ", path: [ - "../../wit/videre-value-flow", - "../../wit/videre-types", - "../../wit/nexum-host", - "../../wit/videre-venue", + "../../../wit/videre-value-flow", + "../../../wit/videre-types", + "../../../wit/nexum-host", + "../../../wit/videre-venue", ], imports: { default: async }, with: { @@ -117,7 +117,7 @@ mod value_flow_smoke { import videre:value-flow/types@0.1.0; } ", - path: ["../../wit/videre-value-flow"], + path: ["../../../wit/videre-value-flow"], }); #[test] @@ -151,10 +151,10 @@ mod client_smoke { } ", path: [ - "../../wit/videre-value-flow", - "../../wit/videre-types", - "../../wit/nexum-host", - "../../wit/videre-venue", + "../../../wit/videre-value-flow", + "../../../wit/videre-types", + "../../../wit/nexum-host", + "../../../wit/videre-venue", ], }); diff --git a/crates/videre-host/src/client.rs b/videre/crates/videre-host/src/client.rs similarity index 100% rename from crates/videre-host/src/client.rs rename to videre/crates/videre-host/src/client.rs diff --git a/crates/videre-host/src/handshake.rs b/videre/crates/videre-host/src/handshake.rs similarity index 100% rename from crates/videre-host/src/handshake.rs rename to videre/crates/videre-host/src/handshake.rs diff --git a/crates/videre-host/src/lib.rs b/videre/crates/videre-host/src/lib.rs similarity index 100% rename from crates/videre-host/src/lib.rs rename to videre/crates/videre-host/src/lib.rs diff --git a/crates/videre-host/src/registry.rs b/videre/crates/videre-host/src/registry.rs similarity index 100% rename from crates/videre-host/src/registry.rs rename to videre/crates/videre-host/src/registry.rs diff --git a/crates/videre-host/tests/platform.rs b/videre/crates/videre-host/tests/platform.rs similarity index 97% rename from crates/videre-host/tests/platform.rs rename to videre/crates/videre-host/tests/platform.rs index e8e87411..883891b1 100644 --- a/crates/videre-host/tests/platform.rs +++ b/videre/crates/videre-host/tests/platform.rs @@ -32,14 +32,14 @@ const INTENT_STATUS: &str = "intent-status"; // ── fixtures + assembly ─────────────────────────────────────────────── -/// Workspace-root-relative path. `CARGO_MANIFEST_DIR` is -/// `crates/videre-host`; two parents up is the workspace root. +/// Path under the workspace root (the topmost ancestor with a `Cargo.toml`). fn workspace_path(relative: &str) -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .expect("crates dir") - .parent() - .expect("workspace root") + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + manifest + .ancestors() + .filter(|d| d.join("Cargo.toml").is_file()) + .last() + .unwrap_or(manifest) .join(relative) } @@ -409,7 +409,7 @@ async fn e2e_ethflow_watcher_boots_and_handles_intent_status() { let Some(wasm) = module_wasm_or_skip("ethflow-watcher") else { return; }; - let manifest = workspace_path("modules/ethflow-watcher/module.toml"); + let manifest = workspace_path("shepherd/modules/ethflow-watcher/module.toml"); let videre = Arc::new(platform(&EngineConfig::default())); let mut supervisor = boot_example(&videre, &wasm, &manifest).await; assert_eq!(supervisor.alive_count(), 1); @@ -583,13 +583,17 @@ async fn e2e_echo_module_registry_adapter_round_trip() { let config = EngineConfig { adapters: vec![AdapterEntry { path: adapter_wasm, - manifest: Some(workspace_path("modules/examples/echo-venue/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-venue/module.toml", + )), http_allow: Vec::new(), messaging_topics: Vec::new(), }], modules: vec![ModuleEntry { path: module_wasm, - manifest: Some(workspace_path("modules/examples/echo-client/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-client/module.toml", + )), }], ..Default::default() }; @@ -691,13 +695,17 @@ async fn e2e_keeper_module_drives_the_venue_through_the_typed_client() { let config = EngineConfig { adapters: vec![AdapterEntry { path: adapter_wasm, - manifest: Some(workspace_path("modules/examples/echo-venue/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-venue/module.toml", + )), http_allow: Vec::new(), messaging_topics: Vec::new(), }], modules: vec![ModuleEntry { path: module_wasm, - manifest: Some(workspace_path("modules/examples/echo-keeper/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-keeper/module.toml", + )), }], ..Default::default() }; @@ -774,13 +782,15 @@ async fn e2e_twap_monitor_boots_against_the_cow_adapter() { // Sepolia variant: twap-monitor pins chain 11155111, so the // adapter manifest must name the same chain for the pair to // submit to the right orderbook. - manifest: Some(workspace_path("crates/cow-venue/module.sepolia.toml")), + manifest: Some(workspace_path( + "shepherd/crates/cow-venue/module.sepolia.toml", + )), http_allow: Vec::new(), messaging_topics: Vec::new(), }], modules: vec![ModuleEntry { path: module_wasm, - manifest: Some(workspace_path("modules/twap-monitor/module.toml")), + manifest: Some(workspace_path("shepherd/modules/twap-monitor/module.toml")), }], ..Default::default() }; @@ -941,7 +951,9 @@ async fn boot_flaky_venue( let config = EngineConfig { adapters: vec![AdapterEntry { path: adapter_wasm, - manifest: Some(workspace_path("modules/fixtures/flaky-venue/module.toml")), + manifest: Some(workspace_path( + "videre/modules/fixtures/flaky-venue/module.toml", + )), http_allow: Vec::new(), messaging_topics: Vec::new(), }], diff --git a/crates/videre-host/tests/zero_leak.rs b/videre/crates/videre-host/tests/zero_leak.rs similarity index 90% rename from crates/videre-host/tests/zero_leak.rs rename to videre/crates/videre-host/tests/zero_leak.rs index 43f32ea5..f592a35b 100644 --- a/crates/videre-host/tests/zero_leak.rs +++ b/videre/crates/videre-host/tests/zero_leak.rs @@ -16,14 +16,14 @@ use nexum_runtime::test_utils::{ }; use videre_host::{VenueRegistry, platform}; -/// Workspace-root-relative path. `CARGO_MANIFEST_DIR` is -/// `crates/videre-host`; two parents up is the workspace root. +/// Path under the workspace root (the topmost ancestor with a `Cargo.toml`). fn workspace_path(relative: &str) -> PathBuf { - Path::new(env!("CARGO_MANIFEST_DIR")) - .parent() - .expect("crates dir") - .parent() - .expect("workspace root") + let manifest = Path::new(env!("CARGO_MANIFEST_DIR")); + manifest + .ancestors() + .filter(|d| d.join("Cargo.toml").is_file()) + .last() + .unwrap_or(manifest) .join(relative) } @@ -73,13 +73,17 @@ async fn e2e_echo_venue_boots_and_submits_through_the_generic_seam() { let config = EngineConfig { adapters: vec![AdapterEntry { path: adapter_wasm, - manifest: Some(workspace_path("modules/examples/echo-venue/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-venue/module.toml", + )), http_allow: Vec::new(), messaging_topics: Vec::new(), }], modules: vec![ModuleEntry { path: module_wasm, - manifest: Some(workspace_path("modules/examples/echo-client/module.toml")), + manifest: Some(workspace_path( + "videre/modules/examples/echo-client/module.toml", + )), }], ..Default::default() }; diff --git a/crates/videre-macros/Cargo.toml b/videre/crates/videre-macros/Cargo.toml similarity index 86% rename from crates/videre-macros/Cargo.toml rename to videre/crates/videre-macros/Cargo.toml index 7cf8ec6f..b2edd840 100644 --- a/crates/videre-macros/Cargo.toml +++ b/videre/crates/videre-macros/Cargo.toml @@ -13,7 +13,7 @@ proc-macro = true workspace = true [dependencies] -nexum-world = { path = "../nexum-world", features = ["macros"] } +nexum-world = { path = "../../../nexum/crates/nexum-world", features = ["macros"] } proc-macro2.workspace = true quote.workspace = true syn = { workspace = true, features = ["full"] } diff --git a/crates/videre-macros/src/intent_body.rs b/videre/crates/videre-macros/src/intent_body.rs similarity index 100% rename from crates/videre-macros/src/intent_body.rs rename to videre/crates/videre-macros/src/intent_body.rs diff --git a/crates/videre-macros/src/keeper.rs b/videre/crates/videre-macros/src/keeper.rs similarity index 100% rename from crates/videre-macros/src/keeper.rs rename to videre/crates/videre-macros/src/keeper.rs diff --git a/crates/videre-macros/src/lib.rs b/videre/crates/videre-macros/src/lib.rs similarity index 100% rename from crates/videre-macros/src/lib.rs rename to videre/crates/videre-macros/src/lib.rs diff --git a/crates/videre-macros/src/venue_marker.rs b/videre/crates/videre-macros/src/venue_marker.rs similarity index 100% rename from crates/videre-macros/src/venue_marker.rs rename to videre/crates/videre-macros/src/venue_marker.rs diff --git a/crates/videre-macros/src/world.rs b/videre/crates/videre-macros/src/world.rs similarity index 100% rename from crates/videre-macros/src/world.rs rename to videre/crates/videre-macros/src/world.rs diff --git a/crates/videre-sdk/Cargo.toml b/videre/crates/videre-sdk/Cargo.toml similarity index 94% rename from crates/videre-sdk/Cargo.toml rename to videre/crates/videre-sdk/Cargo.toml index acc8a57e..16e5b4dc 100644 --- a/crates/videre-sdk/Cargo.toml +++ b/videre/crates/videre-sdk/Cargo.toml @@ -27,7 +27,7 @@ videre-macros = { path = "../videre-macros" } # Host-neutral SDK layer this crate builds on: the `ChainHost` seam the # chain wrapper implements, the shared `Fault` vocabulary, and the # wasi:http `fetch` surface re-exported as `transport::http`. -nexum-sdk = { path = "../nexum-sdk" } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk" } # The venue status-body codec, re-exported as `videre_sdk::status_body`; # venue guests reach the `intent-status` decode path through here. videre-status-body = { path = "../videre-status-body" } @@ -42,4 +42,4 @@ wit-bindgen.workspace = true [dev-dependencies] # In-memory `LocalStoreHost` behind the keeper run tests. -nexum-sdk-test = { path = "../nexum-sdk-test" } +nexum-sdk-test = { path = "../../../nexum/crates/nexum-sdk-test" } diff --git a/crates/videre-sdk/src/adapter.rs b/videre/crates/videre-sdk/src/adapter.rs similarity index 100% rename from crates/videre-sdk/src/adapter.rs rename to videre/crates/videre-sdk/src/adapter.rs diff --git a/crates/videre-sdk/src/bindings.rs b/videre/crates/videre-sdk/src/bindings.rs similarity index 88% rename from crates/videre-sdk/src/bindings.rs rename to videre/crates/videre-sdk/src/bindings.rs index cf8cdd0b..71ec301e 100644 --- a/crates/videre-sdk/src/bindings.rs +++ b/videre/crates/videre-sdk/src/bindings.rs @@ -24,10 +24,10 @@ world sdk-imports { } ", path: [ - "../../wit/videre-value-flow", - "../../wit/videre-types", - "../../wit/nexum-host", - "../../wit/videre-venue", + "../../../wit/videre-value-flow", + "../../../wit/videre-types", + "../../../wit/nexum-host", + "../../../wit/videre-venue", ], world: "videre:sdk-shims/sdk-imports", generate_all, diff --git a/crates/videre-sdk/src/body.rs b/videre/crates/videre-sdk/src/body.rs similarity index 100% rename from crates/videre-sdk/src/body.rs rename to videre/crates/videre-sdk/src/body.rs diff --git a/crates/videre-sdk/src/client.rs b/videre/crates/videre-sdk/src/client.rs similarity index 100% rename from crates/videre-sdk/src/client.rs rename to videre/crates/videre-sdk/src/client.rs diff --git a/crates/videre-sdk/src/event.rs b/videre/crates/videre-sdk/src/event.rs similarity index 100% rename from crates/videre-sdk/src/event.rs rename to videre/crates/videre-sdk/src/event.rs diff --git a/crates/videre-sdk/src/faults.rs b/videre/crates/videre-sdk/src/faults.rs similarity index 100% rename from crates/videre-sdk/src/faults.rs rename to videre/crates/videre-sdk/src/faults.rs diff --git a/crates/videre-sdk/src/keeper.rs b/videre/crates/videre-sdk/src/keeper.rs similarity index 100% rename from crates/videre-sdk/src/keeper.rs rename to videre/crates/videre-sdk/src/keeper.rs diff --git a/crates/videre-sdk/src/lib.rs b/videre/crates/videre-sdk/src/lib.rs similarity index 100% rename from crates/videre-sdk/src/lib.rs rename to videre/crates/videre-sdk/src/lib.rs diff --git a/crates/videre-sdk/src/transport.rs b/videre/crates/videre-sdk/src/transport.rs similarity index 100% rename from crates/videre-sdk/src/transport.rs rename to videre/crates/videre-sdk/src/transport.rs diff --git a/crates/videre-sdk/src/value_flow.rs b/videre/crates/videre-sdk/src/value_flow.rs similarity index 100% rename from crates/videre-sdk/src/value_flow.rs rename to videre/crates/videre-sdk/src/value_flow.rs diff --git a/crates/videre-sdk/tests/adapter.rs b/videre/crates/videre-sdk/tests/adapter.rs similarity index 100% rename from crates/videre-sdk/tests/adapter.rs rename to videre/crates/videre-sdk/tests/adapter.rs diff --git a/crates/videre-status-body/Cargo.toml b/videre/crates/videre-status-body/Cargo.toml similarity index 100% rename from crates/videre-status-body/Cargo.toml rename to videre/crates/videre-status-body/Cargo.toml diff --git a/crates/videre-status-body/src/lib.rs b/videre/crates/videre-status-body/src/lib.rs similarity index 100% rename from crates/videre-status-body/src/lib.rs rename to videre/crates/videre-status-body/src/lib.rs diff --git a/crates/videre-test/Cargo.toml b/videre/crates/videre-test/Cargo.toml similarity index 91% rename from crates/videre-test/Cargo.toml rename to videre/crates/videre-test/Cargo.toml index 02198e5a..d53a82a6 100644 --- a/crates/videre-test/Cargo.toml +++ b/videre/crates/videre-test/Cargo.toml @@ -25,10 +25,10 @@ hex.workspace = true http.workspace = true # Transport seam vocabulary: `ChainHost`, `Fault`, and the `Fetch` seam # the mocks implement. -nexum-sdk = { path = "../nexum-sdk" } +nexum-sdk = { path = "../../../nexum/crates/nexum-sdk" } # `MockChain` is composed rather than reimplemented: one chain mock # serves both personas. -nexum-sdk-test = { path = "../nexum-sdk-test" } +nexum-sdk-test = { path = "../../../nexum/crates/nexum-sdk-test" } # The contract under test: `IntentBody`, `BodyError`, the intent # header types, and the `MessagingHost` seam. videre-sdk = { path = "../videre-sdk" } diff --git a/crates/videre-test/goldens/reference-header.json b/videre/crates/videre-test/goldens/reference-header.json similarity index 100% rename from crates/videre-test/goldens/reference-header.json rename to videre/crates/videre-test/goldens/reference-header.json diff --git a/crates/videre-test/src/codec.rs b/videre/crates/videre-test/src/codec.rs similarity index 100% rename from crates/videre-test/src/codec.rs rename to videre/crates/videre-test/src/codec.rs diff --git a/crates/videre-test/src/fixture.rs b/videre/crates/videre-test/src/fixture.rs similarity index 100% rename from crates/videre-test/src/fixture.rs rename to videre/crates/videre-test/src/fixture.rs diff --git a/crates/videre-test/src/header.rs b/videre/crates/videre-test/src/header.rs similarity index 100% rename from crates/videre-test/src/header.rs rename to videre/crates/videre-test/src/header.rs diff --git a/crates/videre-test/src/lib.rs b/videre/crates/videre-test/src/lib.rs similarity index 100% rename from crates/videre-test/src/lib.rs rename to videre/crates/videre-test/src/lib.rs diff --git a/crates/videre-test/src/reconcile.rs b/videre/crates/videre-test/src/reconcile.rs similarity index 100% rename from crates/videre-test/src/reconcile.rs rename to videre/crates/videre-test/src/reconcile.rs diff --git a/crates/videre-test/src/reference.rs b/videre/crates/videre-test/src/reference.rs similarity index 100% rename from crates/videre-test/src/reference.rs rename to videre/crates/videre-test/src/reference.rs diff --git a/crates/videre-test/src/report.rs b/videre/crates/videre-test/src/report.rs similarity index 100% rename from crates/videre-test/src/report.rs rename to videre/crates/videre-test/src/report.rs diff --git a/crates/videre-test/src/transport.rs b/videre/crates/videre-test/src/transport.rs similarity index 100% rename from crates/videre-test/src/transport.rs rename to videre/crates/videre-test/src/transport.rs diff --git a/crates/videre-test/tests/conformance.rs b/videre/crates/videre-test/tests/conformance.rs similarity index 100% rename from crates/videre-test/tests/conformance.rs rename to videre/crates/videre-test/tests/conformance.rs diff --git a/crates/videre-test/vectors/reference-body.json b/videre/crates/videre-test/vectors/reference-body.json similarity index 100% rename from crates/videre-test/vectors/reference-body.json rename to videre/crates/videre-test/vectors/reference-body.json diff --git a/modules/examples/echo-client/Cargo.toml b/videre/modules/examples/echo-client/Cargo.toml similarity index 92% rename from modules/examples/echo-client/Cargo.toml rename to videre/modules/examples/echo-client/Cargo.toml index c5c20896..c2288cc6 100644 --- a/modules/examples/echo-client/Cargo.toml +++ b/videre/modules/examples/echo-client/Cargo.toml @@ -13,7 +13,7 @@ workspace = true crate-type = ["cdylib"] [dependencies] -nexum-sdk = { path = "../../../crates/nexum-sdk" } +nexum-sdk = { path = "../../../../nexum/crates/nexum-sdk" } # The venue status-body codec the `on_custom` handler decodes an # intent-status transition through, reached via `videre_sdk::status_body`. videre-sdk = { path = "../../../crates/videre-sdk" } diff --git a/modules/examples/echo-client/module.toml b/videre/modules/examples/echo-client/module.toml similarity index 100% rename from modules/examples/echo-client/module.toml rename to videre/modules/examples/echo-client/module.toml diff --git a/modules/examples/echo-client/src/lib.rs b/videre/modules/examples/echo-client/src/lib.rs similarity index 100% rename from modules/examples/echo-client/src/lib.rs rename to videre/modules/examples/echo-client/src/lib.rs diff --git a/modules/examples/echo-keeper/Cargo.toml b/videre/modules/examples/echo-keeper/Cargo.toml similarity index 90% rename from modules/examples/echo-keeper/Cargo.toml rename to videre/modules/examples/echo-keeper/Cargo.toml index ff843e85..de13587b 100644 --- a/modules/examples/echo-keeper/Cargo.toml +++ b/videre/modules/examples/echo-keeper/Cargo.toml @@ -13,6 +13,6 @@ workspace = true crate-type = ["cdylib"] [dependencies] -nexum-sdk = { path = "../../../crates/nexum-sdk" } +nexum-sdk = { path = "../../../../nexum/crates/nexum-sdk" } videre-sdk = { path = "../../../crates/videre-sdk" } wit-bindgen = { version = "0.59", default-features = false, features = ["macros", "realloc"] } diff --git a/modules/examples/echo-keeper/module.toml b/videre/modules/examples/echo-keeper/module.toml similarity index 100% rename from modules/examples/echo-keeper/module.toml rename to videre/modules/examples/echo-keeper/module.toml diff --git a/modules/examples/echo-keeper/src/lib.rs b/videre/modules/examples/echo-keeper/src/lib.rs similarity index 100% rename from modules/examples/echo-keeper/src/lib.rs rename to videre/modules/examples/echo-keeper/src/lib.rs diff --git a/modules/examples/echo-venue/Cargo.toml b/videre/modules/examples/echo-venue/Cargo.toml similarity index 100% rename from modules/examples/echo-venue/Cargo.toml rename to videre/modules/examples/echo-venue/Cargo.toml diff --git a/modules/examples/echo-venue/module.toml b/videre/modules/examples/echo-venue/module.toml similarity index 100% rename from modules/examples/echo-venue/module.toml rename to videre/modules/examples/echo-venue/module.toml diff --git a/modules/examples/echo-venue/src/lib.rs b/videre/modules/examples/echo-venue/src/lib.rs similarity index 100% rename from modules/examples/echo-venue/src/lib.rs rename to videre/modules/examples/echo-venue/src/lib.rs diff --git a/modules/fixtures/flaky-venue/Cargo.toml b/videre/modules/fixtures/flaky-venue/Cargo.toml similarity index 100% rename from modules/fixtures/flaky-venue/Cargo.toml rename to videre/modules/fixtures/flaky-venue/Cargo.toml diff --git a/modules/fixtures/flaky-venue/module.toml b/videre/modules/fixtures/flaky-venue/module.toml similarity index 100% rename from modules/fixtures/flaky-venue/module.toml rename to videre/modules/fixtures/flaky-venue/module.toml diff --git a/modules/fixtures/flaky-venue/src/lib.rs b/videre/modules/fixtures/flaky-venue/src/lib.rs similarity index 100% rename from modules/fixtures/flaky-venue/src/lib.rs rename to videre/modules/fixtures/flaky-venue/src/lib.rs