Release 0.6.0 (draft: version pending owner) - #246
Merged
Merged
Conversation
Turn Unreleased into 0.6.0: merge the changelog's sections, put every breaking change under Changed with its migration, and replace the release notes with the 0.6.0 document. Bump the version, the install lines, the tag-pinned links and the API manifest's package version.
…ersion in the deployment test
# Conflicts: # CHANGELOG.md # mix.exs
…/1 connections mint 1.11.0 leaves an HTTP/1 connection open after a receive timeout and Finch 0.23.0 returns it to its pool, so the next request on it waits behind the unanswered one and times out. Declare mint ~> 1.10, lock 1.10.1 and hpax 1.0.4 here and in both examples, ignore the three mint advisories with their reasons until a Finch release includes sneako/finch#397, add a regression test that fails on 1.11.0 and passes on 1.10.1, and say so in the CHANGELOG and release notes.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Draft of the next release. Nothing is tagged, published or merged. The version is 0.6.0 throughout, pending the owner's choice; each mention sits on one line, so changing it is a one-line edit per file (list below).
What changed
CHANGELOG.md:## Unreleasedis## 0.6.0 — 2026-09-28. The sections are Security, Changed, Fixed, GEPA and Documentation, one of each. The section went from 510 lines to 494.RELEASE_NOTES.md: replaced with the v0.6.0 document: description, why minor, install, headline changes, Upgrading from 0.5, and Known limits.mix.exs@version "0.6.0";priv/public_api.jsonpackage_version(regenerated withmix imp.public_api; that is the only line that changed);test/package_contract_test.exsasserts"0.6.0".{:imp, "~> 0.6"}in README,docs/getting-started/setting-up.md,docs/production.md,docs/coming-from-dspy.md, the five livebooks, andexamples/deployment(mix.exs,README.md).tree/v0.5.0andblob/v0.5.0links in README, docs and livebook 05 now point tov0.6.0. They point to the source of the release the docs describe, so they 404 until the tag exists.decisions.mdrows that record the 0.5.0 ruling ({:imp, "~> 0.5"}, "0.5.0is built but not published"). They are history. The second is stale, since 0.5.0 is on Hex; that is left for the owner.Judgement calls in the CHANGELOG
Structure
LMErrorheader stripping.Breaking items that were not marked "Breaking:" before, now marked and given a migration
4. The
toolsfield name is reserved in anImp.reacttask signature, and a saved program with one no longer loads. This was inside the long react Fixed entry. Migration: rename the field and save the program again.5. An
Imp.Clients.ReqLLMclient built or loaded no longer equals a bare struct. This was also in the react entry. Migration: compare bymodel.6. A reply that answers no output is
:missing_fieldsin Chat, JSON and XML, and ProgramOfThought's error changes from:missing_programto that parse error. This was in Fixed. Migration: match the parse error.7.
ReqLLMBatchno longer resends a request that may have run: timeouts, crashes and 5xx are:ambiguous, and a 0.5.0 checkpoint's transient requests become:ambiguous. I split the old entry. The no-resend behaviour and the classification are under Changed, marked breaking; the retry-after wait is under Fixed. Migration: check an:ambiguousrequest with the provider before resending it.8. MCP 503 and 529 become
:refusedinstead of:unknown. This was in Fixed. Migration: match:refusedfor them.9.
Imp.Datasets.csv/3refuses some files 0.5.0 loaded, andnimble_csvis a new dependency. This was in Fixed; the migration was already there.10. GEPA reports
:with_errorswhere it reported:ok, including under the defaultraise_on_exception: true. Separately, under:beam_native,consecutive_outcome/2counts an iteration that raised as:proposal_error, not:none. #238 left both unmarked because the return shape is unchanged. I marked them breaking because code that checksstatusor builds stoppers sees different results. Say if you would rather keep them unmarked in the GEPA section.Merged, split or moved
11. The sentence about the ReqLLMBatch 0.5.0 checkpoint sat inside the
ReqLLM.Errorheaders entry. It moved into the ReqLLMBatch entry.12. There is a new Changed entry, "Imp 0.5.0 cannot read some files this release writes". It gathers three facts: a trajectory with atom keys and a report holding an
Imp.History(each was a sentence in a GEPA entry, removed there), and aReqLLMBatchcheckpoint at schema version 2. The third is new: I checked it in code. 0.5.0'svalidate_checkpoint/1matches only"schema_version" => 1(git show v0.5.0:lib/imp/clients/req_llm_batch.ex), and this branch writes 2.13. The two ProgramOfThought/CodeAct entries (the extraction instruction, and save/load) are now one.
14. The two GEPA candidate-label entries ("names real failures only" and "named 'Proposal failed: …'") are now one.
15. The redaction pair-rule entry now leads with the rule, then the three things it fixes, then the divergence, which keeps its reason. The old entry led with the saved-program symptom.
16.
ExternalCommand: "It used two patterns of its own before the shared rules" became "in place of its ownsk-andBearerpatterns".Reworded to cut words, with no fact dropped: the StepError, safety-guard, adapter parse, CSV,
consecutive_outcome, react step-format and roster-order entries. Please check these against the old text.Dropped
17. "(a dynamic metric-metadata key, say)", an example in the trajectory atom-key sentence.
18. The examples "500, 502, 504" in the batch status list. The text says "any other 5xx", which covers them.
19. "A fallback never asks for two formats" at the end of the JSON fallback entry, because the sentence before it already says this.
Judgement calls in RELEASE_NOTES
["api_key", v]divergence (Redaction: one high-confidence pattern set, whole-string replacement #226, Redact reports, checkpoints, results and saved programs before converting them #240); checkpoints as sensitive resume state (GEPA from GEPA reports proposals that failed when raise_on_exception is false #238; Fast-Slow and Playbook from Redact reports, checkpoints, results and saved programs before converting them #240); step prose that quotes its own field names (Chat, JSON and XML: a reply that answers none of the requested outputs is a parse error #236); ReqLLM's own stream-failure log (0.5.1: ReqLLMBatch never re-dispatches a possibly-run request; Datasets.csv parses with NimbleCSV #229); the Bearer command-output case (Redaction: one high-confidence pattern set, whole-string replacement #226); and the prepared-validation window (Trajectory codec round-trips; GEPA resumes from every checkpoint it can #243). The Bearer wording is from Redaction: one high-confidence pattern set, whole-string replacement #226: a 12–15 character token, or one with no digit, followed by more text or a newline.mix hex.auditlists exactly those two advisories as ignored..audit_ignoreholds both, and cowlib 2.20.0 is still the newest release on Hex (mix hex.info cowlib).Gates (on this branch)
mix format --check-formatted: exit 0mix compile --warnings-as-errors: exit 0mix docs --warnings-as-errors: exit 0mix test test/documentation_contract_test.exs: 21 tests, 0 failures (1 excluded)mix test test/public_api_manifest_test.exs: 25 tests, 0 failures. It failed first, onpackage_version, until the manifest was regenerated.mix test test/package_contract_test.exs: 14 tests, 0 failuresmix package.check: "clean-room package proof passed: tmp/package-clean-room"The full suite was not run. This change touches documentation, the version and the manifest only.
Fact-check corrections (61bc81d)
The fact-check found overstatements and omissions. Each is fixed in both files where it applies.
Corrections
mix deps.update mint hpax.ExternalCommandentry.["api_key", v]case. Any flat two-element name-first list that is not itself an element of a list stays unredacted: at the top level, in a tuple, or under a non-credential key. I checked this:Imp.Redaction.redact(["password","hunter2"])andredact({:x, ["password","hunter2"]})come back unchanged.{:error, %Imp.Predict.ReActV2.StepError{reason: %Imp.OperationalSafetyError{}}}; Evaluate and the optimizers already raise it.:cancellationis added to the guard kinds (@kindsinImp.OperationalSafetyError).toolsmigration: the saved file does not load, so "save it again" could not be followed. The text now says to rebuild with the field renamed; to keep optimized instructions and demos, rename the field in the saved file or optimize again.ReqLLMBatchshareImp.Errors.status_outcome/1.next_thoughtis Imp's; DSPy's Chat adapter leaves that field empty.pypi-AgE; Upgrading 12 says "saved withImp.dump/1".Omissions added
provider_stream: true, astream/3that raises is recorded and returns{:error, {:lm_failed, lm, error}}.%{text:, tool_calls:}.ReqLLMBatchcheckpoints gainretry_stoppedandschema_migrationevents andnot_before.nilbeside native tool calls. This is in the CHANGELOG adapter entry and in Known limits.%Imp.Predict.ReActV2{}gains:tool_order. This is next to the ReqLLM:tool_callingequality entry and in Upgrading step 7.After #247 and #248 merged
lib/imp/signature/field.ex: a field written asnil,trueorfalsekeeps its name as text and round-trips. The atoms raiseArgumentError.sk-key right after a hyphen) fixes a regression that was never released, so it gets no CHANGELOG line and no Known limit. No entry said such a key is shown; theExternalCommandentry names only the Bearer exception.mix format --check-formatted: exit 0mix docs --warnings-as-errors: exit 0mint held at 1.10.1 (feba21a)
This supersedes the earlier mint lines in this body: the release no longer takes, requires or claims mint 1.11.
What was found. mint 1.11.0 no longer closes an HTTP/1 connection on a receive timeout (the
{:error, %Mint.TransportError{reason: :timeout}}clause inMint.HTTP1.recv/3), and Finch 0.23.0, the newest release, returns any open connection to its pool (transfer_if_openinlib/finch/http1/pool.ex). The next request on that connection is written behind the unanswered one and times out, and so does a retry that lands there. If the server answers late while a request is waiting, Finch raisesCaseClauseError(reproduced here with plainReq.post:no case clause matching: {:status, #Reference<...>, 200}). On mint 1.10.1 the retry opens a new connection. Finch has an open, unmerged, unreleased fix: sneako/finch#397 ("Close abandoned HTTP/1 connections after request errors").With ReqLLM's default pool (8 shards of one connection, chosen at random per request) a timeout spoils only the requests that draw the stuck shard; with Req's default pool it spoils every later request to that host.
What changed
mix.exs:{:mint, "~> 1.10"}. The comment says Imp matches Mint's error structs, and why the floor is not 1.11 (the test,.audit_ignore, finch#397).mix.lock,examples/deployment/mix.lock,examples/workspace_agent/mix.lock: mint 1.10.1, hpax 1.0.4.mix deps.getin each (the deployment one withIMP_PATH=../.., as CI runs it) leaves the locks unchanged..audit_ignore: EEF-CVE-2026-91043, -92103, -94194, in the cowlib entries' format, with the shared reason, what makes each reachable or not (91043 and 92103 are HTTP/2 only; 94194 is HTTP/1 and reachable with a malicious server behind a strict intermediary), the retire condition (a Finch release with finch#397, or mint closing on timeout again; then move Finch and mint 1.11 together), and the date.test/timed_out_connection_test.exs: a realImp.req_llmclient againstImp.Test.LocalHTTP(Bandit). The server holds the first request past the client's 200 ms timeout and answers the rest;Imp.LM.generatewithmax_retries: 0must return{:error, %Imp.LMError{retryable: true}}, then{:ok, _}on a different server connection. The Finchpool_strategy: &hd/1option pins every request to one shard, because ReqLLM's random shard choice would otherwise make the second call miss the stuck connection 7 times in 8. The comment says this test is why the lock holds 1.10.1 and names finch#397.~> 1.10and replaces "only mint moves an existing lock": the other requirements move no lock, and the mint one moves only a lock below 1.10.mix deps.getresolves mint 1.11.0; a new Known limit states the behaviour, who is affected, the advisories' scope, and the application's choice: add{:mint, "~> 1.10.1"}to lock 1.10.1, or take 1.11.0 and accept that a connection that timed out is reused until the server closes it.A consequence of the
~> 1.10floor, checked in a disposable project: an application locked at mint 1.9.3 that adds a~> 1.10requirement moves to 1.11.0 onmix deps.get(Hex takes the newest release), and one that also declares{:mint, "~> 1.10.1"}resolves 1.10.1. The docs say so. A floor of~> 1.8(Finch's) would leave such an application where it is.Falsification of the new test (the lock swapped with
git show HEAD~1:mix.lockplusmix deps.get)1 test, 1 failureat the secondImp.LM.generate(line 75), reason%Req.TransportError{reason: :timeout}.1 test, 0 failures.Gates on feba21a
mix format --check-formatted: exit 0mix compile --warnings-as-errors --force: exit 0 (427 files)mix dialyzer: exit 0, "done (passed successfully)" (Total errors: 143, Skipped: 143, as before)MIX_ENV=test mix quality.check: exit 0. credo "found no issues"; imp.deps.check "Every application Imp names is declared in mix.exs."; deps.audit "No vulnerabilities found."; hex.audit lists the two cowlib and three mint advisories as ignored.mix package.check: exit 0, "clean-room package proof passed: tmp/package-clean-room"mix docs --warnings-as-errors: exit 0tmp/that this worktree does not have (tmp/dspy-parity-venv,tmp/dspy-3.2.1,tmp/gepa-v0.1.4,tmp/gepa-artifact); each fails on:enoentfor that path or on the "pinned DSPy/GEPA sources are required" flunk. CI's differential job sets them up. None involves HTTP.