grows new abilities.
When ourro spots the same workflow twice, it drafts a small Lisp capability, verifies it, and hot-loads it into the running session. Not a note in a prompt — a real tool the agent now has, at zero token cost from that point on.
;; v0.2 · powered by lisp
(defagent ourro :in 'lisp)
;; thesis
An agent that ships frozen is a program.
One that compounds is a species.
Most coding agents are stateless. They read your notes file at the top of every session and pay for it in tokens on every turn. ourro is a living process: when it spots repeated work, it grows a new organ — compiled, verified, and free to run — and keeps it. The agent you use on Friday knows things the agent you started on Monday didn't
;; stay in the loop
ourro is live on GitHub and moving fast. Drop your email for the occasional note when a new generation ships — new capabilities, milestones, write-ups. No drip, no tracking, unsubscribe any time.
A coding agent that grows new abilities — safely. ourro (née tabula-rasa) turns repeated work into tested, versioned Lisp capabilities, then evolves live without taking you out of flow.
Not memory. Not prompt tricks. Compiled, contract-carrying code — verified before it runs and reversible by design. When ourro spots a recurring pattern, it asks an LLM to propose a small capability as Lisp, runs it through a safety pipeline, and hot-loads it into the living image. A learned skill is machine code, not prompt text — so it costs zero tokens every turn after, forever.
Successful changes join a git-backed genome you can inspect, diff, and roll back. The more you use ourro, the more of your workflow becomes free, native capability — the agent compounds instead of resetting.
It's written in Lisp for a specific reason: Lisp is the language where code and data are the same shape. That means ourro can read, transform, and safely write its own building blocks — which is what evolving actually requires. Everything ships as one native binary. No Node, no npm, no lockfile drift.
;; open source on github. one email when a new generation ships.
Four kinds of thing ourro learns as you work. Each one is small, checkable, and one keystroke to undo — earned across enough sessions to be worth trusting.
When ourro spots the same workflow twice, it drafts a small Lisp capability, verifies it, and hot-loads it into the running session. Not a note in a prompt — a real tool the agent now has, at zero token cost from that point on.
ourro mines triggers from your own event stream and turns them into automations. Edit a source file, the test job is already running by the time you hit send — and if it fails, the diagnosis is waiting for you, not a task list.
New capabilities pass safe-read, structural and capability checks, compilation, watchdog-protected tests, and a probation period on real use. Nothing self-modifies until the gates pass, and anything shaky auto-reverts.
A supervisor snapshots each generation, hands your conversation across restarts, and detects crash loops — falling back to the last known-good image. ourro can literally rewrite and reboot itself mid-session without dropping you.
Every version of ourro's behavior is a numbered generation. New behavior is proposed as a candidate, tried in a sandbox, and — if it wins — swapped in without dropping your session. Rolling back is one command. There is a receipt for every change.
| gen | Δ | note |
|---|---|---|
| 000 | bootstrap | hand-written kernel. trusted. small on purpose. |
| 007 | + prompt-artifact | user pinned a style rule. scope=user. reversible. |
| 014 | + recovery-policy | tool/shell-nonzero → :retry-with-flag --no-input. 6/6 held-out. |
| 031 | + workflow-artifact | read→grep→edit→test collapsed into one typed closure. |
| 042 | swap | atomic pointer flip at safe point. in-flight turn finishes on gen 041. |
| 058 | − workflow-artifact | regressed on 2 held-out episodes. rolled back. archived to lineage. |
| 077 | + semantic-memory | project fact, provenance=user, valid-until=2026-12-31. |
| ∞ | candidate | in a child world. not yet earned. |
Self-evolving doesn't mean self-authorized. Every change carries a risk tier — some auto-activate, some wait for evaluation, some require a human, some are off-limits entirely. The kernel is small and the model can't touch it.
| risk | examples | default |
|---|---|---|
| R0 | Explicit user model, style, or scoped preference change | Auto-activate. Reversible. Session or user scope. |
| R1 | Workflow or recovery policy over already-approved capabilities | Auto-promote after ≥5 held-out replays, zero regressions, and one efficiency win. |
| R2 | Inferred memory, prompt/policy changes, shell or network workflows, non-kernel source patches | Human approval after world evaluation. |
| R3 | Kernel, compiler, promotion logic, trust boundary, capability expansion | Never self-promotable. |
;; and no Node.js, no TypeScript, no JavaScript runtime.
Metaprogramming is code that writes code. In ourro, a file that describes a tool is a tool — the same shape whether a human writes it, an extension writes it, or ourro learns to write it. That is why learning here means new tools, not just new prompts. Drop a file in, get a tool. The agent can read these files. The agent can write these files, inside a trust boundary you set. Draw your own conclusions.
(in-package #:ourro/extensions)
(define-command hello (arguments)
"Greet from the live Lisp image."
(format nil "Hello, ~A"
(if (zerop (length arguments)) "world" arguments)))
(define-extension-tool echo (arguments cwd)
(:description "Return a supplied value.")
(:schema
(ourro/util:json-object
"type" "object"
"properties" (ourro/util:json-object
"value" (ourro/util:json-object "type" "string"))
"required" (vector "value")))
(declare (ignore cwd))
(ourro/util:json-value arguments "value"))
;; Extensions that own resources can release them before shutdown.
(register-cleanup
(lambda () (format *trace-output* "extension stopped~%")))Lisp isn't just novelty here — it does real work. A few properties of the language map directly onto things ourro needs to do.
;; longer take → Lisp vs TypeScript for AI coding agents
$ bin/ourro --exploreourro 0.1 :: generation=042 provider=vertex model=gemini-3.1-protype /help, /why, /worlds, /learn, /quit> start the dev server→ shell npm run dev! signaled tool/shell-nonzero (EADDRINUSE :3000) policy recovery-policy/port-in-use (gen 042)→ shell lsof -ti:3000 | xargs kill -9→ shell npm run dev✓ ready on http://localhost:3000 (1.4s)> /why episode 0x9a2f ← recovery-policy/port-in-use learned after you killed :3000 by hand 4 times last week parents 6 episodes · held-out 6/6 · promoted gen 038→042> /worldscandidate workflow/rerun-flaky-test fitness ▲ 1 world running>