What this project is actually about
Adytum is a research prototype, and the honest framing is that the interesting parts are not the autonomous behaviour. They are the four systems problems underneath it. Each one has a well-understood analogue in ordinary backend engineering, which is why the project was worth building.
Tiered delegation, because planners that act will loop
A single process that both decides what to do and does it has a predictable failure mode: it retries a task it cannot complete, forever, with no external signal that anything is wrong.
The runtime splits that into three tiers with enforced boundaries. The top tier holds the goal and is programmatically prevented from calling any tool: its only legal output is a delegation plan. The middle tier orchestrates workflows and fans work out in parallel batches. The bottom tier is ephemeral executors that do one thing and report back.
The important word is programmatically. An instruction not to loop is a suggestion. A runtime in which the planning tier has no tool-calling capability at all makes the loop structurally impossible, which is the difference between a guardrail and a wish.
Two persistence layers, because there are two questions
The system needs to answer "what happened recently that resembles this?" and "what do we know to be true?". Those are a relevance search and a graph traversal. They want different indexes, different write paths and different retention rules.
So there are two stores. An episodic log in SQLite, indexed with FTS5 and vector retrieval, holds every message, call and intermediate step; retrieval is by relevance to the current context. A fact graph holds discrete entity-relationship claims extracted from that log: durable, small, and queried directly rather than searched.
A consolidation pass runs during idle time: it compacts verbose history into summaries and promotes stable observations from the log into the graph. It is the same pattern as an analytics rollup job, and it exists for the same reason: the raw log grows without bound and the useful shape of it does not.
Hot reload, because a restart is a failed abstraction
Capabilities are plugins. A loader scans the workspace for manifests at runtime; a filesystem watcher triggers a live refresh of the tool registry and the runtime's instruction set when a plugin changes on disk.
Dependency guards are the part that matters in practice. A plugin declares what it needs (an operating system, a binary on the path, an API secret) and stays inactive if any of it is missing. The alternative is a capability that registers successfully and then fails at the moment it is first used, which is a much more expensive way to find out.
Lifecycle management on one machine
The runtime is self-hosted, so the compute budget is fixed and small. Capping concurrency would make the system fail sharply at a threshold. Instead, idle workers are serialised to disk and evicted from memory, restored on demand; completed ones are moved to an append-only historical log for later inspection.
The result degrades under load rather than breaking, which is the property you want when the ceiling is one box and there is no autoscaler to call.
The event backbone
Work is not only request-driven. Scheduled heartbeats evaluate progress against long-running goals, idle periods trigger the consolidation pass, and filesystem sensors turn external changes, such as a new commit or a modified file, into scheduled work. It is a job queue with a cron and a watcher attached, and describing it that way is more useful than describing it as autonomy.
Stack: Node.js, Fastify and TypeScript with constructor injection; SQLite with FTS5 for the episodic layer and JSON-backed storage for lifecycle state; a Next.js control surface over Socket.io streaming live runtime metrics.