Skip to content

v0.4.0 — one engine

Choose a tag to compare

@Birfy Birfy released this 05 Aug 14:23
· 1165 commits to main since this release
40486b2

One engine. 0.3.0 made the numbers readable; this release removes the second
implementation they were being measured against.

AgentDescent and AsyncAgentDescent each had their own round barrier, worker
dispatch, snapshot staggering, merger thread, published head and backpressure.
docs/architecture.md called that "a known wart rather than a design intent", and
it kept costing: two measured fixes that had to be hand-ported between the loops, two
early-stop epsilons nobody chose, and three mechanisms the general engine
re-derived — and got wrong — because the reference stack already had them.

Both are adapters over evolve() now. The public surface is unchanged, the
sequential barrier is preserved so a seeded run stays reproducible, and the
reference table still reads first 0.604, final 1.000, against a fork baseline of
0.379.

Highlights

  • One engine, two runtimes. The reference domain is expressed in the vocabulary
    evolve() / async_evolve() speak, and Worker is gone. The three things the
    translation does not preserve exactly are listed in domains/router.py rather than
    left to be discovered.
  • An execution-and-resource plane, with a page of its own. Sandbox leases with an
    owner, a ceiling and a way to be reclaimed; a real container boundary verified
    against both podman and docker; a ledger and an evaluation cache that survive more
    than one writing process; ClusterParallel and the feedback channel a scheduler
    needs.
  • The executor seam is actually wired. A supplied Policies(executor=...) used to
    run nothing while the run reported that it had gone fine — on both paths.
  • Replaceable policies. Each merge, staleness, retirement and early-stop decision
    is a contract you can swap without changing any of the defaults.
  • Evolving a directory — a skill folder, an agent folder, or its code — with
    FileTree(frozen=[...]) enforced twice.
  • Ports share one tested CLI contract, each owns a directory, and the results
    table now marks which rows survive a change of model.
  • Docs rebuilt as a reference, with a generated API page and one table of every
    primitive that is provided, tested, and not in any engine path.

Breaking

  • Removed: agentdescent.worker.Worker, AsyncConfig.aggregator_interval,
    AsyncConfig.worker_pause, EvidenceCard.version_annotations, the
    domains.router.Task alias.
  • full_eval is no longer part of the Evolvable protocol (implementations keep
    theirs).
  • Evolvable.cheap_eval → evidence_eval; cheap_eval remains an alias, and the
    moved strategy import paths still work.

Each entry in the changelog says what replaced it.

Not claimed

Two of the five re-measured port results are knob-dependent — --hard and
--top-k are calibrated against the published model — and docs/results.md marks
those rows ⚠︎ rather than presenting them as reproductions.

Full detail: CHANGELOG