Skip to content

v0.1.0b2 — 2026-04-25 (DRAFT)

Polish + supply-chain + observability cut. Five orthogonal improvements bundled together because none of them break the adapter protocol and all of them shipped during a single overnight sprint.

Status: draft. Cut is gated on (a) the six contributing PRs landing on main and (b) GitHub Actions billing being restored on the escotilha account.

Headline

Model fallback chain on rate-limit exhaustion. When claude -p exhausts its rate-limit retry loop on Opus, oxi now records the exhaustion in the ledger and walks the per-tier fallback chain on the next dispatch (Opus → Sonnet → Haiku for max plans; Sonnet → Haiku for standard). A 6-hour window prevents stale rate-limit state from holding a task on Haiku forever.

What else changed

  • Structured logging via structlog. Existing logging.getLogger(__name__).info(...) call sites in 20+ modules now render as JSON to stderr by default. OXI_LOG_FORMAT=console switches to human-readable; OXI_LOG_LEVEL sets the threshold. Routines and CI get JSON; interactive operators get colors. (#93)

  • MkDocs Material site + GitHub Pages workflow. mkdocs.yml configures the full nav (manual, reference, runbooks, release notes). .github/workflows/docs.yml builds with --strict on every PR and deploys to GH Pages on push to main. Strict mode caught three pre-existing broken anchor links in the manual. (#94)

  • mypy strict allow-list with CI ratchet. [tool.mypy] config enforces strict mode on oxi_core.adapter, oxi_core.db, and oxi_core.v3.notification. CI runs the strict check on every PR. Adding modules to the list is a one-way ratchet: regressions fail CI. (#95)

  • SBOM auto-attach to GitHub Release. scripts/release.sh now uploads the generated *.cdx.json SBOM to the matching v<version> GH Release via gh release upload --clobber after a successful PyPI upload. Skips cleanly on TestPyPI, missing gh, or missing release tag — always with operator-readable fallback guidance. (#96)

What "beta" means (unchanged)

  • No breaking changes within 0.1.0b*. Adapters that work on 0.1.0b1 work on 0.1.0b2.
  • Adapter protocol is frozen until 0.2.0a*.
  • Auto-merge defaults stay off. Operators opt in per DispatchPolicy().auto_merge.

Install

pip install --pre --upgrade oxi-core    # picks up 0.1.0b2 once cut
# or pin:
pip install oxi-core==0.1.0b2

--pre remains required.

What's next

  • 0.1.0b3+: continue ratcheting v3/ modules into the mypy strict list (39 errors → 0 over time)
  • 0.1.0b3+: T3-3 API doc auto-ingestion + adapter generation
  • 0.1.0b3+: coverage gate on new code in CI (T2-13)
  • 0.2.0 (eventually): adapter protocol changes, if any are warranted

Audit trail

PRs merged into this cut: #92 (model fallback), #93 (structlog), #94 (mkdocs), #95 (mypy strict), #96 (sbom auto-attach).

A note on the GitHub Actions situation during this sprint: all five PRs merged on local verification only — the runner-level "recent account payments have failed" annotation blocked the actual CI runs. Each PR description documents the local pytest/ruff/mypy/leak-lint results that stood in for green CI. Once billing is restored, a re-run on main post-merge will surface any environment-specific regressions; none are expected.