Autolith

The agent that rewrites itself while it runs.

A terminal programming agent inside a live Common Lisp image it can read, edit, break, and recover.

nix run github:lambda-symbolics/autolith
Read the docs

Linux, macOS, FreeBSD, NetBSD, OpenBSD, and Windows. See more.

The whole agent is one Common Lisp image.

One image holds the provider client, the terminal, the tool registry, the MCP connections, the conversation store, the memories, the agenda, and the code that runs the turn. The agent reads and edits all of it at the same address.

Common Lisp provides describe, conditions, restarts, CLOS protocols, and source forms at runtime. The agent uses them to inspect and change its own implementation.

File search runs in-process through fff, a Rust library. Separate, persistent Lisp workers provide REPLs for experiments and scripts.

One SBCL image, one process
provider
client
terminal
interface
tool
registry
MCP
connections
conversation
store
persistent
memories
workspace
agenda
mutation
journal
what happens
next

In your repository

Repository work
Filesystem, shell, and search tools with results you can see.
Unattended jobs
Run Autolith inside your own workflows through its bounded headless mode, which prescribes the input and output schemas.

In its own image

Live Lisp
A runtime it can inspect, test, and extend, with heap-isolated workers for experiments.
Oversized context
Recursive inference over corpora too large for the model window.
Continuity
Portable conversations, memories, agendas, checkpoints, and recovery.

Messages are just syntax sugar.

The sentence "Hello Autolith! How do you do?" is read as the Lisp form (prompt :to 'autolith "Hello Autolith! How do you do?")

Prose, typed at the prompt. Autolith reads it as a call to (prompt). Talk to a specific agent using the :to parameter.

Type something.

This browser demonstration wraps prose in a prompt call and leaves parenthesized input unchanged. It does not run Lisp.

The reader

Read as a call to (prompt), addressed to the primary agent.

You do not need to know Lisp. Prose works, and most people never type a form. If you want to learn it, this is a good place to start: the input is a real REPL, and the agent sees what you typed, what came back, and any condition it signalled, so you can ask it why.

So a prompt can be computed.

Prose, commands, tools, and Common Lisp share one input. A form runs in the active image and the model sees the result. Read a prompt off disk, template it, or generate it from the program you are debugging.

;; a computed prompt
(prompt (read-file "review-notes.org"))

;; a tool, called by hand
(resource.read :uri "workspace:.")

;; introspection, right there
(describe 'application)

And you can steer any child in the tree.

Autolith keeps working while its children run. Address one by name to correct it mid-flight. Its next useful reply comes back to the primary terminal.

(prompt :to 'test-review
        "Run the focused tests and
         report only failures.")

Update the running agent without restarting it.

Autolith replaces complete functions, methods, classes, macros, conditions, and global settings in the image it runs in. The change is live at once. Whether it outlives the process depends on what happens next in the journal.

Figure 2. The mutation path. A change passes a check on its way to durable state.

self.redefine compiles and installs one complete definition in the active image and appends it to the journal. self.exercise asserts against the pending change. self.diff collapses everything pending to its effective state. self.discard puts the newest change back. Being wrong is cheap.

self.commit turns the pending set into an immutable private image commit: a manifest plus a complete executable replay script, in a separate private Git history. A clean process replays that script and asserts the load-bearing surface survived before the commit becomes selectable. Your working tree is a different repository.

Figure 3. The failure path. Recovery boots a separate image and reads the capsule.

Then break it on purpose.

Give the formatter behind the live status row a bad redefinition and the process dies on the spot. Autolith writes a private crash capsule, boots a separately built pristine image, and selects a known-working generation from it.

The conversation comes back with the scrollback intact. The first turn afterwards reads only: bounded crash context, the workspace, tracked source, active state. It reports, then asks before it repairs anything.

When an ordinary form signals, the live restart debugger keeps the failed stack alive and puts Ask Autolith why this failed beside the restarts, with up to three validated recovery proposals.

Figure 1. One root completion. The corpus is an environment. Only frame results cross back.

Work beyond the context window.

Every model has a hard limit on how much it can read at once. Autolith works around it. Point it at a log, a codebase, or a folder of documents far too big to fit, and it will answer questions about the whole thing. The method comes from Recursive Language Models, by Alex L. Zhang, Tim Kraska, and Omar Khattab.

It does not try to read everything. It writes small programs to search and slice the material, sends the parts that matter to itself in separate side conversations, and keeps only the answers. Those side conversations never touch yours. A hundred of them add one line to your screen. You set the ceiling on calls and tokens before it starts, so a large question cannot turn into a runaway bill.

Budget
32 calls, 400 000 tokens, depth 2
Corpus
3.1 MB, 121 src/*.lisp files
Root conversation
59.6 K tokens in, 915 out
Answer
83 condition classes across 14 subsystems, each with its file
Trace
inference:s2Wb1o2, readable in session

Recorded sessions.

  :::.      :::        AUTOLITH v0.35.0
  ;;`;;     ;;;        ─────────────────────────────────
 ,[[ '[[,   [[[        model      gpt-5.6-terra
c$$$cc$$$c  $$'        workspace  /root/common-lisp/frob/
 888   888,o88oo,.__
 YMM   ""` """"YUMMM
Download recording
Asked
List every condition class in a 3.1 MB concatenation of 121 source files, grouped by subsystem, with the defining file. Budget of 32 calls, 400 000 tokens, depth 2. Do not read or search the file directly.
Cost
59.6 K tokens in the root conversation. The corpus never enters a prompt.
Answer
All 83 condition classes across 14 subsystems, each with its defining file.

Attach to a session from another terminal.

Every running Autolith publishes a private authenticated endpoint on loopback, keyed by the conversation identifier and guarded by a capability token. Detach and the session moves to a supervised process group that outlives your terminal.

From any other terminal on the machine

$ autolith localgroup status
$ autolith localgroup tell   SESSION "use the staging config"
$ autolith localgroup attach SESSION --read-only
$ autolith localgroup attach SESSION --take-over
$ autolith localgroup pause  SESSION
$ autolith localgroup kill   SESSION

Many observers, one controller. Take over and the previous controller loses the session. Output arrives in order for everyone watching. tell also wakes a paused session, pause cancels active work and holds the queue, kill asks for a graceful shutdown.

On Windows a session runs in the terminal that started it. The endpoint and these commands work the same.

And it moves between machines.

$ autolith data export project.sexp --workspace ~/code/project
$ autolith data import project.sexp --workspace ~/src/project

One readable S-expression archive: conversations, memories, agendas, plans, papercuts, and session assets. Import preserves stable identifiers and merges into local data.

Even self-modified cores can be rebuilt on another machine.

  • Linux x86_64
  • Linux aarch64
  • musl static
  • macOS x86_64
  • macOS arm64
  • FreeBSD
  • NetBSD
  • OpenBSD
  • Windows x86_64

Every command is classified before it runs.

External commands pass through authorization checks before execution. Process isolation and scoped filesystem access limit accidental damage; they are not a hostile-code security boundary.

Sandbox
cl-exec-sandbox selects the backend: Bubblewrap on Linux, Seatbelt on macOS. The default policy gives a command no network, a read-only host, writes in the workspace and temporary directories, protected repository metadata, and sixty seconds. On Linux it adds process, user, IPC, UTS, and network namespaces, no_new_privs, and seccomp.
Classification
In automatic mode one bounded inference frame judges each command under a two-call, eight-thousand-token budget and answers through a closed schema: sandboxed, full access, or denied. It reads the command as data and ignores instructions written inside it. A failed classification denies. An unavailable sandbox turns a sandboxed verdict into a denial.
Approvals
Once, always for this exact command in this directory, sandboxed for the session, full access for the session, or denied. Headless jobs deny anything that would otherwise open the picker.
Credentials
OAuth and MCP credentials render as explicit redaction markers. Crash capsules are written secret-free. A checkpoint clears credentials from memory before it forks. An exported archive carries user data.
Bounds
Sixteen identical tool calls. Five hundred and twelve provider requests per turn. Sixty-four kilobytes of shell output, four mebibytes per file read, sixty-four kilobytes per crash capsule. Call, token, and depth budgets on every inference frame.
Revision gating
A read returns an opaque revision. An edit applies against that exact observation, or it fails and names the revision it expected and the one it found.
Immutable mode
--immutable pins the agent to one state: no evaluation, mutation, persistence, checkpoints, or rollback. Use it when you are integrating a fixed Autolith into something else, or running it unattended, and self-modification is not wanted.

Keep knowledge at the right scope.

A fact you want forever, a commitment for this month, a step for this hour, and an exact heap expire on different schedules. Autolith writes them to separate readable stores rather than one database or one saved core.

Conversations

Append-only portable S-expressions with exact resume commands, crash-tail repair, and read-only replay navigation.

Memories

Workspace or global facts and preferences, recalled under a bounded budget.

Agenda

Durable commitments and blockers for one workspace, delivered in full on every request. An item can carry memory identifiers.

Plan

One ordered working list per workspace, at most thirty-two steps, replaced wholesale.

Private image commits

Complete replay scripts for durable definitions and settings, retained in private Git.

Generations

A saved core, the exact source commit, a reconstruction script, a manifest, and a journal position.

Worker images

Immutable experimental cores with parentage and notes, for trying something at full size.

Every store is append-only or transactional. Shared-state transactions serialize across processes, so two agents can share one workspace.

Change any layer from the prompt.

Configuration is files and Lisp forms, and the running agent reads both.

Skills
Standard SKILL.md with frontmatter, or native SKILL.sexp. Project skills win over yours, yours win over bundled.
MCP servers
Stdio or Streamable HTTP, with an approval policy per server. Trust a directory in directory-scopes.sexp to let its own mcp.sexp load.
Child roles
Six bundled: scout, designer, reviewer, librarian, task, sonic. Write your own into .autolith/agents/ and name the tools, models, and effort each one gets.
Providers
Nine built in, from ChatGPT and Gemini subscriptions to Anthropic and Mistral keys. Register any other OpenAI-compatible endpoint from the REPL.
init.lisp
Ordinary Common Lisp in the autolith package, loaded after tracked code and your selected private commit, with your privileges.
Request context
define-context-contributor attaches bounded standing notes to provider requests. A note shapes one request.
Commands
define-application-command adds your own. The thirty-seven built-in slash commands are sugar for the same Lisp calls.
Instructions
AGENTS.md at the project root, refined by deeper ones, re-read on every request.

Install it.

nix run github:lambda-symbolics/autolith

The high testosterone, high estrogen way to install Autolith.

Then sign in to a provider

autolith auth anthropic autolith auth chatgpt autolith auth fireworks autolith auth gemini autolith auth grok autolith auth mistral autolith auth nous autolith auth opencode autolith auth openrouter

A web flow or an API key, whichever the provider offers. One is enough. Then run autolith.

Autolith 0.50.0

Licence
ISC
Linux
x86_64 and aarch64, glibc and static musl
macOS
x86_64 and arm64
BSD
FreeBSD, NetBSD, OpenBSD on x86_64
Windows
x86_64
Updates
(update) inside, autolith update outside

Yes, piping a URL into a shell is evil. Read the installer first. Nix is the preferred installation method on worthy operating systems.