Designs a system where the engine debugs and improves itself, based on the pattern observed in the last session: 5 consecutive bug fixes all followed trace → read → identify → edit → test, using tools the engine already has access to. Three levels of self-improvement: - Level 1 (Prompt): edit prompts/*.md to prevent LLM mistakes. Auto-apply. - Level 2 (Config): adjust defaults/mappings. Branch + test + PR. - Level 3 (Code): Rust patches for engine bugs. Branch + test + clippy + PR. Architecture: Self-improvement Mission spawns a Reflection thread that reads traces, reads source, proposes fixes, validates via cargo test, and either auto-applies (Level 1) or creates a PR (Level 2-3). Includes: fix pattern database (seeded from our 8 debugging session fixes), feedback loop diagram, safety model, implementation phases (A through D), and what exists vs what's new. Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
13 KiB
Self-Improving Engine: Automated Debugging and Evolution
Date: 2026-03-23 Status: Design Context: The last debugging session revealed a clear pattern: trace → human reads trace → human identifies root cause → human edits code → rebuild. Every step of this loop is something the engine can already do. This plan designs a system where the engine debugs and improves itself.
The Pattern We Observed
5 consecutive fixes followed the same loop:
| Trace symptom | Root cause | Fix location | Fix type |
|---|---|---|---|
Tool web_search not found |
Hyphen/underscore mismatch | effect_adapter.rs |
Code (name conversion) |
TypeError: str indices must be integers |
JSON double-serialization | effect_adapter.rs |
Code (parse before wrap) |
NameError: result not defined |
No variable persistence | loop_engine.rs |
Code (state dict) |
byte index 80 is not a char boundary |
Unsafe UTF-8 slicing | thread.rs, loop_engine.rs, scripting.rs |
Code (chars() not bytes) |
Model calls web_fetch (doesn't exist) |
Wrong example in prompt | codeact_preamble.md |
Prompt edit |
Each fix used the same tools the engine has access to: read_file, apply_patch, shell (cargo test), and file writing.
Three Levels of Self-Improvement
Level 1: Prompt Evolution (low risk)
The engine modifies its own prompt templates based on accumulated experience.
What it changes: crates/ironclaw_engine/prompts/*.md files
Examples:
- Adds "NEVER call web_fetch — use http() or llm_context()" to rules section
- Adds "freshness parameter: 'pd'=past day, 'pw'=past week, 'pm'=past month" to tool hints
- Adds "Always access previous step data via state['tool_name']" after repeated NameErrors
- Removes examples that reference nonexistent tools
Safety: Low risk. Prompt changes only affect LLM behavior, not engine logic. Easy to review diff. Easy to revert (git checkout).
Trigger: After every thread with issues detected by trace analysis.
Validation: None needed beyond human review of diff.
Level 2: Configuration Tuning (medium risk)
The engine adjusts its own defaults and mappings.
What it changes:
ThreadConfigdefaults (max_iterations, truncation limits, compaction thresholds)- Tool name alias mappings
- Output truncation sizes
- Resource limits
Examples:
- After repeated
freshnesserrors: add parameter hints to tool descriptions - After repeated truncation issues: adjust
OUTPUT_TRUNCATE_LEN - After excessive step counts: lower
max_iterationsdefault
Safety: Medium risk. Config changes affect execution behavior. Should be bounded (e.g., max_iterations can go 30-100 but not 1 or 10000).
Trigger: After N threads with similar patterns (not on first occurrence).
Validation: Run existing test suite (cargo test -p ironclaw_engine). Only apply if tests pass.
Level 3: Code Patching (high risk, high value)
The engine proposes Rust code changes to fix bugs it detects in itself.
What it changes: Any file in crates/ironclaw_engine/ or src/bridge/
Examples:
- Fix unsafe byte slicing (detected by panics in traces)
- Add missing type conversions (detected by tool errors)
- Fix missing match arms (detected by unhandled response types)
- Add error recovery paths (detected by repeated failures)
Safety: High risk. Wrong patches can break the engine, introduce security issues, or cause data loss.
Guardrails:
- Always work in a git branch (
self-improve/{timestamp}) - Run full test suite (
cargo test -p ironclaw_engine) - Run clippy (
cargo clippy -p ironclaw_engine --all-targets -- -D warnings) - Never modify files outside
crates/ironclaw_engine/andsrc/bridge/without human approval - Max patch size: 50 lines changed
- Generate a PR (not direct commit) with trace evidence
- Human approves or rejects the PR
Trigger: After a pattern appears in 3+ traces.
Validation: Full test suite + clippy + human review.
Architecture
Self-Improvement Mission
A Mission with MissionCadence::OnEvent that triggers after each thread completion:
Thread completes
→ Trace analysis (existing, automatic)
→ If issues detected:
→ Spawn self-improvement thread (ThreadType::Reflection)
→ Thread has access to: shell, read_file, write_file, apply_patch
→ Thread reads the trace JSON
→ Thread reads relevant source files
→ Thread proposes a fix
→ Thread validates the fix (cargo test)
→ Thread either:
a) Applies prompt edit directly (Level 1)
b) Creates a git branch + PR (Level 2-3)
c) Logs the proposal for human review
The Self-Improvement Thread's Prompt
You are a debugging agent analyzing execution traces from the IronClaw engine.
## Your task
Read the trace file at {trace_path} and identify the root cause of any issues.
Then propose and validate a fix.
## Available information
- Trace JSON: full message history, events, tool results, issues detected
- Source code: read any file in the codebase
- Prompt templates: crates/ironclaw_engine/prompts/*.md
- Bridge adapters: src/bridge/*.rs
- Engine code: crates/ironclaw_engine/src/**/*.rs
## Fix levels
1. PROMPT EDIT: Modify prompts/*.md to prevent LLM mistakes
→ Apply directly, no approval needed
2. CONFIG CHANGE: Adjust defaults in engine code
→ Create git branch, run tests, propose PR
3. CODE PATCH: Fix Rust code bugs
→ Create git branch, run tests + clippy, propose PR
## Rules
- Always read the relevant source file before proposing a change
- Always run `cargo test -p ironclaw_engine` after making changes
- Never modify more than 50 lines in a single patch
- For Level 2-3: create a branch `self-improve/{issue}` and use git
- Explain your reasoning: what the trace shows, why the fix works
Trace-to-Fix Pattern Database
Over time, the system builds a pattern database mapping trace symptoms to fix strategies:
| Trace pattern | Fix strategy | Location pattern |
|---|---|---|
Tool X not found |
Add name alias/conversion | effect_adapter.rs |
TypeError: str indices must be integers |
Parse JSON before wrapping | Where tool output is converted |
NameError: name 'X' not defined |
Add to state dict or prompt hint | loop_engine.rs or prompts/*.md |
byte index N is not a char boundary |
Replace [..N] with chars().take(N) |
Grep for [.. in relevant files |
| Model calls nonexistent tool | Fix prompt example or add alias | prompts/*.md or effect_adapter.rs |
| Model ignores tool results | Improve output metadata format | loop_engine.rs output building |
| Excessive steps (>5) for simple task | Add prompt rule or fix tool schema | prompts/*.md |
This database itself is a MemoryDoc that the self-improvement thread can read and extend.
Feedback Loop
┌──────────────────────────────────┐
│ User Message │
└──────────────┬───────────────────┘
│
┌──────────────▼───────────────────┐
│ Thread Execution (CodeAct) │
│ Using: evolved prompt + │
│ learned rules + tool hints │
└──────────────┬───────────────────┘
│
┌──────────────▼───────────────────┐
│ Trace + Reflection │
│ Produces: Lesson, Issue, │
│ Spec, Rule, Playbook docs │
└──────────────┬───────────────────┘
│
┌─────────▼─────────┐
│ Issues detected? │
└────┬──────────┬────┘
│ yes │ no
┌─────────▼────┐ └──→ done
│ Self-Improve │
│ Thread │
├──────────────┤
│ Read trace │
│ Read source │
│ Propose fix │
│ Test fix │
│ Apply/PR │
└──────┬───────┘
│
┌────────────▼────────────┐
│ Level 1: prompt edit │──→ Apply directly
│ Level 2: config change │──→ Branch + test + PR
│ Level 3: code patch │──→ Branch + test + clippy + PR
└─────────────────────────┘
Implementation Plan
Phase A: Prompt Self-Evolution (Level 1)
Effort: Small. Uses existing infrastructure.
- After reflection, if any
SpecorLessondocs reference prompt issues, spawn a Level 1 self-improvement thread - The thread reads
prompts/codeact_preamble.mdand the Lesson/Spec docs - It proposes an edit using
apply_patchorwrite_file - No testing needed — prompt changes are safe
- Next thread uses the updated prompt (loaded at runtime, not compile time)
Prerequisite: Prompts must be loaded at runtime from workspace, not via include_str!. Change build_codeact_system_prompt to read from store/file with include_str! as fallback.
Phase B: Fix Pattern Database (Level 1-2)
Effort: Medium.
- Create a
MemoryDocof typePlaybookthat maps trace symptoms to fix strategies - Seed it with the 8 patterns from our debugging session
- The self-improvement thread reads this playbook before analyzing a trace
- After successfully fixing an issue, it adds the new pattern to the playbook
- The playbook grows over time — the system gets better at fixing itself
Phase C: Automated Code Patches (Level 3)
Effort: Large. Requires careful safety design.
- Self-improvement thread creates a git branch
- Reads trace + source code + fix pattern database
- Proposes a Rust code change using
apply_patch - Runs
cargo test -p ironclaw_engineandcargo clippy - If tests pass: creates a PR with trace evidence + reasoning
- Human reviews and merges (or the system auto-merges after N successful self-fixes build trust)
Phase D: Meta-Evaluation Loop
Effort: Large. This is the full autoresearch loop.
- Periodically replay historical traces against the current code
- Compare: did the fix actually reduce the failure pattern?
- Score fixes by effectiveness
- Revert ineffective fixes
- Propose more targeted fixes for persistent issues
Safety Model
| Level | What can change | Who approves | Revert mechanism |
|---|---|---|---|
| 1: Prompt | prompts/*.md only |
Auto (no approval) | git checkout prompts/ |
| 2: Config | Engine defaults, constants | Auto if tests pass | git revert |
| 3: Code | Any .rs in engine/bridge |
Human via PR review | git revert or PR rejection |
Hard boundaries (never auto-modify):
- Security-sensitive code (safety layer, policy engine, leak detection)
- Database schemas / migrations
- Files outside
crates/ironclaw_engine/andsrc/bridge/(without human approval) - Test files (never weaken tests to make a fix pass)
What We Already Have vs What's New
| Component | Status | Used for |
|---|---|---|
| Trace recording | Exists | Input: execution data |
| Retrospective analysis | Exists | Detection: find issues |
| Reflection pipeline | Exists | Analysis: produce Lessons/Specs |
| RetrievalEngine | Exists | Context: inject learnings |
| CodeAct/Monty | Exists | Execution: write and run code |
| Tools: shell, read_file, apply_patch | Exists | Mechanics: read/edit files, run tests |
| Missions | Exists | Trigger: run after events |
| Self-improvement thread prompt | NEW | Brain: tells the agent how to debug itself |
| Fix pattern database | NEW | Knowledge: maps symptoms to strategies |
| Runtime prompt loading | NEW | Prerequisite: prompts editable at runtime |
| Git branch + PR creation | NEW | Safety: human review for code changes |
| Trace replay for validation | NEW | Quality: verify fixes actually help |
First Concrete Step
The smallest thing that creates a real self-improvement loop:
- Move prompt loading from
include_str!to runtime file read (with compiled fallback) - After reflection produces a
Specdoc about a prompt issue, spawn a thread that editsprompts/codeact_preamble.md - The edit is a simple append to the "Important rules" section
- Next user message picks up the updated prompt
This is Level 1 prompt evolution with zero risk. One feature, one file change, immediate feedback loop.