Docs / Plugins Build
Plugin Architecture
The extension points EKOS actually has, and how they map to source, compiler, knowledge and query plugins.
EKOS has traits, not a dynamic plugin loader: you write a Rust crate and build an ekos binary that includes it. The seam is EkosExtension (RFC 0149); the public binary is simply main_with(Extensions::none()).
| Plugin kind | Mechanism | Trait / hook |
|---|---|---|
| Source | new connector | Observer (observation-sdk), via EkosExtension::observers |
| Compiler | new analysis | CompilerPass, via EkosExtension::recovery_passes; SQL dialects via SqlDialectParser |
| Knowledge | post-commit enrichment | EkosExtension::after_commit over the committed ledger |
| Query | new MCP tools | EkosExtension::mcp_tools + call_mcp_tool |
| Provider | LLM or embedding backend | LlmProvider, EmbeddingProvider |
Why traits and not dynamic loading
Determinism and auditability. A statically linked extension is versioned with the binary, its logic_version is part of the build fingerprint, and the ledger records which pipeline wrote what.
Constraints
- Extension crates depend on public crates; public crates never depend on extensions.
after_commitfutures are notSend(#[async_trait(?Send)]).- Extension MCP tools are read-only: they receive the same cached store handle as the built-in read tools.