# Aggregate release gates and CI-pinned toolchains

Use this reference when a release contract requires both individual checks and an aggregate target such as `make verify`.

## 1. Reproduce CI, not an arbitrary local toolchain

- Read the workflow and CI requirements before interpreting lint or test differences.
- Run the exact pinned tool version used by CI. A shared virtualenv may contain a newer linter that enables additional rules and produces large false “branch regression” lists against an otherwise green baseline.
- When the pinned executable is not installed locally, use an isolated version runner (for example `uvx --from ruff==<pinned> ruff ...`) rather than changing project dependencies solely for verification.
- Apply the workflow's exact path list and flags. Distinguish “changed-line lint is clean” from “the actual CI lint command is clean”; they prove different things.

## 2. Inspect the aggregate target before running it

- Determine whether the Makefile invokes configurable variables or hard-coded executable names such as `pytest`.
- If a target hard-codes a command, setting an unrelated variable such as `PYTHON=...` does not redirect it. Use the project-supported environment or prepend the intended environment's `bin` directory to `PATH` when permitted.
- Check whether the aggregate target repeats already-heavy backend/frontend suites. Run it alone, not beside lint, builds, scanners, or another full suite.
- Reserve enough timeout and release runway for the repeated work before entering commit/push/deploy phases.

## 3. Preserve truthful gate status

- Individual green components do not make an explicitly required aggregate command green. Record both facts separately.
- If the aggregate command fails, diagnose the failing subtarget from its output. Repair only the concrete cause, then rerun according to the release contract.
- If the execution layer returns an explicit blocked/no-consent verdict, do not retry, rephrase, wrap, or route around the same outcome. Preserve the already-green component evidence, mark the aggregate gate **not completed**, and pause before commit, push, service changes, migration, or deployment.
- Do not reinterpret an execution-policy block as a product failure, and do not claim the branch is release-ready until the required aggregate gate is actually completed or the user explicitly changes the contract.

## 4. Evidence checklist

Record:

- exact aggregate command and candidate tree;
- exact CI-pinned tool versions and path lists;
- component suite counts and skip/xfail status;
- aggregate exit status or explicit execution-layer block;
- whether code changed after the last full suites;
- the exact release side effects intentionally withheld.

This keeps a non-destructive verification blocker from being confused with an implementation regression while still preserving the user's release gate.