Skip to content

0.6.0 — multi-head, allocator, trajectories, governance

Choose a tag to compare

@Birfy Birfy released this 16 Oct 08:22
· 171 commits to main since this release
d0cbc26

Everything merged since 0.5.1: multi-head ledger forks, value-directed allocation, L-traj resume, trajectory ledger, governance contracts, CladeThompson, skill_dir structural gates, RRSI building blocks, changelog fragments, and a large set of crash-safety / overflow / parser fixes.

Highlights

  • Multiple live heads — Ledger.fork / live_heads / discard_head so workers can expand different candidates in parallel without serialising on dev.
  • Value-directed budget allocation — evolve(allocator=...) learns which candidates are worth the expensive self-verify rollout.
  • L-traj resume — async_evolve(resume_queue=...) re-runs stragglers against a newer head instead of only counting them.
  • Rollout trajectory ledger — opt-in record_trajectories=True persists versioned trajectories for process supervision and audit replay.
  • Governance invariants — evolve(contract=Contract(invariants=(...))) enforces machine-checkable rules before measurement.
  • CladeThompson selection, skill_dir structural SKILL.md gates, Diff.rationale, and RRSI component / history / schedule fixtures.
  • Changelog fragments — PRs add changelog.d/<n>-<slug>.md instead of editing CHANGELOG.md.
  • Hardening across AuditStore, CostEfficient/FlatPuct/Archive softmax, rewards number parsing, runstore/FileCache/Ledger write contracts, and AdaptiveTrustRegion caps.

Upgrade notes

  • Install with pip install "agentdescent[mcp]==0.6.0" (MCP extra needs Python >= 3.10). DSH package is dsh-agentdescent@0.6.0.
  • Research examples remain in the source checkout. Clone v0.6.0 for the matching tag.
  • Trajectory recording, contracts, allocator, and resume_queue remain opt-in; defaults match 0.5.1 behaviour.

Validation

Release commit on main: d0cbc268c0104c29520ed79b313a37754c7eca96. Required checks build + test (3.9–3.13) were green on the release PR before squash auto-merge.

Full detail: CHANGELOG.

Added (from CHANGELOG)

  • Ledger.fork / live_heads / discard_head — multiple live heads (#75).
  • Value-directed budget allocation — evolve(allocator=...) / async_evolve(allocator=...). BudgetGovernor degrades optional spend (fusion tournaments, the self-verify rollout) against global floors: once spent / max_tokens crosses a threshold, every candidate stops getting the expensive part. The EvoAlloc line of work measures the cost of that fixed allocation when evaluation is the scarce resource — this replaces it with a per-candidate decision learned from the run's own merge history.
  • **async_evolve(resume_queue=...) — the L-traj resume half, the straggler
  • CladeThompson selection policy (#276): HGM's expansion rule, Thompson
  • Add the RRSI component vocabulary (examples/rrsi/components.py) and per-edit
  • kind="skill_dir" now gates candidates structurally before any rollout
  • Diff.rationale carries the FileTree reflector's reason into the ledger
  • Add the RRSI cosine-annealed L0 edit-budget schedule (examples/rrsi/schedule.py)
  • Add an offline RRSI round-selection mechanism fixture adapted from Google's
  • Rollout trajectory ledger. evolve(record_trajectories=True) (and
  • Governance invariants. evolve(contract=Contract(invariants=(...))) (and
  • Changelog fragments (#295): a PR now adds one file changelog.d/<number>-<slug>.md

Fixed (from CHANGELOG)

  • audit.AuditStore keeps its crash-safety contract (#274). A torn tail left
  • FlatPuct / CostEfficient / MCTS / Beam no longer crash or silently
  • sigmoid_novelty_weights / Archive(sampling='sigmoid_novelty') no longer
  • runstore rounds/status no longer break on a non-finite reward or a torn
  • HuggingFace row-cache filenames sanitize split names and bound their
  • TrajectoryStore.record() no longer raises when a record cannot be encoded
  • FileCache write failures no longer leave orphan *.tmp siblings, and
  • A failed Ledger write no longer corrupts the ledger (#265). Payloads are
  • runstore._write_json encodes before creating a sibling tmp and always
  • meta.cached_completion is best effort and never costs the caller a paid call: a cache-write failure (OSError, unencodable or non-str response) returns the response uncached and leaves no *.partial sibling, the entry is encoded before the disk is touched, and a corrupt or non-str entry (including a JSON list, which used to raise TypeError) is counted once, as a miss, instead of as both a hit and a miss (#269).
  • TrajectoryStore.get / path_for round-trip trace_ids whose artifact_id contains a colon by parsing with rsplit(":", 1) (#257). The key is always a hex digest; a leading split treated a namespaced id as part of the key and returned None for a record that was on disk.
  • dataloader cache entries are written atomically (temp file + os.replace),
  • Container sandbox allowlisted env vars are forwarded as --env NAME so
  • CallBudget default floor is capped at base, so a configured ceiling below
  • hf_rows_modelscope(cache=False) now bypasses an existing on-disk cache and
  • AdaptiveTrustRegion widens when a window is dominated by OVERSIZED
  • Allocator A/B comparisons now use the same fully scored seed pairs for
  • The OVERSIZED merge report now quotes the trust region that actually
  • BudgetGovernor's diminishing-returns stop skips a non-finite (NaN/inf)
  • PopulationAggregator records Candidate.parent and backpropagates

… and 4 more in CHANGELOG.