Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
70 changes: 35 additions & 35 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -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"

Expand Down
12 changes: 6 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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. |
Expand Down
4 changes: 2 additions & 2 deletions docs/00-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion docs/01-runtime-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions docs/02-modules-events-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.<id>]` 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<tuple<string, string>>`); 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

Expand Down
2 changes: 1 addition & 1 deletion docs/03-module-discovery.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions docs/05-sdk-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
```

Expand Down Expand Up @@ -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

Expand Down
4 changes: 2 additions & 2 deletions docs/06-production-hardening.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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:

Expand Down
2 changes: 1 addition & 1 deletion docs/07-rpc-namespace-design.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Loading
Loading