The microkernel that orchestrates Pons modules.
The smallest seed of a thinking system.
The kernel is a thin process orchestrator. It has five responsibilities β and only these:
- Message Bus β in-memory pub/sub forwarding between modules. No persistence, no queue. Fire-and-forget.
- Module Lifecycle β spawn, kill, restart, hot-swap. Each module runs as an isolated child process.
- RPC Routing β direct IPC routing for request/response between modules, with timeouts and origin validation.
- Service Directory β dynamic discovery of module-provided services via
provides/requiresdeclarations. - Configuration β layered YAML config with schema validation, hot-reload via
SIGUSR1, and per-module config sections.
Everything else lives in modules.
βββββββββββββββββββββββββββββββββββββββββββββββ
β Kernel β
β β
β βββββββββββββ ββββββββββββ βββββββββββββ β
β β Message β β Lifecycleβ β Service β β
β β Bus β β Manager β β Directory β β
β βββββββ¬ββββββ ββββββ¬ββββββ βββββββ¬ββββββ β
β β β β β
ββββββββββΌββββββββββββββΌββββββββββββββββΌββββββββ
β β β
ββββββ΄βββ βββββββ΄βββ ββββββββ΄βββ
β Agent β β LLM β β Gateway β ...modules
β β β β β β
βββββββββ ββββββββββ βββββββββββ
process process process
Modules never import each other. All communication flows through the kernel via IPC.
The recommended way to install Pons is via the CLI:
deno install -gA jsr:@pons/cliThen start the kernel:
pons startIf you need just the kernel without the CLI:
deno install -gA -n pons-kernel jsr:@pons/kernelpons-kernel # start
pons-kernel --log debug # verbose loggingModules communicate through topics. A module declares which topics it subscribes to in its manifest, and publishes messages to any topic.
Module A ββpublish("llm:generate", payload)βββΆ Kernel ββdeliverβββΆ Module B
The bus is pure routing β no persistence, no retry. If a module needs delivery guarantees, it implements them itself.
For request/response patterns, modules use RPC through the kernel's service directory:
Agent ββrpc_request(service: "providerRegistry", method: "generate")βββΆ Kernel βββΆ LLM
βββrpc_response(result)ββββββββββββββββββββββββββββββββββββββββββ Kernel βββ LLM
The kernel resolves the service name to a module ID, forwards the request, and routes the response back. Timeout: 30s.
- Kernel discovers modules from
~/.pons/modules/ - Each module is spawned as a child process with its own
deno.json - Module sends
readyβ kernel checksrequiresdependencies - When all required services are available β kernel sends
deps_ready - Health checks run every 30s via
ping/pong - On crash: exponential backoff restart (max 5 attempts)
Layered YAML config at ~/.pons/config.yaml:
logging:
level: info
levels:
agent: debug
models:
providers:
- id: anthropic
type: anthropicModules declare a configKey in their manifest. When that section changes, the kernel pushes config:update to the module. Hot-reload: send SIGUSR1 to the kernel process.
Every module has a module.json:
{
"id": "llm",
"name": "LLM Services",
"description": "Provider registry, model routing, cost tracking",
"provides": ["providerRegistry", "model-router", "cost-tracker"],
"subscribes": ["llm:generate", "llm:stream:request"],
"requires": [],
"optionalRequires": ["http-router"],
"configKey": "models",
"configSchema": "./src/config.schema.ts",
"priority": 5
}| Field | Description |
|---|---|
id |
Unique module identifier |
provides |
Services this module exposes for RPC |
subscribes |
Bus topics this module listens to |
requires |
Services that must be available before activation |
optionalRequires |
Services the module can use but doesn't need to start |
configKey |
Top-level config section this module owns |
configSchema |
Path to Zod schema for config validation |
priority |
Spawn order (lower = earlier) |
Built-in methods available to modules via call:
| Method | Params | Returns |
|---|---|---|
config.get |
{ key: string } |
Config value |
config.set |
{ key: string, value: unknown } |
{ success: boolean } |
config.sections |
β | Available config sections |
module.list |
β | All registered modules |
module.commands |
β | CLI commands from modules |
service.discover |
β | All registered services |
service.resolve |
{ service: string } |
Module ID providing the service |
src/
βββ index.ts # Entry point β CLI flags, boot, start
βββ kernel.ts # Kernel class: boot/start/shutdown
βββ lifecycle.ts # Spawn/kill/hot-swap, RPC routing, health checks
βββ messaging/
β βββ bus.ts # In-memory pub/sub registry
βββ module/
β βββ loader.ts # Module discovery from filesystem
β βββ registry.ts # Module tracking + service directory
βββ config/
β βββ manager.ts # Config CRUD, schema discovery, validation
β βββ types.ts # Config types
βββ logs/
β βββ logger.ts # Logger factory + module log forwarding
βββ formatters.ts # Shared formatting utilities
deno task dev # Watch mode
deno task start # Production
deno check src/index.ts # Type checkSee CONTRIBUTING.md for guidelines.