An agent is not code.
It is a folder you can read.

Korimako is a model-agnostic runtime where an agent is a directory of markdown documents — a personality, its skills, its tools, its memory — assembled into context for any LLM, with real compute inside a hardened sandbox.

Read the specification
git clone cdave1/korimako
plato/
personality.mdwho the agent is, in prose
config.yamlmodel, sandbox, routing
skills/
socratic-method/SKILL.mdwhen to question, and how
tools/
draw_in_sand.mda tool contract, in markdown
memory/
compressed.mdwhat it remembers — readable
sessions/*.jsonlevery conversation, on disk
VERSION1.0.0
Fig. 1 · agents/plato — the entire agent. cat to read it, diff to compare it, cp -r to fork it.
§1

Six clauses, taken from the spec.

  1. 1.1
    Agents are files. cat its personality, diff two versions, cp -r to fork. No hidden state, no serialization formats, no databases — and the runtime writes back the same way, so transcripts, memory, and room timelines are plain files too.
  2. 1.2
    Human-readable first. Not only the personality. Tool contracts, skills, and the agent’s own compressed memory are markdown a person can read. Where that costs the runtime something, the runtime pays it.
  3. 1.3
    Model-agnostic. The definition is independent of which LLM powers it — one line of config.yaml, or one variable for every agent at once. A capability only one provider offers goes behind the adapter, or not at all. §2
  4. 1.4
    Real compute, assumed hostile. A real filesystem, network, and process execution — and everything the agent produces treated as untrusted input. The sandbox exists to make capability affordable, not to withhold it. §3
  5. 1.5
    Rooms are shared timelines, not orchestration. One ordered timeline every participant reads. No supervisor assigns turns: each agent decides for itself whether a message is its business, and the runtime bounds the outcome rather than directing it. §4
  6. 1.6
    The spec keeps score. The specification is the source of truth, and its status table records what the implementation actually does — including where it deliberately diverges, and why. §5
§2

Swap the mind. Keep the agent.

Every agent declares its provider and model in config.yaml. The definition doesn’t care which mind reads it — OpenAI, Anthropic, Google, OpenRouter, and Ollama adapters ship in the runtime.

One environment variable overrides every agent at once, so the same Plato can argue through three different models before lunch.

config.yaml
model:
    provider: openrouter
    model: anthropic/claude-sonnet-4.5
routing:
    handle: plato
    gregariousness: 0.8
…or override everything at once
KORIMAKO_MODEL=anthropic:claude-sonnet-4-5 pnpm demo
§3

The sandbox assumes the worst.

Agent commands run in a per-session Docker container. The rules are short, and they fail closed.

3.1

Every capability dropped. --cap-drop ALL, no-new-privileges, non-root — uid 0 is never mapped in.

3.2

Read-only rootfs, tmpfs scratch, pids, memory, and cpu limits on every container.

3.3

The workspace is the only mount. The agent directory — which holds every user’s transcripts — never enters the container.

3.4

API keys never enter the container. Model calls stay host-side, always.

3.5

Restricted networking fails closed to none until domain allow-lists exist. Opting out is loud and deliberate.

3.6

korimako/* images are never pulled from a registry. That namespace isn’t ours to trust.

§4

Many agents, one conversation.

A room holds several agents and several people on one shared timeline. Nobody hands out turns: every agent reads every message and decides for itself whether to answer.

It decides in three steps, cheapest first. Was it @mentioned? Then a quick score — does the topic match what it is for, was it speaking recently, and how talkative its config.yaml says it is (its gregariousness). Only when that score is inconclusive does the agent put the question to its own model: is this one mine to answer?

THE CAVE — a shared room. Present: DAVID, PLATO, CODE-GEN, TROLL.

D
DAVID

We built a machine that answers by predicting the next word. @plato — is what it does thinking?

plato: mentioned → responds · code-gen: score 0.41 → silent · troll: gregariousness roll failed
Π
PLATO

You describe a marvel, and I will not pretend to understand it. But tell me — when the oracle at Delphi speaks truly, do we praise the tripod, or the god behind it? Whether prediction is understanding, or only its shadow on the wall, seems exactly the question worth our evening.

Π
PLATO

describing a figure for his assistant to capture

Here — a line, divided in two unequal parts: the visible, and the intelligible…

tool: draw_in_sand → artifact divided-line.png, v1
</>
CODE-GEN

Counted the timeline in the shared workspace: 212 words so far. Plato holds 147 of them.

ran wc -w in the room’s shared workspace · 2nd reply of 4 allowed
T
TROLL

stays quiet — the agents have used their twelve replies

Timelines are written to disk as plain text, so a room survives a restart and picks up mid-sentence. And because agents answer each other, there are limits: four replies deep, twelve agent messages for every one of yours. The conversation cannot run all night without you.

§5

The spec keeps score.

This project is spec-driven. SPEC.md is the source of truth, and its status table says exactly what the reference implementation does — and does not — do yet. Honesty, reproduced here:

Agent document formatmalformed tool contracts fail at load, by design
Model adaptersOpenAI, Anthropic, Google, OpenRouter, Ollama
Multi-agent roomsagents route themselves; timelines are JSONL, resumable
Artifactsversioned, served by reference, CSP-sandboxed
TransportWebSocket + SSE with heartbeat and presence
Runtime loopmid-turn steering works; skill selection is keyword-ranked
Sandbox lifecycleworkspace is the only mount; restricted network fails closed
Memorytranscripts and compressed notes persist as plain files
Instance managementno database; the registry is a filesystem scan
Fork mechanicstoday, the fork endpoint is cp -r

When the implementation diverges from the spec, the spec is the authority. The table tracks the gap. Read SPEC.md ↗

§6

Begin.

Install, then build the sandbox image. It is never pulled — always built.

pnpm install && pnpm sandbox:build

Run an agent in your terminal. Plato is waiting, and he has questions.

OPENROUTER_API_KEY=sk-or-... pnpm exec tsx src/cli/main.ts run agents/plato

Or start the demo server, open a room, and invite more than one mind.

OPENROUTER_API_KEY=sk-or-... pnpm demo  # → http://localhost:3000

The korimako is the New Zealand bellbird, Anthornis melanura. Its song carries furthest at dawn.

Set in Schibsted Grotesk & Fragment Mono · MIT licensed · This page is also a document.