Meta-Ability: Genome Replication and Agent Bootstrapping
Source version of CodeSmith:
v0.5.0(commit3a74c82f). All paths are relative to the repo root; line numbers refer to this version.
Intended audience: readers curious whether an agent can repair itself — or even build itself.
Series index: README.
This is the third installment on the meta-ability track, and its subject is the outermost ring of targets: the agent itself. In the previous two, code was respectively the model's thinking tool and the goalkeeper over its behavior; here, the thing code works on becomes the agent itself — repair the Agent with code, create Agents with code.
Start with "Doctoring Itself": the Real Boundaries of doctor
CodeSmith has a codesmith doctor command (run_doctor, crates/tui/src/main.rs:2310) that runs a full checkup in one breath: version and update status, config file parsing, API key sources, network connectivity (including hints that distinguish DNS failures), MCP server health, external dependency resolution, and platform sandbox availability.
Cold water first, reasoning second: the bulk of CodeSmith's doctor is a stack of purely deterministic checks — that must be confessed honestly, not hyped into full-blown "AI self-healing". But there is real craft in deterministic checks themselves; see the comment in crates/agent-runtime/src/dependencies.rs (dependencies.rs:1-20):
Historically, tools that called external binaries hardcoded the
command name and failed at execution time when the binary wasn't on
`PATH`. The most-cited example was `code_execution`, which spawned
`python3` directly — Windows users (where the launcher is `py` or
`python`, not `python3`) saw `Failed to execute tool: program not
found` with no upstream hint of what was wrong.
This module centralises the probe-then-decide pattern.
A real lesson: a tool spawned python3 directly, and Windows users got one dry "program not found" — no hint of what was missing or where to install it. The fix is "probe, then decide": candidates are probed in order, and the result is cached for the life of the process in a OnceLock (one Command::output per candidate — you cannot pay that again on every round of model interaction):
// crates/agent-runtime/src/dependencies.rs:41
pub const PYTHON_CANDIDATES: &[&str] = &["python3", "python", "py -3"];
The order is deliberate — python3 is the least ambiguous (rules out Python 2 leftovers), python covers Windows and Homebrew, and py -3 is the Windows launcher. Probing uses --version rather than which, for portability across Unix, Windows, and containers. doctor then translates the resolved result into per-platform install advice (brew install python@3.12 on macOS, apt install python3 on Debian, winget on Windows).
For contrast, a more aggressive specimen: OpenClaw's doctor detects problems in three layers (config anomalies, state problems, service health) and repairs them in two tiers (safe fixes execute automatically; risky ones require user confirmation); for the oddities deterministic rules cannot cover, it hands things to an LLM to analyze logs, infer causes, and generate fix plans — deterministic checks ensure common problems are fixed reliably, while the LLM backstops the long tail of mysteries. That is the same recipe as Article 13's triple safeguard. In v0.5.0, CodeSmith's doctor filled in this second layer (crates/tui/src/doctor_llm.rs): once the deterministic checks finish, the collected warnings/errors are serialized into structured findings and handed to a single advisory LLM call (the designated cheap brain under [utility_model] if configured, otherwise falling back to the main client) to infer root causes and suggest next actions; deterministic results always take precedence, the LLM only analyzes and never executes, and on failure or timeout (30 seconds) it is skipped silently — Article 23 covers that layer in depth.
Having Agents Write Agents: Where It Gets Hard
One step beyond self-repair is having agents create new agents. Cold water first: creating a high-quality agent is far more complex than generating ordinary application code, and the common defects can be mapped one-to-one onto CodeSmith's own modules:
-
Slapdash context management: trajectories flattened into plain text and stuffed into the context, throwing away the KV Cache optimization of structured messages (Article 4's 100× price gap, voided on the spot), tool-call loops with boundary bugs — CodeSmith has dedicated
prompt_zones.rsandtool_parser.rsmodules managing these; a generated agent won't necessarily know; - Undisciplined tool design: terse descriptions, no negative list, parameters without examples (Article 13's arity lesson, entirely absent);
- Stale technology choices: the most common but already obsolete models and APIs in the training data — models turn over every six months, so training memories are bound to expire;
- Disconnection from the living ecosystem: deprecated APIs, libraries nobody maintains.
The last two are the same disease: the knowledge cutoff. The cure is maintaining a SOTA knowledge base or giving the agent search, so the reference answers stay fresh.
The Key Technique: Exemplar-Based Generation
And the first two? The most effective route is not to enumerate every rule in the prompt — that is whack-a-mole — but to provide a high-quality Agent implementation as an exemplar and have the generator modify the exemplar rather than start from zero. Exemplar code is itself the carrier of best practice: good architectural choices survive naturally because they already sit in the exemplar, while writing the "why" of every rule into the prompt takes a thousand words — inside the exemplar it costs one diff.
CodeSmith turned this route into a built-in mechanism. See crates/agent-runtime/src/skills/system.rs:
// crates/agent-runtime/src/skills/system.rs
const SKILL_CREATOR_BODY: &str = include_str!("../../assets/skills/skill-creator/SKILL.md");
const DELEGATE_BODY: &str = include_str!("../../assets/skills/delegate/SKILL.md");
const V4_BEST_PRACTICES_BODY: &str = include_str!("../../assets/skills/v4-best-practices/SKILL.md");
const PLUGIN_CREATOR_BODY: &str = include_str!("../../assets/skills/plugin-creator/SKILL.md");
const MCP_BUILDER_BODY: &str = include_str!("../../assets/skills/mcp-builder/SKILL.md");
// ...... (plus documents / spreadsheets / pdf / feishu and more — over ten in all)
On first launch, this entire bundle of "exemplar skills" is installed automatically (with BUNDLED_SKILL_VERSION for version management and incremental updates on upgrade). The most typical of them is skill-creator — a skill that teaches the Agent to create skills — which is in essence one high-quality exemplar plus a writing standard; mcp-builder and plugin-creator work the same way: rather than writing a hundred rules on "how to write an MCP server" into the system prompt, hand over one working exemplar and let the model modify it. This is the gateway to bootstrapping.
The subagent system is the other face of "replication plus variation". crates/agent-runtime/src/subagent.rs:32 defines the subagent types:
pub enum SubAgentType {
/// General purpose - full tool access for multi-step tasks.
General,
/// Fast exploration - read-only tools for codebase search.
Explore,
/// Planning - analysis tools only for architectural planning.
Plan,
/// Code review - read + analysis tools.
// ......
}
Plain-English translation: all subagents share the same runtime (the architectural frame does not move); the type decides exactly two things — the role and the tool surface (the part that varies). This is a ready-made implementation of "copy yourself, adjust the prompt, add or remove tools, keep the frame": General is a full copy, Explore is the variant with write access stripped away, Plan is the variant that keeps only analysis. The biological analogy completes here: the genome (the runtime) is replicated, the phenotype (prompt and tool surface) differentiates, and the variations are small steps — one or two dimensions at a time, not a rewrite from zero.
Summary
Pull the first three meta-ability installments into a single thread:
- Meta-ability is "the ability to create abilities": code is precise, executable, composable, and can produce new tools, new constraints, and new expressions on the spot;
- Its target moves outward from the core: thinking (RLM thinking tools) → behavior (the execpolicy goalkeeper) → self (repairing and writing Agents);
- Self-repair is a layered recipe: deterministic rules cover high-frequency problems, and the LLM backstops the long tail of mysteries (CodeSmith's doctor has both layers as of v0.5.0);
- Writing Agents relies on exemplars, not rule lists: a "skill that creates skills" like skill-creator is the gateway to bootstrapping;
- Subagents = genome replication plus variation: shared runtime, differentiated prompts and tool surfaces.
The trade-off, as always: bootstrapping amplifies everything. Good architecture in the exemplar gets copied — and so does bad architecture, and defects become hereditary diseases of every descendant. That is why the bundled skills carry BUNDLED_SKILL_VERSION versioning and are updated with each release — the last layer of the harness, slipped over the genome.
The next lesson after bootstrapping is evolution, and evolution's first safety boundary happens to be buried right here: the safety mechanisms must not be self-modifiable. An Agent may change its own prompts, skills, and tools, but it must never touch the verifiers, test cases, and audit logs that approve its own updates — otherwise it need only lower the test thresholds, and degeneration can disguise itself as progress. Article 23 will unfold that entire course: the full closed loop of learning from experience, and the three boundaries drawn around the loop.
But before the evolution lecture opens, a more fundamental bill comes due: when the model says "tests all green", what is that sentence itself worth? The next installment's answer — it only counts after you replay it.
Top comments (0)