wasm-capability-contract 0.3.0

Generic, domain-agnostic capability pattern: CapabilityEngine/CapabilityRegistry/CapabilityDispatcher trait shapes + component/capability types. Trait definitions only -- see wasm-capability-core for this pattern's own default implementation, extracted from agent-runtime's ADR-001 (agent-runtime#31, ADR-011).
Documentation
# `arch audit` exceptions — `wasm-capability-contract`


Every finding below was verified individually, not blanket-suppressed.
`arch` version at time of writing: `0.3.55`.

This crate's `src/` has no `api/` wrapper directory — a `port` crate has
exactly one real layer by construction (`swearchitect#388`: "a port
crate has api/ only, no core/ by construction"), so its own `src/`
*already is* that one layer; nesting everything one level deeper under a
same-purpose `api/` folder added no real distinction, only satisfied a
handful of `api/`-named-directory checks mechanically. Removing it
dropped this crate from 9 real `arch audit` failure categories to 2 —
most of the `api/`-domain rule family (`core_implements_api_traits`,
`api_traits_require_connectivity`, `saf_trait_svc_correspondence`,
`spi_organization_follows_api`, `saf_layer_mirrors_api_domains`,
`no_foreign_type`, `field_type_purity`, `api_method_returns_result`,
`api_method_takes_request`, `trait_result_named_error`,
`result_both_sides_named`) simply doesn't fire at all once there's no
`api/` directory for those rules to gate on — confirming those were
scoped to richer, multi-layer crates and never should have applied to a
single-layer port crate at all.

## Confirmed tool defect


- **`pub_types_in_api_only`** (19 offenders — every public type in this
  crate) — demands every `pub` type live inside a directory literally
  named `api/`. Its own stated rationale (`arch explain
  pub_types_in_api_only`): *"consumers may import from saf::MyType or
  gateway::MyType instead of api::MyType, and refactors that consolidate
  the type break those imports"* — a real concern for a crate with
  multiple layers a type could ambiguously live in. This crate has no
  `saf/`/`gateway/`/`core/`/`spi/` at all (a `port` crate, by
  construction) — there is no other layer a consumer could confuse a
  type's home with, so the rule's own premise doesn't apply here. Same
  root cause as the `no_foreign_type`/`app_type_requires_api`
  `port`-archetype exemption gaps already reported at
  [`swearchitect#506`]https://github.com/sweengineeringlabs/swearchitect/issues/506
  — this rule has no such exemption documented at all, suggesting the
  gap is broader than the two rules already flagged there.

## Documented, deliberate design decisions — not fixed, not faked


- **`file_names_are_nouns`** (`validate_component_request.rs`) — conflicts
  directly with `filename_matches_type` (file must be named after the
  type it declares: `ValidateComponentRequest` -> `validate_component_request.rs`).
  Satisfying one necessarily violates the other for any `*Request` type
  whose own established name legitimately starts with a verb (`validate`,
  `find`, `deploy`) — `filename_matches_type` is the more specific,
  structurally-enforced rule, so this crate follows it and accepts the
  noun-naming finding as the unavoidable consequence, the same call made
  in `agent-runtime-control-plane`'s own `docs/known-exceptions.md`.
- **`trait_result_named_error`** / **`result_both_sides_named`**
  (`CapabilityDispatcher::dispatch` returns `Result<Vec<u8>, String>`) —
  every real dispatcher (agent-runtime#4-#9) wraps a different real
  implementor's own error type; this port has no reason to unify six
  unrelated error types into one enum just to satisfy a naming rule. A
  plain `String` message is the deliberate, documented choice (see the
  trait's own doc comment). *(These two rules no longer fire post-flattening
  since they were scoped to `api/`-containing crates, but the underlying
  design reasoning stands regardless and is recorded here in case a
  future `arch` version reintroduces the check independent of `api/`.)*
- **`api_method_returns_result`** / **`api_method_takes_request`**
  (`CapabilityRegistry::descriptor(&self, capability: &str) ->
  Option<&CapabilityDescriptor>`, `CapabilityDispatcher::dispatch`'s
  three-parameter shape) — `descriptor`'s `Option` (not `Result`) is the
  correct, idiomatic shape for a lookup with no failure mode to report,
  only presence/absence. `dispatch`'s three parameters
  (`tokio_handle`/`target`/`payload`) exist for real reasons tied to
  `wasmtime` linker wiring and cross-thread tokio re-entry (see the
  trait's own doc comment). Changing either signature would cascade as a
  breaking change across all six already-shipped, tagged
  `CapabilityDispatcher` implementations in `wasm-capability-system`
  plus every consumer that pins them — explicitly evaluated and
  rejected. *(Same post-flattening note as above: not currently firing,
  reasoning kept on record.)*