Shoal is one agent on your own hardware
Shoal is an agent harness. One product, one binary. Code is the first work it was pointed at, not the limit of what it holds: it reads and edits real files in your repository, runs tools, and asks before it writes.
It also owns the layer underneath. Shoal starts the inference server, pins its flags, health checks it, reads its context size, and stops it when the session ends. There is no second piece to install and wire up before a model will answer.
Models plug into Shoal. It does not train one and it does not ship one. A GGUF on your disk, an OpenAI-compatible server on another box, and a frontier model over the network are all reachable from the same session. Which one you use is written down rather than inferred, and nothing leaves the machine unless a record you saved says it should.
The real job is the context window
Everything above the model is context management. Shoal keeps prompts lean, tracks a token budget and corrects it from what the server actually reports, and appends to history rather than rewriting it so the server’s prefix cache stays warm across turns. When the budget tightens, compaction fires once and deeply at 85 percent full and cuts back to 60 percent, instead of trimming a little every turn and re-prefilling the whole window each time.
The same thinking decides how the agent learns what a repository holds.
Reading files one at a time to find out what is in them spends the window on
the search. Shoal keeps a chart of the codebase at .shoal/chart.yaml, a graph
of files with one-line purposes and import edges, and serves it through a tool
call that answers with a single packed block sized to a token budget. Detail
fades with distance from the files a task named, so pressure costs detail
before it costs coverage. The chart is never injected into the prompt. Work
that does not belong in the main window is torn off into a sub-agent with a
fresh context, and a housekeeping pass runs between turns and stages its edits
so they apply at one cache boundary.
Five words carry the architecture
| Word | Meaning |
|---|---|
| Shoal | The product. The agent, the binary, the name on the tin |
| Keel | The engine inside: agent loop, context machinery, tools |
| Dock | An inference engine or endpoint where models tie up |
| Berth | One spot at a dock, holding exactly one moored model |
| Mooring | A model tied up and ready, and the named record of it |
The rest of these pages use those words as written. A mooring names a model, a dock, and a purpose, and the berth is the room it takes.
One engine stands behind three clients
Keel talks to every client through one seam: a typed event stream out and a
channel of operations in. shoal proto speaks that seam over stdio as JSON
lines, and the clients are built on it.
| Client | What it is |
|---|---|
| Terminal | An inline session with a live status region and finished output in native scrollback |
| VS Code | An editor panel that spawns the installed binary, with Ask About Selection in the context menu |
| Desktop | The same web client in its own app window, over a loopback bridge |
They share the engine, the protocol, and the SQLite session store, so a session started in one is resumable and a capability lands in all three at once.
Shoal is pre-alpha and its gaps are named
Working and tested: a full agentic session against a local model Shoal manages itself, streaming, parallel tool batches, delegation to sub-agents, a diff before every edit, write, and patch approval, sessions that persist and resume, compaction, a persistent server later runs adopt, refusal of a model that would not fit the card, mid-session model swaps, file-length limits enforced on the write path, and outside tools bound in as hooks.
Not working, stated plainly: there is no sandbox, so the permission prompt is
the enforcement and git is the undo layer. The file-length limits are measured
on write, edit, and patch, and a shell redirect can still grow a file past
them. The offshore path is tested against a fake server and has never spent a
real token. Two local models side by side on one card has been sized but not
run. The chart resolves import edges for Go only, and other languages get
nodes and purposes without them. One model call runs at a time. The mooring
form’s first-run frame has not been seen in a real VS Code webview or a real
desktop window, and shoal setup asking for a model has not been run live:
those three are covered by tests and a stdio walkthrough only.
Shoal is tuned and measured against one model, gpt-oss-20b, and other models range from working well to barely working. Those measurements are kept as numbers rather than rounded into a claim.