v2.12.0

Added

  • Review agents now see the PR’s title and description, not just the diff (issue #813). Closes a long-standing gap between the two engines: a PR’s stated intent (“this refactor deliberately changes X, not a regression”) is now visible to every finding agent except blind-hunter, which stays diff-only by design.
  • GitLab findings now update in place instead of only being deduplicated (issue #710). A re-detected finding whose content changed gets its existing discussion note PATCHed in place, with a reply on severity escalation, closing the last gap between GitLab’s cross-run dedup and GitHub’s canonical-review reuse. GitLab still has no suppression, since it has no dismiss/false-positive/wont-fix/fixed verdict system.
  • Per-agent output-token budget overrides (issue #191): AI_MAX_TOKENS_<AGENT_NAME> lets you raise or lower one agent’s output cap independently of the global override or roster default, including pr-summarizer/issue-linker, which previously had a hardcoded budget no knob could reach.
  • Pre-flight LLM cost estimate and configurable ceiling (issue #24). A review’s total spend is estimated before any agent dispatches and always logged; set max-cost-usd to abort the run before any billed call when the estimate crosses it.
  • Judge-pass verdict and corroboration state are now persisted to the feedback-learning store (issue #841), making it possible to later check whether a downrank verdict predicts a real false-positive dismissal.

Changed

  • Every finding agent now receives the whole language profile instead of a per-agent routed subset (issue #814): simpler, and enables full prompt-cache reuse across agents in a run.
  • Anthropic/Bedrock prompt caching restructured into up to 3 independent, most-stable-first cache breakpoints (issue #816), recovering cache hits that a single joined system block was losing whenever the least-stable piece changed.
  • Continued internal simplification from Epic 9: unified VCS-provider CRUD/thread-counting logic (#822), a shared scaffold for 5 static analyzers (#823), one shared parser behind every slash-command workflow job (#821), slash-command logic moved out of cli.py (#825), and slash/github_orchestration.py split along its test-layout seam (#849) after being renamed from slash/dismiss.py (#833).

Fixed

  • The feedback-learning addendum and language-profile text were silently dropped on the OpenAI and Google providers (issue #795).
  • Two suppression rules in config/suppressions.json could never fire due to a naming mismatch with findings/suppress.py (issue #796).
  • Five of seven finding-agent prompts instructed the model to emit the literal word NONE on a clean diff, which the findings parser silently discarded entirely (issue #797).
  • claude-opus-5 could return a hard content-filter refusal on some diffs with no fallback; dispatch now retries once on the standard-tier model when this happens (issue #810).
  • code-reviewer’s prompt keyed severity directly to model confidence, letting a confident-but-low-impact finding force REQUEST_CHANGES (issue #798). Severity is now rated on harm alone.
  • Follow-up hardening on the docs-api-check absolute-path fix (issue #713): a pipeline-wide warning catches a recurrence earlier, the same bug class is fixed on the SARIF ingestion path, and eslint/phpcs/phpstan are consolidated onto the same path-stripping helper (issue #846).

Removed

  • The docs-missing-check static analyzer (issue #815): still accepted as a deprecated no-op; formal removal planned for v3.0.0.
  • Four unread ReviewConfig fields and a deprecation-exit gap for AI_CACHE_PRIMING (issue #824).

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