We've been building clive — a CLI Live Environment that gives an LLM a terminal and a keyboard. The core idea is simple: instead of wrapping tools in APIs and schemas, you let the agent read the screen and type. The terminal becomes the interface. The loop becomes the protocol. We've added something that takes that idea to its logical conclusion: clive can now modify its own code.
What clive is
Before going further, a quick recap of how clive works.
clive runs an LLM inside a tmux session. The loop:
1. Agent reads the current terminal screen
2. Agent decides what to type
3. Agent sends a command via XML tag
4. Tool executes, produces output
5. Repeat
Each tool — browser, email client, calendar, data processor — runs in its own named tmux pane. The agent sees all of them, decides which to act on, and routes commands through a session manager. Large content bypasses the terminal entirely through a file channel, preventing the scrollback and token problems that kill most terminal-based agent setups. The design rationale is that LLMs are excellent at reading text and reasoning about it. CLI tools produce text. The terminal is already a persistent, stateful, observable environment. So instead of building translation layers between agents and tools — MCP servers, REST wrappers, schema definitions — you just give the agent a terminal. It reads what's there, reasons about it, and responds. If the tool changes its output format, the agent adapts. No brittle schema mapping to maintain.
The self-modification problem
Users naturally start asking: "Add support for this tool." "Fix this error." "Change how you summarize."
Enabling an agent to edit its own files is genuinely dangerous. The obvious risks: the agent could weaken its own safety constraints, exfiltrate credentials, add network calls that persist between sessions, or simply break itself into an unlaunchable state. And for non-technical users, a broken install with no clear recovery path is worse than no feature at all. The naive approach — just let the agent edit files — fails on all of these. The right approach is a guarded pipeline with hard non-LLM enforcement.
The self-modification architecture
The key structural decision: split clive into a runner and a workspace.
The runner is the stable entrypoint. It enforces policies, owns the rollback mechanism, and cannot be modified by the agent. Ever. It's the part that survives a bad modification.
The workspace is where edits happen. A git worktree isolated from the active version, created fresh for each modification request:
.clive/worktrees/change-<timestamp>/
Every change is a unified diff applied to the workspace, never to the live code. The agent never touches the running version directly.
The pipeline
When a user runs clive selfmod "add support for tool X", this is what happens:
1. Plan — The agent produces a change description: what files, what intent, what risks.
2. Patch — The agent generates a unified diff. The policy gate validates it: does it touch only allowed files? Does it stay within the workspace? Does it attempt to modify the runner, the policy gate itself, or any credentials?
3. Test — The verification pipeline runs automatically. Unit tests if present. Lint and typecheck. A smoke test: launch clive in a fresh tmux session with a minimal task, confirm it completes.
4. Explain — The user sees: what changed, why, what risks were identified, how to undo. Shown as a diffstat plus plain-language summary.
5. Apply? — Explicit confirmation required. No silent application.
6. Promote — On approval: snapshot last-known-good, promote workspace changes to active, restart cleanly.
7. Rollback — clive undo at any point, including after a broken apply, returns to last-known-good and restarts. Works even if the current version crashes.
The policy gate
The policy gate is the most important component and the one the LLM cannot touch. It's a non-LLM module — deterministic code — that enforces hard rules regardless of what the agent produces:
- Path jail: no reads or writes outside the workspace root
- Protected files: the policy gate itself, the rollback system, credential files — all immutable
- Command allowlist: git operations, test runners, linters are allowed. curl, wget, ssh, package installers, destructive filesystem operations are blocked by default
- Capability model:
EDIT_PLUGINandRUN_TESTSare on by default.EDIT_CORE,NETWORK, andINSTALL_DEPSare off
The LLM can propose whatever it wants. The gate decides what passes.
Safe mode
One more safety valve: clive safe-mode starts clive with selfmod disabled, plugins disabled, and a minimal toolset. It's the recovery path if something goes wrong that clive undo can't fix. It's also what non-technical users can reach in one command without understanding what went wrong.
Why this matters
Self-modification isn't just a feature. It's what makes clive a living system rather than a static tool. Most agent infrastructure is frozen at deploy time. The tools are the tools. The schema is the schema. If something doesn't fit, a developer has to update it. clive's design — terminal as interface, text as the protocol — means the agent can reason about any tool it encounters. Self-modification extends that principle inward: the agent can reason about itself and propose improvements, with humans staying in the loop on what gets applied. The pipeline approach — Plan → Patch → Test → Explain → Apply → Rollback — makes this safe enough to hand to non-technical users. You don't need to understand git or diffs to ask clive to improve itself and undo it if something breaks.
The code is at github.com/ikangai/clive.
Unlock the Future of Business with AI
Dive into our immersive workshops and equip your team with the tools and knowledge to lead in the AI era.