From 88ebdfb0ced891d869da825daf4b2869fe42342a Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Fri, 9 Oct 2026 20:38:59 -0700 Subject: [PATCH 1/4] chore(release): prepare 0.6.0 candidate --- .claude-plugin/marketplace.json | 2 +- CHANGELOG.md | 37 +++++++++++++++++-- CONTRIBUTING.md | 4 +- README.md | 32 ++++++++-------- agentdescent/__init__.py | 2 +- docs/index.md | 9 ++--- docs/install.md | 36 ++++++++++-------- docs/plugin-quickstart.md | 16 +++++--- docs/plugins.md | 16 +++++--- .../claude-code/.claude-plugin/plugin.json | 2 +- integrations/dsh-agentdescent/package.json | 2 +- 11 files changed, 102 insertions(+), 56 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 9c857c64..c290a335 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ "name": "agentdescent", "source": "./integrations/claude-code", "description": "Evolve skills, agents, prompts, code and plugins against examples with a parallel, merge-based optimiser.", - "version": "0.5.0" + "version": "0.6.0" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 607cc883..e5d579cc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,35 @@ All notable changes to AgentDescent are documented here. The format follows ## [Unreleased] +## [0.6.0] — 2026-10-10 + +### Release summary + +- Token budgets, cost-aware selection, graceful budget degradation and optional + diminishing-returns stopping; checkpointed search state survives a restart. +- Sparse verifier auditing and calibration, opt-in priority-ordered audit drain, + and replay-aware sampling and proposals that can use settled evidence. +- Policy-slot evolution, the EvoX Genesis port with skill extraction and read-only + investigation, and the porous-molecule tree-search example. Research examples + remain in the source repository rather than the installed wheel. +- More reliable first runs: actionable spec/dataset errors, policy-slot scaffolds, + fail-fast host installation and a clean installed-wheel CLI/MCP smoke gate. + +### Upgrade notes + +- Python >= 3.9 remains supported; the MCP extra requires Python >= 3.10. + NumPy >= 1.20 is now an installed dependency for prediction-powered auditing. +- Use `ThreeLayerVerifier.full_eval` and `full_eval_matches_counts`. The old + `oracle_eval` and `oracle_shares_full_set` aliases remain available; using + `oracle_eval` emits a `DeprecationWarning`. Removal is planned for 0.7. +- Checkpointing, replay weighting and audit draining remain opt-in. Token-budget + enforcement depends on usage reported by the model adapter; it is not a + provider-side hard spending limit. + +The detailed changes below cover the merged commits since 0.5.0. They do not +include the open multi-head, multi-artifact, asynchronous trajectory-resume, +value-directed evaluation or Genesis blind-mode proposals. + ### Fixed - Spec and dataset file failures now report a concise `SpecError` instead of a @@ -957,8 +986,8 @@ All notable changes to AgentDescent are documented here. The format follows the scorer is biased. Reading it as ground truth is what let the docs claim the loop audits itself against something outside itself, which it does not. - Both old names still work, once, with a `DeprecationWarning`, and are removed - in 0.7. `VerifierProtocol` declares `full_eval`; the engine reads a custom + Both old names still work; the `oracle_eval` compatibility path emits a + `DeprecationWarning`. Both aliases are scheduled for removal in 0.7. `VerifierProtocol` declares `full_eval`; the engine reads a custom verifier through `verifier.full_eval_of` / `verifier.shares_eval_counts`, which accept either spelling -- so a verifier written against the pre-0.6 page keeps running instead of raising `AttributeError` in the middle of a merge. The @@ -4324,7 +4353,9 @@ First public release on PyPI as **`agentdescent`**. discrete-space `Aggregator`, staleness policies, DP/TP/PP parallelism, layered governance, and the provider-agnostic `agentdescent.agents` completion layer. -[Unreleased]: https://github.com/Birfy/agentdescent/compare/v0.4.6...HEAD +[Unreleased]: https://github.com/Birfy/agentdescent/compare/v0.6.0...HEAD +[0.6.0]: https://github.com/Birfy/agentdescent/compare/v0.5.0...v0.6.0 +[0.5.0]: https://github.com/Birfy/agentdescent/compare/v0.4.6...v0.5.0 [0.4.6]: https://github.com/Birfy/agentdescent/compare/v0.4.5...v0.4.6 [0.4.5]: https://github.com/Birfy/agentdescent/compare/v0.4.2...v0.4.5 [0.4.2]: https://github.com/Birfy/agentdescent/compare/v0.4.1...v0.4.2 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 95ea2095..eac690e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -9,7 +9,7 @@ are very welcome. ```bash git clone https://github.com/Birfy/agentdescent cd agentdescent -pip install -e ".[dev]" # core engine has zero runtime deps; [dev] adds pytest +pip install -e ".[dev]" # installs NumPy plus the pytest/PyYAML development tools ``` Python ≥ 3.9 is required. @@ -38,7 +38,7 @@ The suite is **offline and deterministic** (no network, no model API): pytest -q ``` -CI runs the same suite on Python 3.9 / 3.11 / 3.12 for every push and PR. Please +CI runs the same suite on Python 3.9 / 3.10 / 3.11 / 3.12 for every push and PR. Please add or update tests for any behavior change — the reference domain (`agentdescent/domains/router.py`) and the example stubs let you test the full parallel/async loop without an API key. diff --git a/README.md b/README.md index 8d57d198..64ff72b1 100644 --- a/README.md +++ b/README.md @@ -63,38 +63,36 @@ The figure is the paper's, rendered from its TikZ source by [`tools/gen_architecture_figure.py`](tools/gen_architecture_figure.py) so it cannot drift from what the paper shows. -## Try the offline demo from current `main` +## Install and run the offline demo -The packaged `agentdescent demo` command shown here is on the unreleased -`main` branch. Install that checkout before running it: +These instructions target **0.6.0**. Once that version is published: ```bash -git clone --branch main https://github.com/Birfy/agentdescent && cd agentdescent +pip install "agentdescent>=0.6.0" +agentdescent demo +``` + +Before publication, or when developing from source, install your checkout: + +```bash +git clone https://github.com/Birfy/agentdescent && cd agentdescent pip install -e . agentdescent demo ``` The library supports Python ≥ 3.9 and installs NumPy for its prediction-powered audit estimator. The packaged demo runs the offline -evolution loop without a model API key. On current unreleased `main`, it ends -with output like: +evolution loop without a model API key and ends with output like: ``` held-out reward: 1.000 outcomes: {'committed': 1} what it learned: rules.md -> 'COLUMN: amount' ``` -For the published stable v0.5.0 installation, run: - -```bash -pip install agentdescent -``` - -Its documented offline example uses `python -m examples.run_demo`; those -examples are outside the wheel, so clone the repo and follow -[install and first run](docs/install.md). The library includes -[`evolve()`](docs/evolution.md), [`DirectoryStrategy`](docs/directory-evolution.md), -and its algorithm ports. +Research examples are outside the wheel. For a source checkout and the +`python -m examples.run_demo` comparison, see [install and first run](docs/install.md). +The library includes [`evolve()`](docs/evolution.md), +[`DirectoryStrategy`](docs/directory-evolution.md), and its algorithm ports. ## Quickstart — a dataset to an evolved skill diff --git a/agentdescent/__init__.py b/agentdescent/__init__.py index 9827cd2c..a1e7963c 100644 --- a/agentdescent/__init__.py +++ b/agentdescent/__init__.py @@ -211,7 +211,7 @@ shard_round_robin, ) -__version__ = "0.5.0" +__version__ = "0.6.0" __all__ = [ "Contract", diff --git a/docs/index.md b/docs/index.md index 8f727cf5..5cc6e0bf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -210,16 +210,15 @@ pip install agentdescent ## 30-second tour -This demo command is available from the unreleased `main` checkout: +For 0.6.0, once published: ```bash -git clone --branch main https://github.com/Birfy/agentdescent && cd agentdescent -pip install -e . +pip install "agentdescent>=0.6.0" agentdescent demo # complete offline evolution loop ``` -For the published v0.5.0 install and source-example workflow, see -[install and first run](install.md). Everything runnable, with the output each +Before publication, use the editable checkout instructions in +[install and first run](install.md), which also covers the source examples. Everything runnable, with the output each one produces: [run everything](usage.md). No LLM or external service is required: the diff --git a/docs/install.md b/docs/install.md index 0aa5017d..97e7667b 100644 --- a/docs/install.md +++ b/docs/install.md @@ -1,14 +1,23 @@ # Install and first run -## Current `main`: packaged offline demo +## Packaged offline demo + +These instructions target **0.6.0**. Once that version is published: + +```bash +pip install "agentdescent>=0.6.0" +agentdescent demo +``` + +Before publication, or to work on the source, install your checkout instead: ```bash -git clone --branch main https://github.com/Birfy/agentdescent && cd agentdescent +git clone https://github.com/Birfy/agentdescent && cd agentdescent pip install -e . agentdescent demo ``` -The library supports Python ≥ 3.9 and current `main` installs NumPy for the +The library supports Python ≥ 3.9 and installs NumPy for the [`audit.ppi`](api.md) estimator. The packaged CLI demo runs offline and needs no model API key: @@ -16,7 +25,7 @@ model API key: agentdescent demo ``` -On current unreleased `main`, a successful run ends with output like: +A successful run ends with output like: ``` held-out reward: 1.000 outcomes: {'committed': 1} @@ -39,23 +48,20 @@ the [quickstart](quickstart-skill.md) to connect a model. The library includes Nothing else is needed for an OpenAI-compatible endpoint — GLM, DeepSeek, a local vLLM server — because [`openai_compatible`](agents.md) speaks HTTP directly. -## Published v0.5.0 installation and source examples +## Source examples -Install the stable PyPI package with: +Research examples are kept in the source repository, outside the installed +wheel. For the published 0.6.0 examples, clone the matching tag and install the +contributor tools: ```bash -pip install agentdescent -``` - -The v0.5.0 release's documented offline demo uses research examples kept in the -source repository, outside the installed wheel. To run that example, clone the -tagged source and install the contributor tools: - -```bash -git clone --branch v0.5.0 https://github.com/Birfy/agentdescent && cd agentdescent +git clone --branch v0.6.0 https://github.com/Birfy/agentdescent && cd agentdescent pip install -e ".[dev]" ``` +The tag is created at publication. Before then, use your release-candidate +checkout and run `pip install -e ".[dev]"` there. + Then run the source demo (no API key): ```bash diff --git a/docs/plugin-quickstart.md b/docs/plugin-quickstart.md index 5a6ea310..c2f64581 100644 --- a/docs/plugin-quickstart.md +++ b/docs/plugin-quickstart.md @@ -10,15 +10,21 @@ until step 3. ## 1. Install -These CLI commands use current unreleased `main`; install that checkout first: +These commands target **0.6.0**. Once published, install the package with its +MCP extra: + +```bash +pip install "agentdescent[mcp]>=0.6.0" +``` + +Before publication, or if you already have a source checkout: ```bash -git clone --branch main https://github.com/Birfy/agentdescent && cd agentdescent pip install -e ".[mcp]" ``` -For the published v0.5.0 install and documented source-example path, see -[Install and first run](install.md#published-v050-installation-and-source-examples). +See [Install and first run](install.md) for the source checkout and +[source examples](install.md#source-examples). `[mcp]` is the extra that lets agents talk to AgentDescent. Skip it and the CLI still works, but `agentdescent mcp` exits 3 and tells you to add it. @@ -47,7 +53,7 @@ make a real run fail — but none of them stop step 2. `bin/` to add. Hosts start the server as a **subprocess**, so it must be on the `PATH` of whatever launches your agent, not just your interactive shell. -## 2. Current `main`: run the packaged demo offline +## 2. Run the packaged demo offline ```bash agentdescent demo diff --git a/docs/plugins.md b/docs/plugins.md index 881dfe82..f942ec06 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -11,18 +11,24 @@ The design record — why it is shaped this way and what was considered — is ## Install -The CLI example below uses current unreleased `main`: +For 0.6.0, once published: ```bash -git clone --branch main https://github.com/Birfy/agentdescent && cd agentdescent -pip install -e ".[mcp]" # the MCP server needs this extra (and Python >= 3.10) +pip install "agentdescent[mcp]>=0.6.0" # the MCP server needs this extra (and Python >= 3.10) agentdescent demo # a complete evolution, offline, no key agentdescent doctor # which agent CLIs, keys and optional pieces are here agentdescent install dsh # or: claude-code, codex, opencode ``` -For the published v0.5.0 install and documented source-example workflow, see -[install and first run](install.md#published-v050-installation-and-source-examples). +Before publication, clone the repository as described in +[install and first run](install.md), then install the MCP extra from that checkout: + +```bash +pip install -e ".[mcp]" +``` + +Research demos beyond `agentdescent demo` use the +[source examples](install.md#source-examples). The MCP SDK requires Python >= 3.10; AgentDescent supports 3.9. On 3.9 the extra installs nothing and the tool surface is unavailable — the CLI verbs are diff --git a/integrations/claude-code/.claude-plugin/plugin.json b/integrations/claude-code/.claude-plugin/plugin.json index 71e6e069..0d1dd5f0 100644 --- a/integrations/claude-code/.claude-plugin/plugin.json +++ b/integrations/claude-code/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "agentdescent", "description": "Evolve skills, agents, prompts, code and plugins against examples with a parallel, merge-based optimiser.", - "version": "0.5.0", + "version": "0.6.0", "author": { "name": "AgentDescent" }, diff --git a/integrations/dsh-agentdescent/package.json b/integrations/dsh-agentdescent/package.json index 57d6dd9a..b0819499 100644 --- a/integrations/dsh-agentdescent/package.json +++ b/integrations/dsh-agentdescent/package.json @@ -1,6 +1,6 @@ { "name": "dsh-agentdescent", - "version": "0.5.0", + "version": "0.6.0", "description": "Evolve skills, agents, prompts, code and plugins from inside DeepSeek Harness, with AgentDescent.", "keywords": [ "dsh-plugin", From 2771a09e23a6893ac6c16ca18cb822ae1ea65074 Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Fri, 9 Oct 2026 20:54:34 -0700 Subject: [PATCH 2/4] chore(release): retarget candidate to 0.5.1 --- .claude-plugin/marketplace.json | 2 +- CHANGELOG.md | 8 ++++---- README.md | 4 ++-- agentdescent/__init__.py | 2 +- agentdescent/aggregator.py | 4 ++-- agentdescent/policies.py | 2 +- agentdescent/verifier.py | 18 +++++++++--------- docs/design-directory-evolution.md | 2 +- docs/index.md | 4 ++-- docs/install.md | 8 ++++---- docs/plugin-quickstart.md | 4 ++-- docs/plugins.md | 4 ++-- docs/verifier.md | 6 +++--- .../claude-code/.claude-plugin/plugin.json | 2 +- integrations/dsh-agentdescent/package.json | 2 +- tests/test_audit_and_cheap_layer.py | 6 +++--- tests/test_verifier.py | 2 +- 17 files changed, 40 insertions(+), 40 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index c290a335..bbffc202 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -11,7 +11,7 @@ "name": "agentdescent", "source": "./integrations/claude-code", "description": "Evolve skills, agents, prompts, code and plugins against examples with a parallel, merge-based optimiser.", - "version": "0.6.0" + "version": "0.5.1" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index e5d579cc..9e5bc308 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ All notable changes to AgentDescent are documented here. The format follows ## [Unreleased] -## [0.6.0] — 2026-10-10 +## [0.5.1] — 2026-10-10 ### Release summary @@ -989,7 +989,7 @@ value-directed evaluation or Genesis blind-mode proposals. Both old names still work; the `oracle_eval` compatibility path emits a `DeprecationWarning`. Both aliases are scheduled for removal in 0.7. `VerifierProtocol` declares `full_eval`; the engine reads a custom verifier through `verifier.full_eval_of` / `verifier.shares_eval_counts`, which - accept either spelling -- so a verifier written against the pre-0.6 page keeps + accept either spelling -- so a verifier written against the pre-0.5.1 page keeps running instead of raising `AttributeError` in the middle of a merge. The `oracle_budget` argument, `VerifierBudget.oracle_calls_*` and the `oracle-rejected` merge outcome keep their names: they are the public spelling @@ -4353,8 +4353,8 @@ First public release on PyPI as **`agentdescent`**. discrete-space `Aggregator`, staleness policies, DP/TP/PP parallelism, layered governance, and the provider-agnostic `agentdescent.agents` completion layer. -[Unreleased]: https://github.com/Birfy/agentdescent/compare/v0.6.0...HEAD -[0.6.0]: https://github.com/Birfy/agentdescent/compare/v0.5.0...v0.6.0 +[Unreleased]: https://github.com/Birfy/agentdescent/compare/v0.5.1...HEAD +[0.5.1]: https://github.com/Birfy/agentdescent/compare/v0.5.0...v0.5.1 [0.5.0]: https://github.com/Birfy/agentdescent/compare/v0.4.6...v0.5.0 [0.4.6]: https://github.com/Birfy/agentdescent/compare/v0.4.5...v0.4.6 [0.4.5]: https://github.com/Birfy/agentdescent/compare/v0.4.2...v0.4.5 diff --git a/README.md b/README.md index 64ff72b1..f1ae1dd9 100644 --- a/README.md +++ b/README.md @@ -65,10 +65,10 @@ cannot drift from what the paper shows. ## Install and run the offline demo -These instructions target **0.6.0**. Once that version is published: +These instructions target **0.5.1**. Once that version is published: ```bash -pip install "agentdescent>=0.6.0" +pip install "agentdescent>=0.5.1" agentdescent demo ``` diff --git a/agentdescent/__init__.py b/agentdescent/__init__.py index a1e7963c..55d657cd 100644 --- a/agentdescent/__init__.py +++ b/agentdescent/__init__.py @@ -211,7 +211,7 @@ shard_round_robin, ) -__version__ = "0.6.0" +__version__ = "0.5.1" __all__ = [ "Contract", diff --git a/agentdescent/aggregator.py b/agentdescent/aggregator.py index 5c1db5f9..7589dea5 100644 --- a/agentdescent/aggregator.py +++ b/agentdescent/aggregator.py @@ -24,7 +24,7 @@ "spot-check" arrow, which reads as advisory when it holds a veto. Note what this stage does *not* do. It re-reads the caller's own scorer over the -whole held-out set (``full_eval``, called ``oracle_eval`` until 0.6), so it can +whole held-out set (``full_eval``, called ``oracle_eval`` until 0.5.1), so it can catch a verdict that rested on too few tasks and cannot catch one that rested on a biased scorer -- the outcome name outlived the rename and overstates the check. :mod:`agentdescent.audit` is the second source. @@ -1055,7 +1055,7 @@ def _audit(self, artifact, artifact_id, best_state, best_diff, # # Read through the two helpers rather than by attribute: a verifier # is whatever the caller handed us, including one written against the - # pre-0.6 `oracle_eval` / `oracle_shares_full_set` names. Reading the + # pre-0.5.1 `oracle_eval` / `oracle_shares_full_set` names. Reading the # new name directly would have made an old custom verifier fail here, # mid-merge, several minutes into a run. if shares_eval_counts(self.verifier): diff --git a/agentdescent/policies.py b/agentdescent/policies.py index 0b3fc3d1..3470f14f 100644 --- a/agentdescent/policies.py +++ b/agentdescent/policies.py @@ -334,7 +334,7 @@ class VerifierProtocol(Protocol): Not three. `docs/verifier.md` said three for a while, and a verifier written from that page fails in the middle of a merge rather than at startup. - ``full_eval`` was ``oracle_eval`` until 0.6. The engine still reads the old + ``full_eval`` was ``oracle_eval`` until 0.5.1. The engine still reads the old name, once, with a `DeprecationWarning` (:func:`~agentdescent.verifier.full_eval_of`), so an implementation written against the old page keeps working until 0.7. The rename is a correction: diff --git a/agentdescent/verifier.py b/agentdescent/verifier.py index a3e4f2b2..5021bc69 100644 --- a/agentdescent/verifier.py +++ b/agentdescent/verifier.py @@ -13,7 +13,7 @@ .. note:: **The expensive layer is not a second opinion.** - ``full_eval`` was called ``oracle_eval`` until 0.6, and the old name claimed + ``full_eval`` was called ``oracle_eval`` until 0.5.1, and the old name claimed more than the code delivers. Every layer here calls the one ``eval_fn`` the caller supplied; they differ in **how many tasks** they score, not in *who is scoring*. So the expensive layer bounds the sampling error of a measurement @@ -123,7 +123,7 @@ class ThreeLayerVerifier: #: itself declares over the value it inherited from here. full_eval_matches_counts = True - #: Pre-0.6 name for :attr:`full_eval_matches_counts`. Read through + #: Pre-0.5.1 name for :attr:`full_eval_matches_counts`. Read through #: :func:`shares_eval_counts`, which prefers the new one, so a custom #: verifier that set either keeps working. oracle_shares_full_set = True @@ -219,7 +219,7 @@ def eval_counts(self, artifact: Evolvable, def full_eval(self, artifact: Evolvable) -> float: """``eval_fn`` on the **whole** held-out set. Consumes audit budget. - Called ``oracle_eval`` until 0.6, and the rename is a correction rather + Called ``oracle_eval`` until 0.5.1, and the rename is a correction rather than a tidy-up. The name promised an *independent source of truth* and the method delivers the same ``eval_fn`` the cheap layers call, differing only in **how many tasks** it looks at -- so it can shrink the variance of @@ -264,10 +264,10 @@ def oracle_eval(self, artifact: Evolvable) -> float: return self.full_eval(artifact) -# -- reading a verifier that may predate the 0.6 rename ---------------------- +# -- reading a verifier that may predate the 0.5.1 rename ---------------------- # # `VerifierProtocol` is structural, so a verifier is whatever a caller hands the -# engine -- including one written against the pre-0.6 page and carrying only the +# engine -- including one written against the pre-0.5.1 page and carrying only the # old names. These two read either spelling, so the rename costs a warning # rather than an `AttributeError` in the middle of somebody's merge. @@ -275,7 +275,7 @@ def oracle_eval(self, artifact: Evolvable) -> float: def full_eval_of(verifier: Any) -> Callable[[Evolvable], float]: """The verifier's whole-held-out-set scorer, under whichever name it has. - Prefers ``full_eval``; falls back to a pre-0.6 ``oracle_eval`` and says so + Prefers ``full_eval``; falls back to a pre-0.5.1 ``oracle_eval`` and says so once per verifier class, naming the class so the warning points at the file that has to change. """ @@ -290,7 +290,7 @@ def full_eval_of(verifier: Any) -> Callable[[Evolvable], float]: "full_eval") warnings.warn( f"{type(verifier).__name__} defines oracle_eval but not full_eval. The " - "method was renamed in 0.6 -- oracle_eval is read for now and dropped " + "method was renamed in 0.5.1 -- oracle_eval is read for now and dropped " "in 0.7. Rename it; the behaviour is unchanged.", DeprecationWarning, stacklevel=2) return legacy @@ -303,13 +303,13 @@ def shares_eval_counts(verifier: Any) -> bool: buying the same sweep twice -- and, more importantly, instead of routing a commit decision through a call that degrades to a sub-sample once the budget is gone. Reads :attr:`~ThreeLayerVerifier.full_eval_matches_counts`, then the - pre-0.6 ``oracle_shares_full_set``. + pre-0.5.1 ``oracle_shares_full_set``. """ # A *declaration* beats an inherited default. `ThreeLayerVerifier` sets # `full_eval_matches_counts = True` as a statement about how that class is # written, and a subclass inherits it -- so the escape hatch the attribute's # docstring offers ("simply does not define it") does not exist for a - # subclass, and one that set the pre-0.6 `oracle_shares_full_set = False` + # subclass, and one that set the pre-0.5.1 `oracle_shares_full_set = False` # was ignored. Its independent expensive layer then went uncalled and the # gate degraded to the cheap measurement it existed to cross-check, with no # warning. diff --git a/docs/design-directory-evolution.md b/docs/design-directory-evolution.md index 876a2925..93c51872 100644 --- a/docs/design-directory-evolution.md +++ b/docs/design-directory-evolution.md @@ -378,7 +378,7 @@ result.write_to(path, backup=True) # 装回,先备份 两个反直觉的点,都已对代码核实: -1. **审计门是免费的。** `full_eval`(0.6 前叫 `oracle_eval`)和 `eval_counts` 调同一个 `eval_fn`、同一个 +1. **审计门是免费的。** `full_eval`(0.5.1 前叫 `oracle_eval`)和 `eval_counts` 调同一个 `eval_fn`、同一个 held-out 集,而 `_EvalCache` 按 `(render(), task.id)` 记忆化 ([evolution.py:531](https://github.com/Birfy/agentdescent/blob/main/agentdescent/evolution.py#L531)),所以 L1 的强制审计只消耗 `oracle_budget` 计数器,不产生任何额外 agent 调用。**演化 agent 目录/代码 diff --git a/docs/index.md b/docs/index.md index 5cc6e0bf..edd40853 100644 --- a/docs/index.md +++ b/docs/index.md @@ -210,10 +210,10 @@ pip install agentdescent ## 30-second tour -For 0.6.0, once published: +For 0.5.1, once published: ```bash -pip install "agentdescent>=0.6.0" +pip install "agentdescent>=0.5.1" agentdescent demo # complete offline evolution loop ``` diff --git a/docs/install.md b/docs/install.md index 97e7667b..6e77be55 100644 --- a/docs/install.md +++ b/docs/install.md @@ -2,10 +2,10 @@ ## Packaged offline demo -These instructions target **0.6.0**. Once that version is published: +These instructions target **0.5.1**. Once that version is published: ```bash -pip install "agentdescent>=0.6.0" +pip install "agentdescent>=0.5.1" agentdescent demo ``` @@ -51,11 +51,11 @@ vLLM server — because [`openai_compatible`](agents.md) speaks HTTP directly. ## Source examples Research examples are kept in the source repository, outside the installed -wheel. For the published 0.6.0 examples, clone the matching tag and install the +wheel. For the published 0.5.1 examples, clone the matching tag and install the contributor tools: ```bash -git clone --branch v0.6.0 https://github.com/Birfy/agentdescent && cd agentdescent +git clone --branch v0.5.1 https://github.com/Birfy/agentdescent && cd agentdescent pip install -e ".[dev]" ``` diff --git a/docs/plugin-quickstart.md b/docs/plugin-quickstart.md index c2f64581..8a5bfc17 100644 --- a/docs/plugin-quickstart.md +++ b/docs/plugin-quickstart.md @@ -10,11 +10,11 @@ until step 3. ## 1. Install -These commands target **0.6.0**. Once published, install the package with its +These commands target **0.5.1**. Once published, install the package with its MCP extra: ```bash -pip install "agentdescent[mcp]>=0.6.0" +pip install "agentdescent[mcp]>=0.5.1" ``` Before publication, or if you already have a source checkout: diff --git a/docs/plugins.md b/docs/plugins.md index f942ec06..ef49b80b 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -11,10 +11,10 @@ The design record — why it is shaped this way and what was considered — is ## Install -For 0.6.0, once published: +For 0.5.1, once published: ```bash -pip install "agentdescent[mcp]>=0.6.0" # the MCP server needs this extra (and Python >= 3.10) +pip install "agentdescent[mcp]>=0.5.1" # the MCP server needs this extra (and Python >= 3.10) agentdescent demo # a complete evolution, offline, no key agentdescent doctor # which agent CLIs, keys and optional pieces are here agentdescent install dsh # or: claude-code, codex, opencode diff --git a/docs/verifier.md b/docs/verifier.md index 9a7c5c6f..d48bc2b9 100644 --- a/docs/verifier.md +++ b/docs/verifier.md @@ -100,7 +100,7 @@ verifier.eval_counts(artifact) # (successes, failures) on the FULL held-out s verifier.full_eval(artifact) # the same eval_fn, whole set, spends budget ``` -!!! warning "`full_eval` was `oracle_eval` until 0.6" +!!! warning "`full_eval` was `oracle_eval` until 0.5.1" The old name promised an independent source of truth. Every layer here calls the one `eval_fn` you supplied and they differ only in **how many tasks** they score — so this layer bounds *sampling error* and cannot detect *bias*. If @@ -216,7 +216,7 @@ eval_counts(artifact) -> (successes, failures) # the acceptance test, full set full_eval(artifact) -> float # the same eval_fn, whole set ``` -Pre-0.6 code named the last one `oracle_eval`. The engine still reads that name, +Pre-0.5.1 code named the last one `oracle_eval`. The engine still reads that name, once, with a `DeprecationWarning`, and drops it in 0.7. There is also one **optional** attribute, read with a default so a substitute @@ -230,7 +230,7 @@ Set it when both are the same measurement, and the aggregator will reuse the rates it already has rather than asking twice. Leave it out when your full-set scorer is genuinely independent — then it is called, and it must stay exact: a `full_eval` that gets cheaper under budget pressure holds a veto over commits. -The pre-0.6 spelling `oracle_shares_full_set` is still read, and the new name +The pre-0.5.1 spelling `oracle_shares_full_set` is still read, and the new name wins if a class carries both. An [`aggregator_factory`](aggregator.md#replacing-aggregator_factory-aggregatorprotocol) diff --git a/integrations/claude-code/.claude-plugin/plugin.json b/integrations/claude-code/.claude-plugin/plugin.json index 0d1dd5f0..c3af96f3 100644 --- a/integrations/claude-code/.claude-plugin/plugin.json +++ b/integrations/claude-code/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "agentdescent", "description": "Evolve skills, agents, prompts, code and plugins against examples with a parallel, merge-based optimiser.", - "version": "0.6.0", + "version": "0.5.1", "author": { "name": "AgentDescent" }, diff --git a/integrations/dsh-agentdescent/package.json b/integrations/dsh-agentdescent/package.json index b0819499..7c846edb 100644 --- a/integrations/dsh-agentdescent/package.json +++ b/integrations/dsh-agentdescent/package.json @@ -1,6 +1,6 @@ { "name": "dsh-agentdescent", - "version": "0.6.0", + "version": "0.5.1", "description": "Evolve skills, agents, prompts, code and plugins from inside DeepSeek Harness, with AgentDescent.", "keywords": [ "dsh-plugin", diff --git a/tests/test_audit_and_cheap_layer.py b/tests/test_audit_and_cheap_layer.py index 6647076e..cdbd699d 100644 --- a/tests/test_audit_and_cheap_layer.py +++ b/tests/test_audit_and_cheap_layer.py @@ -246,7 +246,7 @@ def test_the_full_set_is_still_what_commits(tmp_path): assert round(successes + failures) == len(agg.verifier.held_out) -# -- the 0.6 rename: oracle_eval -> full_eval ----------------------------------- +# -- the 0.5.1 rename: oracle_eval -> full_eval ----------------------------------- # # `VerifierProtocol` is structural, so a verifier is whatever a caller hands the # engine. Renaming a method it calls therefore breaks other people's code at the @@ -283,7 +283,7 @@ def oracle_eval(self, artifact): return 0.25 legacy = Legacy() - with pytest.warns(DeprecationWarning, match="renamed in 0.6"): + with pytest.warns(DeprecationWarning, match="renamed in 0.5.1"): assert full_eval_of(legacy)(_Stub()) == 0.25 assert shares_eval_counts(legacy) is False @@ -316,7 +316,7 @@ def test_a_pre_rename_verifier_still_drives_a_whole_run_through_the_audit_gate() Written as a standalone class rather than a proxy on purpose. A proxy with `__getattr__` forwards `full_eval_matches_counts` from whatever it wraps, so it would take the reuse shortcut and never reach the legacy method -- the - test would pass while testing nothing. Somebody's real pre-0.6 verifier is a + test would pass while testing nothing. Somebody's real pre-0.5.1 verifier is a class like this one. `blast_radius=0.6` is L1, so `force_oracle` fires on every merge; with diff --git a/tests/test_verifier.py b/tests/test_verifier.py index f6bb7c3d..490f9d5e 100644 --- a/tests/test_verifier.py +++ b/tests/test_verifier.py @@ -12,7 +12,7 @@ def test_a_subclass_can_declare_its_expensive_layer_independent(): """`ThreeLayerVerifier` sets `full_eval_matches_counts = True` as a statement about how *that* class is written, and a subclass inherits it -- so the escape hatch the attribute's docstring offers, "simply does not - define it", is not available to a subclass. One that set the pre-0.6 + define it", is not available to a subclass. One that set the pre-0.5.1 `oracle_shares_full_set = False` was ignored, its independent expensive layer went uncalled, and the gate degraded to the cheap measurement it existed to cross-check.""" From c378e73ae8a21d0aa21ea69078d436912834e506 Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Fri, 9 Oct 2026 21:11:23 -0700 Subject: [PATCH 3/4] test(packaging): validate quoted release installs without losing checkout guard --- README.md | 5 +-- tests/test_packaging.py | 67 +++++++++++++++++++++++++++++++++++------ 2 files changed, 61 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index f1ae1dd9..5cb2dff7 100644 --- a/README.md +++ b/README.md @@ -89,8 +89,9 @@ held-out reward: 1.000 outcomes: {'committed': 1} what it learned: rules.md -> 'COLUMN: amount' ``` -Research examples are outside the wheel. For a source checkout and the -`python -m examples.run_demo` comparison, see [install and first run](docs/install.md). +Research examples are outside the wheel. To run the +`python -m examples.run_demo` comparison, clone the repo and follow +[install and first run](docs/install.md). The library includes [`evolve()`](docs/evolution.md), [`DirectoryStrategy`](docs/directory-evolution.md), and its algorithm ports. diff --git a/tests/test_packaging.py b/tests/test_packaging.py index ed2a3fd6..4586cab1 100644 --- a/tests/test_packaging.py +++ b/tests/test_packaging.py @@ -10,6 +10,8 @@ import pathlib import re +import pytest + ROOT = pathlib.Path(__file__).resolve().parent.parent @@ -24,16 +26,63 @@ def test_packaging_only_ships_the_library(): "shipping a top-level `examples` package would collide with other projects" +def _assert_example_checkout_caveat(readme): + """Validate the first shell install command and its source-example caveat.""" + install_at = None + # Inspect shell blocks, not a quoted command in explanatory prose. The first + # pip install is onboarding: a later correct command cannot excuse a typo. + for block in re.finditer(r"```(?:bash|sh)\n(.*?)```", readme, re.DOTALL): + install = re.search(r"(?m)^pip install[^\n]*$", block.group(1)) + if install: + package = (r"agentdescent(?:\[[A-Za-z0-9_,.-]+\])?" + r"(?:(?:===|==|!=|~=|>=|<=|>|<)[A-Za-z0-9.*+_-]+" + r"(?:,(?:===|==|!=|~=|>=|<=|>|<)[A-Za-z0-9.*+_-]+)*)?") + bare = r"agentdescent(?:\[[A-Za-z0-9_,.-]+\])?(?:==[A-Za-z0-9.*+_-]+)?" + command = rf"pip install (?:\"{package}\"|'{package}'|{bare})[ \t]*" + assert re.fullmatch(command, install.group()), \ + "onboarding must install agentdescent; quote shell version constraints" + install_at = block.start(1) + install.start() + break + assert install_at is not None, "the README must show a shell pip install command" + assert "python -m examples" in readme, "premise: the README advertises examples" + nearby = readme[install_at:install_at + 1200].lower() + caveat_at = nearby.find("examples are outside the wheel") + assert caveat_at >= 0, "explain beside the install that examples are source-only" + assert "clone the repo" in nearby[caveat_at:], \ + "the source-example checkout instruction belongs beside the install" + + def test_readme_tells_pip_users_the_examples_need_a_checkout(): - readme = (ROOT / "README.md").read_text() - assert "python -m examples" in readme, "premise: the README does advertise them" - lowered = readme.lower() - assert "clone" in lowered, "the README must say a checkout is required" - # the explanation must sit near the install instructions, not buried at the end - install_at = readme.index("pip install agentdescent") - clone_at = lowered.index("clone the repo") - assert 0 < clone_at - install_at < 1200, \ - "the checkout caveat belongs beside the install instructions" + _assert_example_checkout_caveat((ROOT / "README.md").read_text()) + + +@pytest.mark.parametrize("requirement", [ + "agentdescent", "agentdescent==0.5.1", '\"agentdescent>=0.5.1\"', + "'agentdescent[mcp]>=0.5.1,<0.6'", +]) +def test_checkout_guard_accepts_supported_install_syntax(requirement): + _assert_example_checkout_caveat( + f"```bash\npip install {requirement}\n```\n" + "Research examples are outside the wheel. To run python -m examples.run_demo, " + "clone the repo.") + + +@pytest.mark.parametrize("readme", [ + # No caveat; a clone elsewhere does not explain the source-only examples. + "```bash\npip install agentdescent\n```\nclone the repo; python -m examples.run_demo", + # A valid-looking command for a different package cannot satisfy onboarding. + "```bash\npip install agentdescent-other\n```\n" + "Examples are outside the wheel; clone the repo; python -m examples.run_demo", + # Shell redirection is not a version constraint unless quoted. + "```bash\npip install agentdescent>=0.5.1\n```\n" + "Examples are outside the wheel; clone the repo; python -m examples.run_demo", + # A caveat too far from the install still fails the positioning invariant. + "```bash\npip install agentdescent\n```\n" + "x" * 1200 + + "Examples are outside the wheel; clone the repo; python -m examples.run_demo", +]) +def test_checkout_guard_rejects_missing_or_misleading_onboarding(readme): + with pytest.raises(AssertionError): + _assert_example_checkout_caveat(readme) def test_usage_guide_repeats_the_caveat_before_the_demos(): From acc054e2a0fc208c1f180f259a26bacd6015e391 Mon Sep 17 00:00:00 2001 From: Danyang Chen Date: Fri, 9 Oct 2026 21:31:14 -0700 Subject: [PATCH 4/4] docs: retain port dry-run guidance in the agent-first quickstart --- docs/install.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/install.md b/docs/install.md index 380647ac..3dc74760 100644 --- a/docs/install.md +++ b/docs/install.md @@ -17,7 +17,7 @@ cd agentdescent pip install -e ".[mcp]"
Run the source-only research examples

Research examples are outside the wheel. After 0.5.1 is published, clone its matching tag and install the development extra:

git clone --branch v0.5.1 https://github.com/Birfy/agentdescent
 cd agentdescent
 pip install -e ".[dev]"
-python -m examples.run_demo

The tag is created at publication. Before then, use your release-candidate checkout with pip install -e ".[dev]". See run everything for the remaining examples.

Building these docs locally

From the repository checkout, run pip install -e ".[docs]", then mkdocs serve for a local preview or mkdocs build --strict for the production build.

+python -m examples.run_demo

All 20 algorithm ports print their configuration and return with --dry-run, with no model call or API key. The eight benchmark-faithful ports also return before loading data. The eleven MethodPolicy ports build their policy first; a real-benchmark port may download and cache its split during a dry run. See the port catalogue for the full list.

The tag is created at publication. Before then, use your release-candidate checkout with pip install -e ".[dev]". See run everything for the remaining examples.

Building these docs locally

From the repository checkout, run pip install -e ".[docs]", then mkdocs serve for a local preview or mkdocs build --strict for the production build.

Make the loop your own.

Explore strategies, policies and the Python API whenever you need more control.

Explore evolve() ↗