This release includes breaking changes for platform teams planning a safe upgrade.
✓ No known CVEs patched in this version
Topics
+14 more
Summary
AI summaryUpdates New features None, Internal, and Upgrade notes across a mixed release.
Changes in this release
| Type | Severity | Summary | CVE |
|---|---|---|---|
| Feature | Medium |
Generate SBOM from isolated venv installing only project and resolved dependencies. Generate SBOM from isolated venv installing only project and resolved dependencies. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Feature | Medium |
Soft-fail cross-repo landing-mirror dispatch on PAT scope errors, keeping docs-drift pipeline moving. Soft-fail cross-repo landing-mirror dispatch on PAT scope errors, keeping docs-drift pipeline moving. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Feature | Medium |
Map UrlSchemeError to documented typed errors in MCP transports and lineage-alert sink. Map UrlSchemeError to documented typed errors in MCP transports and lineage-alert sink. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Feature | Medium |
Validate bundle command inputs as a pair and read private key before mutating on-disk state. Validate bundle command inputs as a pair and read private key before mutating on-disk state. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Performance | Medium |
Raise Sonar scan job timeout to 60 minutes with per-step timeouts; pin astral-sh/setup-uv action v8.1.0 with cache enabled. Raise Sonar scan job timeout to 60 minutes with per-step timeouts; pin astral-sh/setup-uv action v8.1.0 with cache enabled. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Bugfix | Medium |
Restored int(), float(), str() coercions and added isinstance guards dropped by FURB refactor. Restored int(), float(), str() coercions and added isinstance guards dropped by FURB refactor. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: high |
— |
| Bugfix | Medium |
Harden CLI against malformed GLITCHTIP_DSN and snapshot sidecars failing schema validation. Harden CLI against malformed GLITCHTIP_DSN and snapshot sidecars failing schema validation. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: high |
— |
| Bugfix | Medium |
Capture HTTP status from cross-repo workflow_dispatch call, emit warning annotation on PAT scope error. Capture HTTP status from cross-repo workflow_dispatch call, emit warning annotation on PAT scope error. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: high |
— |
| Bugfix | Medium |
Treat schema-invalid snapshot sidecars as unreadable metadata, returning None and warning instead of raising errors. Treat schema-invalid snapshot sidecars as unreadable metadata, returning None and warning instead of raising errors. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: high |
— |
| Bugfix | Medium |
Catch OSError around GitHub App private-key reads, raising TrackerUnavailable to preserve typed error surface in GitHub Projects adapter. Catch OSError around GitHub App private-key reads, raising TrackerUnavailable to preserve typed error surface in GitHub Projects adapter. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Bugfix | Medium |
Wrap sentry_sdk.init in try/except to prevent malformed DSN from crashing CLI on import. Wrap sentry_sdk.init in try/except to prevent malformed DSN from crashing CLI on import. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Bugfix | Low |
Reject negative `--days` for `bernstein git gc` before constructing the store and computing the cutoff. Reject negative `--days` for `bernstein git gc` before constructing the store and computing the cutoff. Source: granite4.1:30b@2026-05-20-audit Confidence: low |
— |
| Refactor | Medium |
Mechanical code-quality cleanup of remaining refurb findings across src/ and tests/, applying auto-fix rules FURB123, FURB138, FURB113. Mechanical code-quality cleanup of remaining refurb findings across src/ and tests/, applying auto-fix rules FURB123, FURB138, FURB113. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Other | Medium |
Clarify literal closing-fence string in failure-taxonomy consumer-contract step; prune scope reads; add text language tag to sequence diagram fence; replace classic PAT scopes with fine-grained model in GitHub Projects tracker doc. Clarify literal closing-fence string in failure-taxonomy consumer-contract step; prune scope reads; add text language tag to sequence diagram fence; replace classic PAT scopes with fine-grained model in GitHub Projects tracker doc. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
| Other | Medium |
Annotated sarif_module fixture return type; added assertion message for missing EXPECTED_CHILD_SECRETS; parsed GraphQL request body as JSON in adapter tests. Annotated sarif_module fixture return type; added assertion message for missing EXPECTED_CHILD_SECRETS; parsed GraphQL request body as JSON in adapter tests. Source: granite4.1:8b-q6_K@2026-05-19 Confidence: low |
— |
Full changelog
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:writeon the landing repo. - Harden the CLI against malformed
GLITCHTIP_DSNand snapshot sidecars that fail schema validation. - Map
UrlSchemeErrorto 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 explicitisinstanceguards 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_dispatchcall 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 thetrigger-landing-mirrorjob and blocking the docs-drift pipeline on main. - GLITCHTIP_DSN crash on import (#1618). Wrap
sentry_sdk.initin 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/ValueErrorthroughSnapshotStore.get/list. Reject negative--daysforbernstein git gcbefore constructing the store and before computing the cutoff. - MCP transport typed-error surface (#1618). Wrap
UrlSchemeErrorfromensure_http_urlasTransportErrorinSseTransport.connectandStreamableHttpTransport.connect. CatchUrlSchemeErrorinsink_from_configand fall back toNullAlertSink, preserving the "orchestrator never raises here" contract. - GitHub Projects adapter robustness (#1618). Catch
OSErroraround GitHub App private-key reads and raiseTrackerUnavailableso the typed error surface stays intact. In_item_to_ticket, skip items whosecontent.__typenameis not Issue / PullRequest / DraftIssue rather than emitting tickets with empty title / body / content-ids. Added regression test for the HTTP 403 abuse-detection ->RateLimitedmapping. - 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
textlanguage 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/andtests/. 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 withast.parseround-trip per file), FURB113 (repeated append ->list.extend, 5 leftovers viaruff check --select FURB113 --preview --unsafe-fixes --fix). Counts: FURB123 148 -> 0, FURB138 106 -> 49, FURB113 31 -> 26. Reformatted byruff 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 withcontinue/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 --covon 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 newastral-sh/setup-uvaction to v8.1.0 with cache enabled so subsequent runs reuse the dev environment. - GlitchTip setup doc (#1616). Added
docs/operations/glitchtip-setup.mdcovering 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.mdso they are not lost. - Test typing and assertions (#1618). Annotated the
sarif_modulefixture return type asGenerator[ModuleType, None, None]intests/unit/scripts/test_sarif_drop_suppressed.py. Explicit assertion message whenEXPECTED_CHILD_SECRETSis missing an entry for a child intests/unit/test_post_ci_dispatcher_yaml.py. Parse the GraphQL request body as JSON and assert againstvariablesrather than byte-substring against rawrequest.contentin 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-mirrorjob should verify the fine-grained PAT hasactions:writeon 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 insideSnapshotStore. - Operators using the GitHub App private-key path for the GitHub Projects tracker adapter will now see
TrackerUnavailableon filesystem errors instead of a rawOSError.
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.
Weekly OSS security release digest.
The CVE patches and breaking changes that affected production tools this week. One email, every Sunday.
No spam, unsubscribe anytime.
Share this release
About chernistry/bernstein
Deterministic multi-agent orchestrator for 18 CLI coding agents (Claude Code, Codex, Cursor, Aider, Gemini CLI, OpenAI Agents SDK, and more). MCP server mode (stdio + HTTP/SSE) exposes the orchestrator to any MCP client. Git worktree isolation per agent, HMAC-chained audit trail, cost-aware model routing via contextual bandit. ~11K monthly PyPI downloads, Apache 2.0.
Related context
Related tools
Beta — feedback welcome: [email protected]