Skip to content

v2.3.1 - Maintenance

4 commits since v2.3.0. No new features, no breaking changes. Patch release covering correctness fixes, CI hardening, and follow-up on review-bot findings deferred during the v2.3.0 cycle.

Highlights

  • Restore numeric and key coercions that the FURB123 auto-fix pass removed, plus 19 mechanical fixes from the 2026-05-19 review-bot catch-up.
  • Soft-fail the cross-repo landing-mirror dispatch on PAT scope errors so the docs-drift pipeline keeps moving when the fine-grained PAT lacks actions:write on the landing repo.
  • Harden the CLI against malformed GLITCHTIP_DSN and snapshot sidecars that fail schema validation.
  • Map UrlSchemeError to the documented typed errors in MCP transports and the lineage-alert sink.

New features

None.

Fixes

  • Refurb correctness fixup (#1615). Restored int() / float() / str() coercions and added explicit isinstance guards that the FURB refactor pass dropped. Eight bot-ack findings on the same PR addressed.
  • Landing-dispatch PAT scope (#1617). Capture the HTTP status from the cross-repo workflow_dispatch call and emit an operator-actionable warning annotation when the dispatch endpoint rejects the request. The job now exits 0 in all non-success cases instead of failing the trigger-landing-mirror job and blocking the docs-drift pipeline on main.
  • GLITCHTIP_DSN crash on import (#1618). Wrap sentry_sdk.init in a best-effort try/except so a malformed DSN cannot crash the CLI on import.
  • Snapshot-sidecar schema errors (#1618). Treat schema-invalid snapshot sidecars as unreadable metadata (return None and warn) instead of raising KeyError / TypeError / ValueError through SnapshotStore.get / list. Reject negative --days for bernstein git gc before constructing the store and before computing the cutoff.
  • MCP transport typed-error surface (#1618). Wrap UrlSchemeError from ensure_http_url as TransportError in SseTransport.connect and StreamableHttpTransport.connect. Catch UrlSchemeError in sink_from_config and fall back to NullAlertSink, preserving the "orchestrator never raises here" contract.
  • GitHub Projects adapter robustness (#1618). Catch OSError around GitHub App private-key reads and raise TrackerUnavailable so the typed error surface stays intact. In _item_to_ticket, skip items whose content.__typename is not Issue / PullRequest / DraftIssue rather than emitting tickets with empty title / body / content-ids. Added regression test for the HTTP 403 abuse-detection -> RateLimited mapping.
  • Bundle command input validation (#1618). Validate sign inputs as a pair and read the private key before assembling the bundle, so invalid CLI input never mutates on-disk state.
  • Docs cleanups (#1618). Clarify the literal closing-fence string in the failure-taxonomy consumer-contract step. Prune scope reads as two distinct scopes in session-memory docs (episodic = session, semantic = task). Add text language tag to the post-CI-dispatcher sequence-diagram fence so markdownlint MD040 passes. Replace classic PAT scope strings with the fine-grained PAT permission model in the github-projects tracker doc.

Internal

  • Refurb auto-fix wave 3 (#1615). Mechanical code-quality cleanup of remaining refurb findings across src/ and tests/. Rules auto-fixed: FURB123 (redundant cast removal, 147 sites via custom line-based rewriter), FURB138 (assign-empty-list + append loop -> list comprehension, 57 sites via libcst rewriter restricted to single-statement bodies with ast.parse round-trip per file), FURB113 (repeated append -> list.extend, 5 leftovers via ruff check --select FURB113 --preview --unsafe-fixes --fix). Counts: FURB123 148 -> 0, FURB138 106 -> 49, FURB113 31 -> 26. Reformatted by ruff format (3 files). Wave 3 of the bulk auto-fix work started in #1558 and continued in #1582. Skipped this round: FURB184 (2440 sites, still needs whole-function liveness analysis), FURB138 leftovers (49 sites with multi-statement bodies, guarded branches, or appends with continue / break), FURB108 (24 sites), FURB173 (2 sites).
  • Sonar-scan timeout and uv caching (#1616). Sonar scans were dying at the 20-minute job timeout during uv sync --group dev + pytest --cov on a 127-commit history. Raise the job-level budget to 60 minutes with per-step timeouts that fail fast on individual stages (sync 15m, coverage 30m, scan 10m). Pin the new astral-sh/setup-uv action to v8.1.0 with cache enabled so subsequent runs reuse the dev environment.
  • GlitchTip setup doc (#1616). Added docs/operations/glitchtip-setup.md covering DSN provisioning, env-var export, and end-to-end event verification on a single page.
  • SBOM scope (#1618). Generate the SBOM from an isolated venv where only the project and its resolved dependencies are installed, so the output reflects bernstein's dependency graph rather than the runner base image.
  • Review-bot triage continuity (#1618). PR #1584 inventoried 48 review-bot findings and landed 4 mechanical fixes. This release picks up the remaining 44: 19 applied here, 14 already resolved on source PR branches before merge (CodeRabbit confirmed "Addressed in commits ..."), and 11 deferred for design judgement (config-schema changes, frozen-dataclass migrations, semantic-prune scope, stack indexing rework, worktree-aware git-dir resolution). Deferred items are tracked in docs/review-bot/deferred-2026-05-19.md so they are not lost.
  • Test typing and assertions (#1618). Annotated the sarif_module fixture return type as Generator[ModuleType, None, None] in tests/unit/scripts/test_sarif_drop_suppressed.py. Explicit assertion message when EXPECTED_CHILD_SECRETS is missing an entry for a child in tests/unit/test_post_ci_dispatcher_yaml.py. Parse the GraphQL request body as JSON and assert against variables rather than byte-substring against raw request.content in the github-projects adapter tests.

Deprecations

None.

Upgrade notes

  • Drop-in upgrade from v2.3.0. No config-schema changes, no API changes, no audit-chain changes.
  • Operators relying on the cross-repo trigger-landing-mirror job should verify the fine-grained PAT has actions:write on the landing repo. If the scope is missing, the job will now emit a warning annotation instead of failing the workflow.
  • Operators using bernstein git gc --days <N> should note that negative <N> is now rejected up front rather than mishandled inside SnapshotStore.
  • Operators using the GitHub App private-key path for the GitHub Projects tracker adapter will now see TrackerUnavailable on filesystem errors instead of a raw OSError.

Acknowledgements

Thanks to the operators and reviewers who triaged the 2026-05-19 review-bot batch and to the CodeRabbit / Sourcery automation surface that surfaced the underlying findings.