Architecture
go-code is a local-first coding agent runtime. At the center is harnessd, a long-running HTTP daemon that boots the full agent runtime — LLM providers, tools, memory, cron, MCP, skills, and workflow orchestration — and exposes it over a REST + Server-Sent Events (SSE) API. Clients (the interactive TUI, the harnesscli one-shot command, or any external service) talk to that daemon over HTTP. Above the daemon sit optional orchestration layers — the Workflow Engine, Go Relay, and Symphony — that compose, route, and dispatch runs at higher levels of abstraction.
Runs & Conversations
A run is one discrete unit of agent work: the harness receives a prompt, executes LLM turns and tool calls, and produces a final output. Every run is independent by default, but you can link runs together into a conversation so the agent remembers what happened before. This page explains the run lifecycle, how conversation_id stitches runs together, and how to steer or inspect a run while it is active.
Tools & Permissions
The agent runtime exposes a catalog of tools — Go functions that an LLM can call to read files, run shell commands, search the web, spawn subagents, and more. Not every tool is visible to the LLM at once. Instead, the catalog is split into two tiers: a compact core set that is always present, and a larger deferred set that is hidden until the agent activates what it needs. On top of that, every run has a permission model that governs filesystem access and whether humans must approve tool calls before they execute.
Workspaces & Isolation
A workspace is the isolated execution environment in which one agent run operates. It bundles together a filesystem directory, a reachable harnessd HTTP endpoint, and (for some backends) managed git state. Workspaces are set up and torn down by the orchestration layer — the agent loop itself never manages its own workspace.
Providers & Routing
go-code can talk to ten different LLM backends — OpenAI, Anthropic, DeepSeek, Groq, xAI, Kimi, Qwen, Together AI, OpenRouter, and Google Gemini — through a single unified interface. Every provider, every model, and every pricing rate is described in a JSON catalog (catalog/models.json) that the server loads at startup. This page explains how that catalog works, how go-code decides which provider to use for a given run, and how it tracks and caps spending.
Event Model
Every agent run in go-code communicates progress through a stream of Server-Sent Events (SSE). When you start a run with POST /v1/runs, the server assigns it an ID, queues it, and starts executing it asynchronously. You then connect to GET /v1/runs//events to receive a real-time feed of everything that happens: when the LLM was called, which tools ran, how many tokens were used, and finally whether the run succeeded or failed.
Skills, Profiles, Subagents
Skills, profiles, and subagents are the three composition primitives in go-code. They let you
Memory
The harness ships two complementary memory subsystems that let agents remember facts and task state across turns and across separate runs. Observational memory watches the conversation transcript automatically and extracts durable facts without any explicit agent action. Working memory is a key/value store that the agent controls explicitly — it writes exactly what it wants to remember and reads it back later. Both systems inject their contents into every LLM turn so the model always has relevant context in scope.
Configuration
harnessd is configured through a layered cascade: settings flow down from built-in defaults through files on disk and named profiles, and are finally overridden by HARNESS_* environment variables. Each layer only overrides what it explicitly sets — absent fields fall through to the layer below. The result is that teams can share sensible base settings in a repo-committed file while operators or CI pipelines override only the few values they need.