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
2 changes: 1 addition & 1 deletion docs/02-modules-events-packaging.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ A module is distributed as a **bundle** - a WASM component plus a manifest that

### Manifest (`module.toml`)

Every module ships with a manifest. The file is named `module.toml` in 0.2 (was `module.toml` in earlier drafts; per [ADR-0001](adr/0001-engine-toml-separate-from-nexum-toml.md) the operator/module split is now explicit).
Every module ships with a manifest. The file is named `module.toml` in 0.2 (was `nexum.toml` in earlier drafts; per [ADR-0001](adr/0001-engine-toml-separate-from-nexum-toml.md) the operator/module split is now explicit).

```toml
[module]
Expand Down
2 changes: 2 additions & 0 deletions docs/adr/0007-upstream-protocol-logic-to-cow-rs.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,5 @@ Lower-priority follow-ons (`OrderUid::from_slice`, retry middleware on `OrderBoo
- Guest modules consume `cowprotocol` types directly (gated on the wasm32 feature in item 3). The `shepherd-sdk` crate in M3 may add ergonomic wrappers on top, but those live on the guest side, not behind a WIT boundary.
- A follow-on Bleu module - the Rust-side equivalent of `cowprotocol/refunder` (permissionless `invalidateOrder` triggering for expired EthFlow orders) - becomes natural to ship once an ethflow-watcher module lands. Out of scope for M2 but explicitly enabled by the same primitives.
- TWAP polling logic (decode `ConditionalOrderCreated`, eth_call `getTradeableOrderWithSignature`, decode return, build `OrderCreation`) and EthFlow event decoding stay entirely in guest module code. The `cowprotocol` crate provides only the types and the orderbook client; the strategy is the module's.

_Errata: `crates/nexum-engine` was renamed to `crates/nexum-runtime` + `crates/nexum-cli` in the 0.2 refactor. The `cowprotocol` crate now publishes to crates.io (the workspace pins `0.2.0`), so the PR-#5-head consumption model above is historical; a `[patch.crates-io]` git override to `nullislabs/cow-rs` remains active pending a release with the hash-only `OrderCreationAppData` constructor - see the comment above the patch block in the root `Cargo.toml` for the current state._
29 changes: 11 additions & 18 deletions docs/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,26 +151,19 @@ For systemd-style production runs, see `docs/production.md`.

## Docker

A reference Dockerfile + Compose file is planned for M5.
Until that lands, build manually:

```dockerfile
# (sketch — full Dockerfile is planned for M5)
FROM rust:1.91 as build
COPY . /src
WORKDIR /src
RUN cargo build --release -p nexum-cli
RUN rustup target add wasm32-wasip2 \
&& cargo build --target wasm32-wasip2 --release \
-p twap-monitor -p ethflow-watcher

FROM gcr.io/distroless/cc-debian12
COPY --from=build /src/target/release/nexum /usr/local/bin/
COPY --from=build /src/target/wasm32-wasip2/release/*.wasm /modules/
COPY engine.toml /etc/shepherd/engine.toml
ENTRYPOINT ["/usr/local/bin/nexum"]
A `Dockerfile` + `docker-compose.yml` ship at the repo root. See
[`docs/deployment/docker.md`](deployment/docker.md) for the full
container workflow. The quick start:

```sh
cp .env.example .env
$EDITOR .env # paste wss:// RPC URLs
docker compose up -d
```

The image is published to
`ghcr.io/nullislabs/shepherd:<tag>` on every merged commit to `main`.

Mount the `state_dir` as a volume so the redb file survives container
restarts.

Expand Down
47 changes: 8 additions & 39 deletions docs/production.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,45 +140,14 @@ journalctl -u shepherd -f --output=json | jq '.MESSAGE | fromjson?'

## 3. Container deploy: Docker Compose

> **Status note:** the official Dockerfile is tracked as a
> separate issue. Until it lands, build the image locally with
> the multi-stage recipe below; the Compose file is forward-
> compatible with the eventual published image.

### 3.1 Dockerfile (interim)

```dockerfile
# syntax=docker/dockerfile:1.6
FROM rust:1.86-slim-bookworm AS build
WORKDIR /src
RUN apt-get update && apt-get install -y --no-install-recommends \
pkg-config libssl-dev cmake clang \
&& rm -rf /var/lib/apt/lists/*
RUN rustup target add wasm32-wasip2
COPY . .
RUN cargo build -p nexum-cli --release
# Build all 5 modules. Add yours here.
RUN cargo build -p twap-monitor --target wasm32-wasip2 --release \
&& cargo build -p ethflow-watcher --target wasm32-wasip2 --release \
&& cargo build -p price-alert --target wasm32-wasip2 --release \
&& cargo build -p balance-tracker --target wasm32-wasip2 --release \
&& cargo build -p stop-loss --target wasm32-wasip2 --release

FROM debian:bookworm-slim AS runtime
RUN apt-get update && apt-get install -y --no-install-recommends \
ca-certificates tini \
&& rm -rf /var/lib/apt/lists/* \
&& useradd -r -s /usr/sbin/nologin -d /var/lib/shepherd shepherd \
&& install -d -o shepherd -g shepherd /var/lib/shepherd
COPY --from=build /src/target/release/nexum /usr/local/bin/
COPY --from=build /src/target/wasm32-wasip2/release/*.wasm /opt/shepherd/modules/
COPY --from=build /src/modules /opt/shepherd/manifests
USER shepherd
WORKDIR /var/lib/shepherd
EXPOSE 9100
ENTRYPOINT ["/usr/bin/tini", "--", "nexum"]
CMD ["--engine-config", "/etc/shepherd/engine.toml"]
```
### 3.1 Dockerfile

The official multi-stage `Dockerfile` ships at the repo root - it
builds the `nexum` binary, compiles all five module wasms, and runs as
a non-root user under `tini`. Build it with `docker build -t shepherd .`
or let the root `docker-compose.yml` build it for you. The full image
reference (published tags, pinning, .env wiring) is in
[`docs/deployment/docker.md`](deployment/docker.md).

### 3.2 docker-compose.yml

Expand Down
2 changes: 1 addition & 1 deletion docs/qa-signoff.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
| `cargo test --workspace` | ✅ | 145 host tests + 1 doctest passing. |
| Em-dashes in `crates/`, `modules/`, `docs/` | ✅ | 0. One was in `price-alert/strategy.rs:4` (mine), fixed. |
| Em-dashes in `wit/**.wit` | ⚠ | 3 in mfw78's M1 prose. Intentionally left alone; flag for him in upstream review. |
| `warn(unused_crate_dependencies)` on every crate root | ✅ | sdk, sdk-test, nexum-engine, twap, ethflow, price-alert, balance-tracker, stop-loss. |
| `warn(unused_crate_dependencies)` on every crate root | ✅ | sdk, sdk-test, nexum-runtime, twap, ethflow, price-alert, balance-tracker, stop-loss. |
| WASM build (`wasm32-wasip2 --release`) | ✅ | All 5 modules build. Sizes: twap 314 KB, ethflow 282 KB, stop-loss 311 KB, price-alert 215 KB, balance-tracker 102 KB. |
| String-wrapped errors outside WIT boundary | ✅ | All hits in `crates/nexum-runtime/src/host/impls/*` (FFI boundary - exception per rust-idiomatic skill). No leaks in SDK or modules. |

Expand Down
11 changes: 7 additions & 4 deletions docs/sdk.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,10 @@ The SDK crates are currently `0.1.0` and live at `crates/nexum-sdk/`
and `crates/shepherd-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 at `0.1.0`; the
workspace declares `cowprotocol = "0.1.0"` in `[workspace.dependencies]`
with no `[patch.crates-io]` or git overrides. Module Cargo.toml files
that inherit from the workspace pick it up automatically.
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.
Loading