Autonomous improvement without LLM weight training — evolves prompts, memory, and strategies based on interaction data.
Record (realtime) → Analyze (daily) → Evolve (every 3 days)
- Record layer: Trace every interaction, tool call, and outcome
- Memory system: Retrieval, safety filtering, compression, anti-pattern detection
- Analysis: Automated evaluation with judge model and test suites
- Evolution engines: Memory evolution, prompt evolution, strategy evolution
- Safety: pre-write snapshots (restored by hand), gate checks, shadow mode for first rounds
- Pipeline: Scheduler, pipeline orchestration, annotation system
- Integrated runtime: evolution state, history, configuration, and manual trigger commands are exposed through the main CLI
prx evolution status # Show evolution state
prx evolution history # Show evolution history
prx evolution trigger # Manually trigger one evolution cycleA prompt.mutable_files entry of skills/<name>/SKILL.md uses the enabled
owner-scoped skill lifecycle. Its projection must match the active immutable
revision, and active knowledge patterns must be backed by eligible stored
experiences before a model call is made. The bounded lifecycle proposer stages
a SkillProposal; the evolution record carries its proposal, skill and revision
IDs, with model usage and the physical accounting scope preserved.
These candidates never produce a generic file-write commit. Source review, paired evaluation, the governing holdout suite and publication authorization remain prerequisites of the lifecycle's existing publication and projection transaction, even when the general evolution judge approves a proposal. An unavailable lifecycle or insufficient evidence refuses the managed proposal. Other allowlisted prompt files retain the legacy prompt workflow; they are not silently imported or advertised as lifecycle-evaluated skills.
Prompt proposals are generated by the resolved default model, with bounded input/output and a strict JSON reply. The daemon and manual trigger use the same managed provider construction. Missing providers, accounting ownership, budget or usable output refuse generation instead of producing fixed text. The proposal records model identity, input/output digests, evidence references, reported usage and an opaque scope joining it to the physical cost journal. Real judge verdicts and human-review queue entries carry their own model, usage and accounting scope, separately from the proposal's call.
The judge receives the proposed before/after content as ephemeral review data;
that projection is not serialized into cycle records. Whole-document model
replies are severity 4 regardless of the requested mutation category. Default
human-review thresholds block automatic application. Immutable sections must
remain balanced and unchanged. Draft-only persistence retains content hashes.
Model calls use [self_system] evolution_model_max_tokens,
evolution_model_max_micro_usd and evolution_judge_timeout_secs; see
configuration. Existing paid judge configurations now need
an explicit nonzero monetary allowance. Set the token allowance to zero to
disable these calls without enabling a synthetic fallback.
A layer engine only proposes its change. The evolution judge (the resolved
default model) scores the proposal, and in auto mode the change is written
only after the judge accepts it:
| Layer | Change | Written when |
|---|---|---|
| prompt | the first prompt.mutable_files entry |
a model judge scores the proposal at or above the pass threshold |
| strategy | strategy.decision_policy_path |
the strategy gate passes, then a model judge accepts |
| memory | evolution_config.toml (and redundant conversation memories moved to trash) |
the memory gate passes, then a model judge accepts; while the memory engine scores with its built-in mock (as it does today) it defers first, so memory evolution does not apply in auto mode |
Before a change is written, the previous version of its target is kept as a
JSON snapshot under .evolution/rollback/<layer>/. There is no rollback
command; restore a snapshot's content by hand if needed.
- A score below the pass threshold writes nothing; the cycle is logged with
result
rejected. - A deferred verdict writes nothing; the cycle is logged with result
deferred. A verdict is deferred when there is no model judge (only the built-in mock scorer, errorjudge_degraded), or when the model judge's call fails, its reply is not a score, it does not answer within[self_system] evolution_judge_timeout_secs(1 to 3600, default 180), or the run is cancelled while it waits (errorjudge_failed). - A run cancelled after the judge accepted but before the change was written
writes nothing (error
commit_cancelled, resultdeferred). A change that cannot be written is logged with resultdeferredand errorapply_failed. - An accepted and written change is logged with no result yet; the fitness backfill scores it later.
- Each cycle's row is flushed to the evolution log as soon as it is appended,
also for a cancelled run. If the row cannot be written, the run reports
record_failedand the commit decision (for example an applied change) stands. - On daemon shutdown, after stopping its components, the daemon cancels the
evolution verdict tasks and waits for them (up to 10 seconds) before it
exits. A judge still working is abandoned, and a run that reaches its
verdict after the drain began is not judged: nothing is written and the
cycle is recorded as
deferred. A write that an accepted verdict already started completes and is recorded if it finishes within that bound; otherwise the runtime shutdown can drop it and its row may be missing. prx evolution statusopens the circuit on consecutiveregressedorrejectedentries;deferredentries are skipped. The running scheduler's own breaker still counts a deferred cycle as a failed run, so the two can disagree.- The strategy layer could not read any decision policy file before this
release, so it never proposed a change. In
automode it now proposes changes tostrategy.decision_policy_path(decision_policy.toml), written only after the judge accepts them. prx evolution triggerprintscommit : …(what became of the proposed change) instead ofrolled : …; its JSON report hascommitandjudge_outcomeinstead ofrolled_back.- In every mode, including
draft_only, ajudge_failedverdict marks theevolution_judgehealth component as an error with the reason, and the scheduler counts the layer run as a failure for its circuit breaker, as it does for a rejected or deferred change. The next scored verdict, or a restart or reload that builds a model judge, marks the component ok again.