v2.13.0

Added

  • Bitbucket reaches feature parity with GitHub/GitLab for finding lifecycle management (issues #839, #873, #874): cross-run dedup so an unchanged finding isn’t reposted every run, inline diff-anchored findings via Bitbucket Code Insights annotations (on by default; opt out with AI_BITBUCKET_CODE_INSIGHTS), and verdict-command polling so /ai-pr-review dismiss|false-positive|wont-fix|fixed commands (posted as a fresh top-level comment, since Bitbucket Pipelines has no comment-triggered event) are picked up and applied at the start of the next review run (opt-in via AI_BITBUCKET_VERDICTS). See Bitbucket setup.
  • Further Bitbucket parity, found while live-verifying the work above (issues #917, #918, #920): every active finding now renders as a bullet in the review comment even when it also got a Code Insights annotation (#920, previously invisible outside the Diff/Reports view); the starter bitbucket-pipelines.yml now sets AI_FAIL_ON_FINDINGS=true by default, matching the GitHub Action example (#917); and the review’s decided outcome now has a real effect on the PR’s own reviewer-state UI via Bitbucket’s approve/request-changes endpoints, default on via AI_BITBUCKET_REVIEW_STATE (#918), capped by approval-ceiling the same way GitHub/GitLab approvals are. Behavior change: since this defaults on, upgrading gets you real approve/request-changes state on Bitbucket immediately with no opt-in step. Review your branch restrictions if they count bot approvals toward a merge requirement, or set AI_BITBUCKET_REVIEW_STATE=false to keep the prior heading-text-only behavior.
  • approval-ceiling input / AI_APPROVAL_CEILING env var (issue #858): caps the strongest review event this bot may post, so a human can be required to make every merge decision instead of the bot. See Configuration: Approval ceiling.

Changed

  • Anthropic premium default: claude-opus-5 → claude-opus-5-5. This repo’s model-change verification process requires a live canary run before a default-model PR merges; whether that gate was actually satisfied for this bump is unconfirmed (see CHANGELOG.md for detail). Set AI_MODEL_PREMIUM=claude-opus-5 to restore the previous default.
  • Pre-flight cost estimate accuracy (issue #848): the estimate now uses the exact same gating and per-agent output-token cap as the real dispatch (previously a hardcoded, drifted 4096), and charges CJK/Hangul/kana/fullwidth text at roughly 1 token per codepoint instead of the same ratio used for English-like text. Both can move a run across AI_MAX_COST_USD differently than before. The estimate’s docstring also now discloses its two remaining known omissions (prompt caching, the judge pass) instead of leaving them implicit.
  • A cost-ceiling skip now posts the analyzer/SARIF findings it already computed instead of discarding them (issue #896), with AI_FAIL_ON_FINDINGS applying to those surviving findings the same way it does on a normal run.

Fixed

  • Five security findings surfaced by the Bitbucket-parity work’s own review passes: a verdicts marker forgeable via unsanitized pr-summarizer/issue-linker output, fixed in two passes (issue #886, pre-existing on every provider); the same forgery class reaching the id-map/acks/judge-map markers and the unsanitized Finding.source field, redirecting a maintainer’s dismiss command (issue #913); prompt-injected bullet-rendering syntax that could forge a fake finding for the same reason (issue #914); a fingerprint() delimiter collision from an unescaped | join that could let two distinct findings collide (issue #887); and Bitbucket’s summary-comment listing trusting any comment matching the marker text regardless of author, now fixed at the root and fail-closed (issue #894).
  • claude-opus-5-5 was silently billed at Opus 5 rates due to an unanchored pricing-pattern match (25% cost overstatement); two other pricing rows were also stale against Anthropic’s current published rates.
  • policy.yml’s exclude-agents/exclude-analyzers were silently ignored: only the env-var denylists were ever applied.
  • Slash-command input forwarding gaps (issues #863, #865): nineteen container-action inputs (max-diff-lines, max-inline, ignore-merge-commits, context-enrichment, and fifteen more found in a follow-up audit) had no effect on /ai-pr-review rescan/review-full, silently falling back to hardcoded defaults regardless of a consuming repo’s AI_REVIEW_* variables. A structural parity test now guards against this class of regression recurring.
  • A ::warning:: annotation leaked into the posted /ai-pr-review dismiss/wont-fix/false-positive reply text, caused by a stray stdout print in the feedback store’s duplicate-entry detection.
  • Corrected a false CHANGELOG claim from v2.12.0 (issue #847’s follow-up work was claimed done but never actually implemented; #847 remains open. #848’s follow-up work did land, in this release, above).

See CHANGELOG.md for full technical detail on every change above.