Skip to main content
How extensibility works today. HyphaeDB is extended through trait seams — the core depends on an interface, and a concrete implementation is selected at startup — and through the typed PluginRegistry over those seams: config-driven selection per extension point ([plugins.<point>].use), per-plugin readiness probes, a boot audit record of the active set, and hyphae.plugin.* metrics. Extension points remain compile-time and config-time; what stays future (dynamic loading, WASM, sidecars, a marketplace) is noted at the end.
HyphaeDB’s core logic — the gossip walk, the energy model, layer promotion — is written against interfaces, not concrete backends. Each interface is a Rust trait with Send + Sync bounds; the server picks one implementation of each at boot and wires it in. This is what lets the same engine run against Postgres or an in-memory double, embed with a local model or a hosted API, and rate-limit in one process or across a cluster — without touching the code that gossips knowledge.

The showcase: swappable embedders

The clearest example is embedding. The EmbeddingEngine trait has five shipped implementations, and which one runs is a configuration choice: Point the config at a different backend and the entire mesh embeds differently — nothing in the gossip or promotion code changes, because it only ever sees EmbeddingEngine.

The seam catalog

The interfaces you can implement or select, and what each abstracts: Two properties fall out of this design and are worth calling out, because they’re the reason the seams stay clean:
  • Zero-overhead defaults. A seam that isn’t wired uses a no-op (the PropagationObserver default, for instance, makes the gossip walk byte-for-byte identical to having no observer at all). You never pay for an extension point you don’t use.
  • No dependency inversion. Seams that a lower crate must emit into — like the mesh emitting TrustChange audit events — are defined as narrow traits in hyphae-core, so hyphae-mesh never takes a dependency on hyphae-server. The interface lives below both.

Adding an implementation

The shape is the same for every seam:
1

Implement the trait

Write a type that implements the seam’s trait (e.g. EmbeddingEngine). Its methods are the only surface the core will ever call.
2

Construct it at boot

The server builds each backend from configuration in one place (the build_* constructors the build_server path calls). Add your backend as a variant the builder can select.
3

Select it by config

Choose the implementation with a configuration value (or a Cargo feature for compile-time-optional backends, like the NLI contradiction classifier). A selected backend the build did not compile is refused at boot by the wiring preflight (hyphae-server check verifies it without booting). The rest of the system depends only on the trait, so nothing else changes.
Because the whole system is written against the trait, a new backend is additive — it can’t change how gossip, promotion, or the energy model behave.

The plugin registry

The seams are managed by a typed PluginRegistry. You select a plugin per extension point in config — [plugins.<point>].use = "<name>" — and the server resolves the full set once at boot: an unknown plugin name is a fail-closed boot error, never a silent fallback. Each selected plugin gets its own plugin.<point> readiness probe on /readyz, the resolved extension-point → plugin set is recorded as a synchronous PluginSelected audit row — a durable record of what code was active at boot — and the hyphae.plugin.* metrics cover selection, init duration and failures, and health. Because resolution happens once at boot, the registry adds zero hot-path overhead, and the Production deployment profile additionally gates which selections may boot.

What isn’t here (yet)

The framework is static: implementations are compiled in and resolved at startup. There is deliberately no dynamic plugin system — no runtime discovery, no third-party dynamic libraries, no WASM or sidecar isolation, no plugin marketplace. That keeps the security surface small and the build reproducible. Dynamic loading, WASM plugins, sidecar processes, and a marketplace are proposed as a separate ecosystem phase; until then, the registry and the seams above are the supported way to extend HyphaeDB, and they cover the backends most deployments need to swap.

See also