Developer and ArchitectureReference

Architecture deep-dive

The subsystem map and a recommended reading order, retold as data-flow traces.

On this page
  1. What this page is for
  2. Subsystem map
  3. Recommended reading order
  4. Trace one. An interactive request
  5. Trace two. A self-improving cycle
  6. Going deeper

What this page is for

A map for someone arriving at the codebase for the first time. The System index is the catalog that lists every subsystem flat with its path; this page is the path. It shows what to read first and how one request actually flows through the code.

Subsystem map

Production source has three responsibilities: core/ owns the GEODE runtime and operator surface, evals/ owns measurement and audit, and evolve/ owns scaffold search and hill-climbing. Dependencies flow only as evolve → evals → core.

Self-Improving  evolve/scaffold_search/  train.py + measure/fitness/gate/ledger + loop/{mutate,observe,inject}
Agent           core/agent/           AgenticLoop (while tool_use), sub_agent, system_prompt
Harness         core/cli/             thin CLI + commands/ + IPC client
                core/server/          serve daemon: ipc_server (CLIPoller) + supervised (messenger pollers)
                core/messaging/       binding-based gateway routing
                core/hooks/           public hooks, trusted middleware, runtime events
                core/orchestration/   LaneQueue, TaskGraph, compaction, tool offload
                core/scheduler/       cron/event triggers + scheduled jobs
                core/wiring/          bootstrap injection (container, bootstrap, scheduling)
                core/ui/              terminal rendering (event_renderer, latex)
Runtime         core/tools/           tool registry + deferred loading + PolicyChain
                core/mcp/             MCP client (manager, stdio_client)
                core/memory/          5-tier context + session stores
                core/skills/          skill registry
                core/llm/prompts/     prompt templates + hash pins
                core/audit/           audit-result extraction (dim_extractor)
                core/observability/   SQLite session/events, run projections, trajectories, OTLP
                core/config/          Settings + layer resolution (explain)
                core/auth/            OAuth, profiles, cooldown
Model           core/llm/             router + adapter registry
                core/llm/providers/   Anthropic / OpenAI / Codex / GLM

A few entry modules sit at the top level: GeodeRuntime in core/runtime.py is the bootstrap, core/paths.py resolves every directory path in one place, and core/mcp_server.py is the geode-mcp entry point. For why the layer boundaries fall where they do, see Why five layers.

  1. The two loops. The mental model the rest of the docs build on. Start here.
  2. The five-layer stack. What each layer owns and where its responsibility ends.
  3. The inner agentic loop. The while(tool_use) primitive and the paths that end a turn.
  4. Context assembly. Where each LLM call's context is built.
  5. Sub-agent orchestration. Isolated parallel lanes and merge on completion.
  6. Hooks and observability. How observe and act stack on one event.
  7. The outer loop. The self-improving cycle through mutate, audit, gate, promote.

If operating and configuring is the goal, go instead to Configuration basics and Serve and gateway.

Trace one. An interactive request

geode  (thin REPL, core/cli/)
   │  free text → IPCClient.send_prompt  (~/.geode/cli.sock)
   ▼
CLIPoller  (core/server/ipc_server/poller.py)  ── acquires session + global lanes
   ▼
AgenticLoop  (core/agent/loop/agent_loop.py)
   ▼  each round
system prompt + context assembly  (core/agent/system_prompt.py + core/memory/)
   ▼
LLM call  (core/llm/router/ → core/llm/providers/)
   ▼
tool requested?  ── yes → run core/tools/ → observe result → next round
   │
   └ no → stream the answer  (core/ui/event_renderer.py)

The thin CLI does no work itself. It connects over IPC to the geode serve daemon, and the single GeodeRuntime inside the daemon runs the task. Each round, the memory tiers and prompt layers merge into a context, the router picks an adapter, and when the model requests a tool the registry runs it. The paths that end a turn are detailed in The inner agentic loop.

Trace two. A self-improving cycle

auto-trigger or operator  (core/wiring/scheduling.py → loop/auto_trigger.py)
   ▼
propose + apply a mutation  (evolve/scaffold_search/loop/mutate/runner.py, 7 behaviour kinds)
   ▼
Petri audit subprocess  (measure.py → geode-eval audit → evals/petri/)
   │  measures the same AgenticLoop with the mutated scaffold injected
   │  via GEODE_WRAPPER_OVERRIDE
   ▼
fitness  (fitness.py: 22-dim judge scores → one scalar)
   ▼
margin gate  (gate.py)
   ├ pass → promote: update baseline.json + append baseline_archive.jsonl  (ledger.py)
   └ fail → revert: restore the SoT to its pre-mutation value

The two loops share code but meet through a record. The audit runs the same AgenticLoop as the thing being measured, and only gate-passing mutations are promoted, leaving their lineage in git-tracked ledgers. There is no weight update anywhere. The fullflow is in The outer loop; the measurement framework is in Petri × GEODE.

Going deeper

Moved from the GEODE repository’s documentation site. Source commit de077a4 · View the source on GitHub