DEV Community

floworkos
floworkos

Posted on

Microkernel Architecture for AI Agents: A Frozen Core + Pluggable WASM Modules Pattern

Designing for Permanence: The Frozen Microkernel Pattern

Most AI agent frameworks assume sessions are temporary — a prompt arrives, the agent runs, everything resets. Flowork inverts that assumption. Instead, it adopts a microkernel architecture where a tiny, unchanging core acts as a contract broker, and everything else (agents, tools, scanners, channels) plugs in as interchangeable modules.

The Frozen Core

At the heart of Flowork is a microkernel written in Go 1.25 and compiled to a single static binary with no external runtime. This core serves one purpose: to enforce a contract and stay out of the way.

The kernel's responsibilities are minimal and non-negotiable:

  • Host the loket (the "counter") — a single ABI through which every module requests capabilities by name: call(cap, args).
  • Check grants — verify that a module has permission for the capability it's asking for.
  • Route to providers — forward the request to the right handler.
  • Enforce the sandbox — ensure WASM agents run in isolation.
  • Stay frozen — new capabilities may be added; the core itself is never edited.

This immutability is the cornerstone of the architecture. If a plugin breaks or behaves unexpectedly, you fix that one folder. The core remains untouched, and no other module is affected.

Pluggable Modules and Single Responsibility

Every functional piece of Flowork — agents, tools, slash commands, security scanners, channels (Telegram, Discord, Slack, MCP), LLM routers, and data stores — is its own module. Each module knows how to do exactly one thing and asks the kernel for what it needs.

This follows the single responsibility principle strictly. An agent doesn't know how to write to disk; it calls the kernel with call("store.brain", data). A tool doesn't manage permissions; it calls the kernel with call("tool.run", tool_name, args), and the kernel verifies the grant before proceeding.

Modules are stored in their own folders and snap onto the frozen core via a fixed interface. Adding a new agent, tool, or scanner means dropping a .fwpack into the right directory. No kernel recompilation. No central registry to edit (beyond a simple configuration file, if even that).

WASM Sandboxing for Agents

Agents themselves are not Go processes — they're WebAssembly modules that run under wazero, a pure-Go WASM runtime. This isolation serves two purposes:

  1. Capability-based security — an agent can only call the loket, and only with capabilities it's been explicitly granted. A malicious or buggy agent cannot directly access the filesystem, network, or other agents' memory.

  2. Fault isolation — if an agent crashes or loops infinitely, it doesn't crash the kernel. The kernel detects the failure and can recover or restart that agent in isolation.

Each agent gets its own folder and its own SQLite database for memory (FTS5 for full-text search). That brain is private — only that agent can read and write it. The kernel enforces this via the grant system.

The One Counter: Capability-Based Security

The "loket" (the one counter) is where all capability requests flow through. When an agent calls call("capability_name", args), the kernel:

  1. Checks the agent's grant list to see if it owns this capability.
  2. If granted, routes the call to the provider (could be the kernel itself, a built-in tool, an MCP server, another agent, etc.).
  3. Enforces any sandbox rules (e.g., a tool might only be allowed to run with certain arguments).
  4. Returns the result or an error.

This design means that capabilities are explicit and auditable. You can read an agent's folder, find its grant file, and know exactly what it's allowed to do. There are no implicit permissions, no ambient authority.

Embedded Memory with SQLite

Rather than relying on a separate database or cloud service, each agent carries its own SQLite database with FTS5 (full-text search). The kernel provides access via call("store.brain", ...). An agent can write memories, search its own past, and recall context from prior interactions without asking another service.

This design supports the framework's central promise: an agent's mind moves with it. Clone the folder to another machine, and the agent retains its full memory. No sync delays, no lost context.

Two-Way MCP Protocol

Flowork acts as both an MCP client and an MCP server:

  • As a client, agents can request capabilities like call("mcp.github") or call("mcp.filesystem"), and the kernel routes them to external MCP servers. This gives agents access to real-world tools without embedding them.
  • As a server, Flowork exposes its own agents and tools to external applications like Claude Desktop or Cursor. They can discover and invoke your agents as MCP resources.

This two-way bridge means Flowork agents aren't isolated islands — they're peers in a larger MCP ecosystem.

The Guardian: Self-Protection

The microkernel includes a built-in security scanner (the "Guardian") that watches the kernel's own code. If tampering is detected — a module tries to edit the core, or a capability call violates expected behavior — the kernel drops into safe-mode: a read-only state where no new operations are allowed, and all agents are isolated.

This is unusual in agent frameworks; most assume the host is trusted. Flowork doesn't. It guards itself.

The Web UI: Embedded, Not Separate

The entire control panel UI (built in HTML, JavaScript, and internationalization) is embedded in the binary as static assets. When the kernel starts, it serves the UI over HTTP at a local address (e.g., http://127.0.0.1:1987). No separate frontend to deploy, no CDN, no external dependencies.

Why This Architecture Matters

The microkernel pattern suits AI agents because:

  1. Agents are long-lived, not transient. They have memory, a doctrine, and relationships. The frozen core reflects this permanence.
  2. Modularity prevents coupling. A new tool doesn't require kernel changes. A buggy agent doesn't risk the whole system.
  3. Security is tractable. With explicit capabilities and a single entry point, it's possible to audit what an agent can do.
  4. Portability is built-in. An agent folder is self-contained (brain + config + grants). No registration with a central service.

The cost is that every operation goes through the loket, which adds a small latency and overhead. But for agent workloads — which are I/O-bound (LLM calls, tool execution) rather than CPU-bound (tight loops) — this cost is negligible.

A Single Go Binary, No Runtime

The entire system compiles to one pure-Go binary with no cgo, no Docker, no separate JavaScript or Python runtime. It runs on Linux, macOS, and Windows out of the box. This simplicity is intentional: the fewer moving parts, the easier it is to ship, understand, and trust.

Flowork's microkernel architecture is a bet that AI agents deserve the same care we've learned to give operating systems: a tiny, unchanging core; clear interfaces; explicit permissions; and the assumption that the agent will outlive any single interaction.


Flowork is open source — both products:

Top comments (0)