docs/book/src/architecture/decisions/ADR-002-trait-driven-extensibility.md
This is a retroactive record of a decision made before the formal ADR process. The exact original decision date is not available in this record; the date above is the date this ADR was added to the architecture docs.
This record was drafted from
FND-002 §6.3,
the current zeroclaw-api trait surfaces, and the crate and
tool-boundary docs. It was not recovered from an older ADR file.
ZeroClaw needs many extension families: model providers, messaging channels, tools, memory backends, observability sinks, runtime adapters, and hardware peripherals. Each family has different IO, error, configuration, security, and lifecycle constraints, but each must still compose into the same agent runtime.
Without explicit contracts, every integration would pressure the runtime loop to grow special cases. That would make new integrations faster at first and harder to maintain later: provider routing would leak into channels, tool policy would leak into providers, channel authentication would leak into the agent loop, and memory or logging behavior would be copied across unrelated crates.
The repository already uses zeroclaw-api as the public contract layer.
The architecture docs describe that crate as the kernel ABI and state
that the runtime depends on traits rather than concrete
implementations.
First-party extension families use explicit Rust trait contracts in
zeroclaw-api and are wired through the existing factory, registry,
composition, or host-provided boundary for that surface.
The primary contracts include:
ModelProvider for model-provider clients;Channel for inbound and outbound messaging surfaces;Tool for agent-callable capabilities;Memory and MemoryStrategy for persistence and recall;Observer for runtime telemetry;RuntimeAdapter for host-runtime capabilities;Peripheral for hardware and board surfaces.Shared behavior belongs at the trait, factory, registry, policy, config, logging, or lower-layer helper boundary when multiple implementations need it. An individual integration should not patch the runtime loop or add parallel state only to make one provider, channel, tool, or backend work.
This ADR covers first-party in-process extension surfaces. It does not replace the plugin, WIT, MCP, or skill-package boundaries for out-of-process or independently distributed capabilities.
Positive consequences:
Negative consequences:
Follow-up decisions:
crates/zeroclaw-api/src/model_provider.rscrates/zeroclaw-api/src/channel.rscrates/zeroclaw-api/src/tool.rscrates/zeroclaw-api/src/memory_traits.rscrates/zeroclaw-api/src/observability_traits.rscrates/zeroclaw-api/src/runtime_traits.rscrates/zeroclaw-api/src/peripherals_traits.rs