Skip to content

feat(modules): module.toml for twap-monitor + ethflow-watcher (BLEU-834)#11

Open
brunota20 wants to merge 3 commits into
dev/m2-basefrom
feat/m2-module-manifests-bleu-834
Open

feat(modules): module.toml for twap-monitor + ethflow-watcher (BLEU-834)#11
brunota20 wants to merge 3 commits into
dev/m2-basefrom
feat/m2-module-manifests-bleu-834

Conversation

@brunota20

Copy link
Copy Markdown
Collaborator

Summary

Per ADR-0001, two manifests:

twap-monitor / module.toml

  • `capabilities.required = ["logging", "local-store", "chain", "cow-api"]` — matches the Rust imports the BLEU-826 / -827 / -828 paths exercise.
  • `[[subscription]]` log on Sepolia (chain id `11155111`) against ComposableCoW `0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74` with topic-0 = `keccak256("ConditionalOrderCreated(address,(address,bytes32,bytes))")` = `0x2cceac5555b0ca45a3744ced542f54b56ad2eb45e521962372eef212a2cbf361`.
  • `[[subscription]]` block on Sepolia for the BLEU-827 poll loop.

ethflow-watcher / module.toml

  • Same capability set (`chain` reserved for a future eth_call to read the EthFlow refund pointer, without churning the manifest later).
  • `[[subscription]]` log on Sepolia against CoWSwapEthFlow production `0xbA3cB449bD2B4ADddBc894D8697F5170800EAdeC` with topic-0 = `keccak256("OrderPlacement(address,(address,address,address,uint256,uint256,uint32,bytes32,uint256,bytes32,bool,bytes32,bytes32),(uint8,bytes),bytes)")` = `0xcf5f9de2984132265203b5c335b25727702ca77262ff622e136baa7362bf1da9`.

Both `[capabilities.http].allow` lists stay empty — all outbound HTTP flows through the `cow-api` capability (host-pinned orderbook URL).

`component` is the 0.2 placeholder all-zero sha256; 0.3 validates it against the loaded component bytes.

Sequencing

BLEU-834 lives next to (not inside) the skeletons:

The PR branches from `dev/m2-base` so reviewers see just the two manifests. When dev/m2-base accumulates the two skeleton merges, this PR rebases cleanly.

Linear: BLEU-834. Ref ADR-0001.

Test plan

  • TOML parses against the engine's `Manifest` schema (`crates/nexum-engine/src/manifest/types.rs`): module / capabilities / capabilities.http / [[subscription]] log + block, with the discriminator `kind` matching the `Subscription` enum's lowercase tag.
  • End-to-end `cargo run -p nexum-engine -- target/wasm32-wasip2/release/{twap_monitor,ethflow_watcher}.wasm modules/{twap-monitor,ethflow-watcher}/module.toml` — gated on PRs feat(twap-monitor): workspace + skeleton (BLEU-825) #2 / feat(ethflow-watcher): workspace + skeleton (BLEU-831) #8 (skeletons) being on the same base, plus a Sepolia RPC entry in engine.toml.

Per ADR-0001 (module.toml schema), authored for the two M2
modules:

twap-monitor / module.toml
- capabilities.required = ["logging", "local-store", "chain",
  "cow-api"] — matches the Rust imports the BLEU-826/827/828
  paths exercise.
- [[subscription]] log on Sepolia (chain_id 11155111) against
  ComposableCoW (0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74)
  with topic-0 keccak256(
    "ConditionalOrderCreated(address,(address,bytes32,bytes))"
  ) = 0x2cceac5555b0ca45a3744ced542f54b56ad2eb45e521962372eef212a2cbf361.
- [[subscription]] block on Sepolia for the BLEU-827 poll loop.

ethflow-watcher / module.toml
- Same capability set (chain reserved for a future eth_call —
  e.g. read the EthFlow refund pointer — without churning the
  manifest).
- [[subscription]] log on Sepolia against CoWSwapEthFlow
  production (0xbA3cB449bD2B4ADddBc894D8697F5170800EAdeC) with
  topic-0 keccak256(
    "OrderPlacement(address,(address,address,address,uint256,uint256,
     uint32,bytes32,uint256,bytes32,bool,bytes32,bytes32),
     (uint8,bytes),bytes)"
  ) = 0xcf5f9de2984132265203b5c335b25727702ca77262ff622e136baa7362bf1da9.

Both [capabilities.http].allow stay empty: all outbound HTTP
flows through the cow-api capability, which routes via the
host's pinned orderbook URL.

The content hash field is the 0.2 placeholder all-zero sha256;
0.3 will validate it against the loaded component bytes.

Linear: BLEU-834. Ref ADR-0001.
@linear-code

linear-code Bot commented Jun 15, 2026

Copy link
Copy Markdown

BLEU-834

Three threads from the internal review mirror of upstream nullislabs/shepherd PR #17:

1. ethflow-watcher/module.toml capabilities: move `chain` from required to optional. The comment on the original manifest already said the module does not call `chain` today; declaring it as required widened the grant for a capability the module does not exercise. Optional keeps "future-proofing" (BLEU-855 can use it without manifest churn) without violating least-privilege.

2. ethflow-watcher/module.toml subscription comment: soften the "identical on every chain" claim. cow-rs::ETH_FLOW_PRODUCTION is identical across chains today, but unlike ComposableCoW's CREATE2 address EthFlow has had multiple per-network and per-version deployments historically. Multi-chain config in M5 must re-check per `chain_id` instead of assuming the address carries. Address itself stays unchanged: 0xbA3cB449bD2B4ADddBc894D8697F5170800EAdeC is verified against the live Sepolia deployment (event firing observed in the COW-1064 dry-run on 2026-06-18 + cow-rs canonical constant + multiple load-test runs).

3. README.md module manifest example: the documented `address` field said `0xC92E8bdf79f0507f65a392b0ab4667716BFE0110` labeled "ComposableCoW", but that is the GPv2VaultRelayer (per scripts/lib.sh). ComposableCoW is `0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74`. Fixed the address; expanded the comment to clarify it is the canonical CREATE2 address (same on every supported chain).

Stays on `feat/m2-module-manifests-bleu-834` as a stacked branch so upstream PR #17 + internal mirror PR #54 can see the fixes as a separate, atomic commit.

AI assistance disclosure: drafted by Claude (Opus 4.7, 1M context).
…ance)

Filtered subset of the compliance applied in PRs #66/#67 of bleu/nullis-shepherd,
restricted to files that exist on the M2 epic head. M3+ files (shepherd-sdk, examples,
backtest, deploy artifacts) and M4-coupled hunks (ProviderError typed-source variants,
JoinSet reconnect tasks, supervisor restart helper) are skipped — they land via their
own upstream PRs.

Brings M2 epic in line with the repo-wide rust rubric (typed errors, no anyhow in libs,
em-dash sweep, #[non_exhaustive] on public error enums).

AI Assistance: Claude Code (Opus 4.7) applied a filtered patch derived from PR #67 in
the bleu fork. A human (Bruno) is accountable for the result.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant