Protocol System
Kernle uses a protocol-based composition architecture. Instead of one monolithic class, an entity is assembled from interchangeable components that communicate through defined interfaces.The Entity is the Composition
No single component is the entity. The entity emerges from the composition of all its parts:- Core (Entity) coordinates everything — routes operations, manages lifecycle
- Stack (SQLiteStack) stores and retrieves memories — self-contained, portable
- Plugins add capabilities — commerce, communications, analytics
- Model provides thinking — generates text, embeds vectors
- Components extend the stack — embedding, forgetting, emotional tagging
Five Protocols
Every major component implements a protocol — a PythonProtocol class that defines its interface contract.
| Protocol | Role | Default Implementation | Analogy |
|---|---|---|---|
| CoreProtocol | Bus / coordinator | Entity | Torso — connects everything |
| StackProtocol | Memory container | SQLiteStack | Head — stores knowledge |
| PluginProtocol | Capability extension | installed plugins | Limbs — reach into the world |
| ModelProtocol | Thinking engine | AnthropicModel, OllamaModel | Heart — drives behavior |
| StackComponentProtocol | Stack sub-plugin | Embedding, Forgetting, etc. | Organs — internal functions |
| Interface | Role |
|---|---|
| InferenceService | Narrow model access for stack components (infer + embed) |
| PluginContext | What the core provides to plugins (mediated memory access) |
Why Protocols?
Interchangeability. Swap SQLiteStack for anotherStackProtocol implementation without changing anything else. Replace Anthropic with Ollama and the entity keeps its memories but thinks differently.
Testability. Every protocol can be tested against a contract test suite. If your custom implementation passes the contract tests, it works with the system.
Clean boundaries. Plugins never touch stack internals. Stacks never see models directly. Components hook into the stack lifecycle without coupling to specific storage backends.
Graceful degradation. No model bound? Stack components that need inference skip their work instead of crashing. No stack attached? Plugins get None from memory operations and handle it.
Entry Point Discovery
Components find each other through Python’simportlib.metadata entry points. Each component type registers in a specific group:
| Entry Point Group | Discovers |
|---|---|
kernle.plugins | Plugin implementations |
kernle.stacks | Stack implementations |
kernle.models | Model implementations |
kernle.stack_components | Stack component implementations |
pyproject.toml:
Protocol Version
All protocols share a single version number (PROTOCOL_VERSION = 1 in protocols.py). Plugins declare which version they were built against. The core checks compatibility on load:
- Plugin version matches core: load normally
- Plugin version is older: load with a warning
- Plugin version is newer than core: refuse to load (core is too old)
Dive Deeper
CoreProtocol
The coordinator — stack management, plugin lifecycle, operation routing.
StackProtocol
The memory container — write, read, search, components, and working memory.
PluginProtocol
Building extensions — lifecycle, tools, entry points, and a tutorial.
ModelProtocol
The thinking engine — generate, stream, embed, and capabilities.