Skip to content

feat(wit-abi): add the fault vocabulary and SDK HostFault surface#213

Open
mfw78 wants to merge 1 commit into
fix/m0-mock-hardeningfrom
feat/fault-vocabulary
Open

feat(wit-abi): add the fault vocabulary and SDK HostFault surface#213
mfw78 wants to merge 1 commit into
fix/m0-mock-hardeningfrom
feat/fault-vocabulary

Conversation

@mfw78

@mfw78 mfw78 commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #207, part of the typed-fault train stacked on the epic-80 stack, merges in stack order.

Adds the shared fault vocabulary that later host interfaces will embed as a case, plus the SDK-side mirror that module authors program against.

Changes

  • wit/nexum-host/types.wit: added variant fault with the seven specified cases (unsupported, unavailable, denied, rate-limited, timeout, invalid-input, internal) and record rate-limit { retry-after-ms: option<u64> }, both alongside the existing untouched host-error record.
  • crates/nexum-sdk/src/host.rs: mirrored Fault (thiserror #[error] per case, IntoStaticStr with snake_case labels, #[non_exhaustive]), the RateLimit struct, and the HostFault trait (fault(&self) -> Option<&Fault>, label(&self) -> &'static str) with a reflexive impl on Fault itself.
  • Rebuilt the module wasms in-tree (example, twap-monitor, ethflow-watcher, price-alert, balance-tracker, stop-loss, http-probe, flaky-bomb, fuel-bomb, memory-bomb, panic-bomb) so the supervisor e2e tests resolve them, since the wit path was touched.

No host interface or consumer moves onto Fault yet and host-error is not removed. That migration is deliberately out of scope here and lands in the next PRs in the stack.

Test plan

  • cargo fmt --all --check
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features --no-fail-fast (new tests host::tests::fault_labels_are_stable_snake_case and host::tests::host_fault_is_object_safe both pass)
  • wasm-tools component wit wit/nexum-host round-trips the package with the new variant and record present

Notes for reviewer

RateLimit derives Copy, Default, and Hash since it is a single Option<u64>; Fault itself stays Clone only because it carries String payloads.

label() delegates to IntoStaticStr via self.into() so the snake_case set has one source of truth, and the test pins all seven labels plus the rate_limited underscore form.

Object safety is proven rather than asserted: host_fault_is_object_safe boxes a dyn HostFault so both trait methods are checked as dispatchable.

Follow-ups intentionally not implemented here: migrating host interfaces onto typed per-interface errors that embed Fault, retiring host-error once every consumer has moved, and adding From/TryFrom between the wit-bindgen-generated Fault and the SDK Fault once the first consumer interface lands.

There is one pre-existing duplicated_attributes clippy lint in nexum-sdk's proptests.rs/lib.rs that only surfaces under the host's rustc 1.92 rather than the project-pinned 1.94; it is untouched by this diff and present on the base commit.

AI Assistance: Claude Code (Opus 4.8 implementation and adversarial review, Sonnet 5 PR authoring) used for the full change.

Add a fault variant and rate-limit record to nexum:host/types alongside
the existing host-error record, with no consumers moving yet. The
richer per-interface errors that follow embed fault as a shared,
payload-bearing failure case.

Mirror Fault and RateLimit in nexum-sdk with thiserror, snake_case
IntoStaticStr labels and non_exhaustive, plus a HostFault trait that
recovers the embedded fault and a stable label from a richer error.
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