Back to projects

Architecture Deep Dive: Agent Run Cache (ARC)

ARC came out of a practical problem I kept seeing while working with coding agents: they can find the right path once, then forget the exact commands, files, and checks that made it work. ARC watches a real agent session, keeps the verified route that succeeded, and reuses it later as a small, evidence-backed capsule.

TypeScript Electron React ACP Local Embeddings Rust macOS Notarization Linux Packaging
ARC desktop workbench showing a saved command capsule and memory panel
ARC desktop workbench showing a saved command capsule, the agent run, and the memory panel.

The actual problem

Coding agents are good at investigating a repo, but they often repeat the same discovery work: which command actually verifies a change, which files belong to a flow, which setup step is easy to miss, and which earlier approach already failed. Chat history is noisy, and documentation can drift. A generic memory system can make this worse if it injects a stale or half-true note into a future run.

The design goal was narrower: keep the parts of a completed run that are useful to repeat, and stay silent when the evidence is weak.

Capsules, not general memory

ARC stores a capsule, not a transcript summary. A capsule describes a reusable route: the purpose, parameters, binding files, steps, commands, success criteria, reuse conditions, and do-not-reuse conditions. It is keyed to the intent of the work rather than to the exact words in the prompt.

That distinction shaped the whole system. A missed capsule only means the agent rediscovers something later. A wrong capsule can poison the next run. ARC therefore treats precision as more important than coverage.

The capture pipeline

The runtime records typed events from the agent run: prompts, tool calls, command exit codes, edited paths, assistant observations, and validation output. When a turn finishes, a deterministic local gate filters out small talk, no-op requests, failed work, and aborted runs. Ambiguous cases can be reviewed by the user's selected agent provider.

The reviewer does not get to invent a workflow. It receives bounded evidence from the run and can save a capsule only when the final state supports it. Failed attempts can become cautions, but they cannot be rewritten as proof that something worked.

Evidence had to be engineered

One bug shaped the review design. A successful run had real command output, file changes, and validation, but the draft sent to review was too clean and dropped the evidence that made the work reusable. The result was a rejected capsule even though the run had useful knowledge.

The fix was to carry redacted evidence snippets through the review packet: command outputs, changed-file context, assistant observations, and validation results. That made the reviewer judge the actual run instead of a vague summary of it.

Recall and staleness

Recall uses local embeddings with a conservative distance gate. If the prompt is not close enough to a saved capsule, ARC abstains instead of injecting a weak match. When a capsule is selected, ARC injects a compact note with the route that worked, not a long transcript.

Capsules also track the files and sources they depend on. When those bindings change, the capsule can be marked stale and stop being suggested. That matters because a stale command can be worse than no help at all.

Runner and provider boundaries

ARC has a TypeScript runtime and CLI at the root of the repo, with an Electron and React desktop app around it. It supports Codex, Claude Code, Copilot, and ACP-compatible agents. Capture and recall are ARC's job. The coding work still belongs to the agent the user chose.

That boundary affected implementation details. Provider-owned tasks such as review, title generation, summaries, and retries should use the current provider for that session, not silently fall back to another one. That keeps the app honest when someone switches between agents.

The desktop app

The app has two main memory surfaces. Capsules show saved reusable methods and bounded project facts. Activity shows the lifecycle around a run: started, completed, reviewed, saved, skipped, or rejected. Activity mattered because a user needs to know whether ARC ignored a turn on purpose or failed somewhere in the review path.

The renderer talks to the local runtime through an Electron bridge and local JSON-RPC style APIs. That kept the UI close to the local machine model: traces, capsules, retrieval state, and project memory live on the user's computer in the current public scope.

Native Copilot CLI port

I also ported the ARC core to a native Rust binary for the GitHub Copilot CLI. The package is published on npm as arc-copilot. Its split command runs Copilot next to a live ARC pane in the same terminal, while the capsules and retrieval state stay local.

The TypeScript implementation remains as the reference. Differential tests run the Rust and TypeScript versions against the same fixtures and compare their behavior. Real agent runs also become replay fixtures when they expose a bug, so a fix has to survive the session that originally broke it.

Packaging was part of the architecture

A desktop agent tool is not finished if it only works from a developer shell. The packaged app had to start its local runtime pieces itself, choose a workspace reliably, and avoid depending on fragile launch environment variables.

The release work included Apple Developer ID signing, notarization, stapling, Gatekeeper checks, Linux packages built in a Linux x64 environment, package verification, and cold-launch probes that open the installed app with a clean environment. Those checks caught the kind of issues that do not show up when everything is run from the repo.

Public scope boundary

ARC is intentionally local-first in the public trunk. Team sharing, hosted sync, billing, and managed backend pieces were kept out of the release scope. That made the product promise clearer and reduced the chance of shipping private infrastructure assumptions into the public repo.

What matters about it

The restraint is the point. ARC saves only completed work that has evidence behind it, reuses a capsule only when the match is strong, and drops it when the files it depended on change. Every one of those choices trades coverage for precision, because a wrong suggestion costs the next run more than a missing one does.