Your First Evolution
Watch KRAIT write, validate, and merge its own code through the self-evolution cycle.
How Self-Evolution Works
KRAIT agents evolve by proposing changes to their own skill modules, validating those changes through a security and testing pipeline, and merging them into the running system — all without human intervention. The entire cycle is supervised by OTP, so a failed evolution never crashes the agent.
The Evolution Cycle
When the agent determines it needs a new capability, it follows a four-stage process:
- Propose — The agent generates a new or modified skill module using its configured LLM provider.
- Validate — Narsil performs static analysis, security rule checking, and taint tracking on the proposed code.
- Test — The proposed skill is compiled and executed inside a sandboxed Docker container against generated test cases.
- Merge — If all checks pass, the new skill is hot-loaded into the running OTP application via code replacement.
Triggering Your First Evolution
Start the agent in development mode and give it a task that requires a skill it does not yet have:
krait dev
Then, in the chat interface at http://localhost:4000:
> Summarize the contents of a CSV file at /tmp/sample.csv
The agent will recognize it lacks a CSV-parsing skill and begin the evolution cycle. You can watch the process in real time in the terminal output.
Watching the PR Process
Every evolution is recorded as an internal pull request. You can inspect past evolutions with:
krait evolutions list
krait evolutions show evo-00a3f1
Each evolution record includes the proposed diff, Narsil validation results, test output, and merge status.
Narsil Validation
Narsil enforces the security rules defined in your Configuration. During validation it runs:
- Rule matching against KRAIT-001 through KRAIT-007 (and any custom rules)
- Taint analysis to ensure user input never flows into unsafe sinks
- Dependency auditing to block unauthorized external packages
If any check fails, the evolution is rejected and the agent receives structured feedback explaining why, so it can refine its next attempt.
The Merge Flow
After validation and testing pass, KRAIT uses Erlang/OTP hot code loading to swap in the new module:
# Simplified view of the merge step
defmodule Krait.Evolver do
def merge(%Evolution{module: mod, bytecode: beam}) do
:code.purge(mod)
:code.load_binary(mod, ~c"#{mod}.beam", beam)
Logger.info("Evolution merged: #{mod}")
end
end
The previous version is kept in memory by the BEAM VM, so the agent can roll back instantly if the new code raises exceptions at runtime.
Next Steps
- Skills System — learn how skill modules are structured
- Configuration — tune security rules and sandbox limits