Skip to content

Module map

Every module, what it is for, and where its design is explained. The API reference is the generated companion to this page: this is why and how, that is what.

                          evolve()  ── the one entry point
   ┌───────────────┬──────────┴──────────┬────────────────────┐
   │               │                     │                    │
 what evolves   who does the work    where it runs        how it merges
   │               │                     │                    │
 strategies      agents               executor             aggregator
 filetree        backends             supervisor           defaults
 treestrategy    runners              workspec             ledger
                 sampling             sandbox              verifier
                 dataloader           sandbox_container    evaluator
                 rewards              sandbox_shared       evalcache
                 parallel             pipeline             staleness
                 scheduler                                 governance

              policies ── the contracts, across all four
              metrics · bench ── what a run cost, and comparing runs

The loop

module what it is page
evolution evolve(), the artifact, the actor, the result The evolve method
evolvable Evolvable, Diff, EvidenceCard, Contract — the data model Data model
skill evolve_skill() — dataset in, instruction out Quickstart
skilldir evolve_skill_dir() / _agent_dir() / _agent_code() Directory evolution
async_evolve the same loop without the round barrier Async
orchestrator, async_runtime, domains.router the reference domain the results were measured with — adapters over the engine above, not a second loop Orchestrator

What evolves

module what it is page
strategies SingleSlot, AppendRules, KeyedRules — the text strategies (re-exported from evolution, which is the published import path) Strategies
filetree a directory ↔ artifact state, path safety, TreeSpec Directory evolution
treestrategy FileTree, the <EDITS> proposal protocol, tree_reflector Directory evolution

Who does the work

module what it is page
agents any prompt -> text is a completion; WorkspaceAgent adds a directory Agents
backends a tool-using agent over a document too big to inline Backends
runners give a real agent the candidate directory, one workspace per rollout Directory evolution
dataloader datasets, splits, cached fetches Data layer
rewards the three scorers everyone writes, with the details right Rewards

How the work is spread

module what it is page
parallel DP / TP / PP — how a round's work is split Parallelism
sampling which task a worker rolls out next Sampling
scheduler duration-aware dispatch, stragglers, the audit queue Scheduling
pipeline the retirement, early-stop and backpressure rules both runtimes share Async

Where it runs

module what it is page
executor the rollout(spec) -> Result seam, and the in-process default Execution
supervisor persistent worker processes, and deciding when one is gone Execution
workspec a rollout as data: named callables instead of closures Execution
sandbox workspace leases: one ceiling, one release path, reclaim what an owner abandoned Sandboxes
sandbox_shared one ceiling across processes, counted from the lease directory Sandboxes
sandbox_container the provider that makes a sandbox an actual boundary (needs docker/podman) Sandboxes

How a change is accepted

module what it is page
aggregator the optimizer: staleness → conflict → fusion → acceptance → commit Aggregator
defaults the shipped algorithm as replaceable pieces: conflict, fusion, acceptance, promotion Aggregator
stats the acceptance maths: Beta posterior, P(Δ>0), annealed δ, UCB, difficulty weight Aggregator
verifier rule / learned / oracle, and the budget on the expensive one Verifier
evaluator the gate's own bounded, reusable concurrency, separate from the rollouts' Verifier
evalcache memoised evaluations: single-flight, environment-aware, shareable across processes Verifier
staleness what to do with a diff whose base version moved Staleness
ledger the git-backed, compare-and-swap artifact store Ledger
governance L0 frozen / L1 slow / L2 fast, by blast radius Governance

Across all of it

module what it is page
policies the contracts: which decisions are replaceable, and what each is given Architecture
metrics what the run cost: time, calls, staleness ratio, cache hits, sandbox waits Usage
bench the configuration matrix and the rules that make comparing them mean something Efficiency

Reading order

Depending on what you are doing:

Just using it. InstallQuickstartThe evolve method → the one module you need to swap.

Evolving a folder or an agent's code. Quickstart — a directoryDirectory evolutionGovernance for the safety model.

Deciding whether to trust it. ConceptsAggregatorOrchestrator (how the claims were measured) → Results.

Extending it. Data modelStrategiesAggregator → the algorithm ports, each of which replaces a different piece.

Provided, tested, and not in any engine path

Some of what import agentdescent gives you is a primitive for a configuration that does not ship yet — the design calls for it, it is implemented and tested in isolation, and no loop reaches it today. Each one says so in its own docstring, which meant finding out cost a read of the source, one class at a time. They are all in one table instead:

name why it exists what would reach it
Ledger.commit_atomic 2PC across several artifacts, for a contract-breaking diff that must land with its adapters a multi-artifact library; evolve() registers exactly one
L1SerialGate "at most one L1 diff in evaluation anywhere" concurrent merging; every shipped runtime merges on one thread, so the guarantee already holds by construction
ResumeQueue turn-level checkpoints of a timed-out rollout a rollout that exposes its turns; run(rendered, task) -> output is opaque, which is what lets any agent be plugged in
AuditScheduler.pop draining the Ĝ-ordered audit queue out of band AuditScheduler(collect=True); the default computes priorities without queuing, because nothing drains it
EvidenceBuffer.settled discarded evidence stays addressable — the structural advantage of artifacts over gradients re-filing settled cards into the trajectory pool; today it is a bounded diagnostic ring
TaskScheduler × artifact axis the design's L-task is (task cluster × artifact) more than one artifact; TaskCluster has no artifact dimension. The cluster axis is reachable from evolve() via ClusterParallel
PipelineParallel one artifact per stage, with upstream blame a multi-artifact run; evolve() refuses it rather than degrading to DP in silence

The rule they share: a primitive that is implemented and unreachable is honest; one that is reachable and silently does nothing is not, which is why PipelineParallel raises and Policies refuses a field it cannot honour.

Dependency shape

Nothing in the framework imports a provider SDK at module level, and the core imports nothing outside the standard library:

evolvable ── ledger ── aggregator ── evolution ── skill / skilldir
    │           │          │             │
governance   verifier  staleness    parallel · sampling · scheduler
                              agents ── backends ── runners
                              filetree ── treestrategy

anthropic and openhands-ai are imported lazily inside the functions that need them, so the rest of the framework runs without either.