by default: ruff (lint), pyright or mypy (types), pytest (tests). the security gate (bandit or semgrep) is opt-in, as is cross-model review. each gate runs inside the agent's worktree before the merge queue considers it. failed gates trigger a retry, optionally with an escalated model (sonnet -> opus). after the retry budget is exhausted the task moves to the dead-letter queue. gates are pluggable via the pluggy hookspecs in src/bernstein/plugins/, so you can add a custom gate (terraform plan, openapi diff, license check) without forking the core. configure which gates run under quality.gates in bernstein.yaml.
canonical answer