Big session: zero-tech-debt sweep (PR #127), v0.28.0 Hardening Sweep release, residual closure (#129: llms-full generator, Supabase search verdict, skill toolchain), the v1.0 beta→stable promotion pass (#130), and now cutting v0.29.0 — Stability Promotions (this handoff). v1.0 still baking ~mid-July; the Python 3.9 drop (#99) is done; 1.0 freeze next.
- Version:
0.29.0insrc/selectools/__init__.pyandpyproject.toml. CHANGELOG## [0.29.0] - 2026-06-15 — Stability Promotionssynced todocs/CHANGELOG.md. Release = push tagv0.29.0(CIpublish-pypijob fires onrefs/tags/v*). - Suite: 7,796 tests collected; full non-e2e run 7,637 passed / 0 failed. 115 examples, 115 source-verified models.
- Quality gate: ruff format + check clean, mypy fully clean (0 errors, 180 files), bandit clean. Architecture stability gate green.
- 0.28.0 themes:
execute_shellshell=False (behavior change), SSRF guard on browser/webhook (consolidated_ssrf.py), sessionbranch()namespace + consistent round-trippablelist()keys across all backends, public-API type tightening (AgentResult/AgentConfigoffAny), embedding timeout/retry, new[cache]extra, doc/count reconciliation. - Docs: README (What's New v0.28 + badges/counts), ARCHITECTURE, COMPATIBILITY, QUICKSTART, EVALS, index, CONTRIBUTING, landing/index.html, og assets, llms.txt, and CHANGELOG all reconciled this release.
- #108 v0.26.0 performance benchmarks published (
docs/modules/BENCHMARKS.md)- post-1.0 backlog reconciled in ROADMAP.
- #109
recalltool — completes the agentic-memory pair (toolbox/memory_tools.py). - #110 Toolbox +4 categories (Discord, S3, browser, image-gen): 48 → 56 tools.
- #111 UnifiedMemory AgentConfig wiring —
MemoryConfig(unified=True, ...); also delivered episodic-retention config (add_turnauto-prunes). - #112 Cache-rate cost for OpenAI + Gemini (
calculate_cost_with_cached_input,cached_prompt_cost); 24 rates re-verified live; gemini-embedding-2 documented as GA/recommended-for-new, default stays -001 (incompatible space). - #113 Cron/scheduled agents (
scheduler.py:AgentScheduler,cron,every). - #114 Reasoning tools (
toolbox/reasoning_tools.py:think/analyze, bounded). - #116 MongoSessionStore; #117 DynamoDBSessionStore (sessions now 6 backends).
- #118
PromptInjectionGuardrail— heuristic injection/jailbreak detection.
All autonomously-buildable Future/Watch items are shipped. The rest need a product call (see ROADMAP "needs a product decision"):
- Firestore session backend — only if there's real demand (adds a dep).
- Model-based guard (beyond the heuristic #118) — hosting decision.
- Multi-channel bot gateway — in-repo vs separate package.
- Learning system — needs a concrete spec.
- Shadow git checkpoints — only if steering toward coding agents.
Sheriff #303 (the prior "next up") is DONE — merged + deployed 2026-06-12, prod logs clean on selectools 0.26.0.
All v1.0 code work remains merged and baking. v0.26.0 is a mid-bake
patch, not a new feature wave: the @beta surface got real-world
mileage, the bake hunt caught a real safety bug, and the fix shipped.
The July 1.0 tag plan is unchanged.
- Drop Python 3.9 — DONE (dedicated PR):
requires-python = ">=3.10", 3.9 removed from the CI matrix,aclosingbackport replaced withcontextlib.aclosing(the only true 3.9-only shim), ruff retargeted (target-version = "py310"). NOTE: thestability.pyProtocol workaround is for a 3.9–3.11 bug, NOT 3.9-only — it STAYS until the floor is ≥3.12. This is the only remaining breaking change and it lands BEFORE the tag. - Promote-after-bake review — sweep the
@betasurface for anything that baked cleanly through the window (v0.24 + v0.25 betas; check issue tracker for API-shape complaints). Promotions are deliberate, not automatic. - Classifier flip at tag —
Development Status :: 5 - Production/Stablein pyproject.toml, version1.0.0, CHANGELOG entry, tag. The release commit for 1.0 should be boring.
- Sheriff adoption: DONE — caching, parser, knowledge, and the pending store/sanitizer deletion all merged + deployed (Sheriff #300-#303).
- UnifiedMemory config wiring: DONE (#111).
- Remaining backlog: prompt registry/versioning, durable execution, code sandbox, Bedrock-native provider (LiteLLM covers it meanwhile), P3 items. Plus the decision-gated Future/Watch items above.
- Venv:
.venvnow hasruffandmkdocsinstalled (this session);pymongois NOT installed (the Mongo backend tests inject a fake viasys.modules, the same pattern as the Redis/Mongo/Dynamo backend tests). Runbanditviapython -m banditif the shim shebang is broken. The editable.pthpoints at the main repo'ssrc; pytest'spythonpath = ["src", "."]makes worktree runs use the worktree's own source. AgentConfig(hooks=...)now raises TypeError (#94). Migration mapping lives indocs/MIGRATION_1.0.md. Don't resurrect it for a "quick fix" — observers cover every hook point.- Stability gate is parametrized per symbol
(
tests/test_architecture.py::test_every_public_symbol_has_stability_marker). Any new public symbol without a marker fails CI by design; mark it, don't exempt it. - Protocol classes + markers: stability markers must not become structural members of runtime-checkable Protocols (py3.10-3.11 regression fixed in #95) — keep markers in the registry for Protocols, not as attributes.
tests/rag/test_property_based_rag.py::test_full_metadata_filter_always_matchesflaked once during release prep (hypothesis draw), passed on re-run and in isolation. If it flakes again, pin and minimize the failing example instead of rerunning.RedisPendingStoreneeds Redis >= 6.2 (GETDEL claim);tighten_ttlis an id-pinned atomic Lua rewrite — covered by real-Redis smoke tests (#93), keep a Redis running locally to exercise them.Tool._serialize_resultre-injectskindfor ToolResult subclasses (#72) — ClassVars never surviveasdict().- Gemini flash-lite + tools is unreliable upstream (docs/COMPATIBILITY.md) — don't re-litigate.