Skip to content

Commit 65da3d8

Browse files
committed
Drop CodeQL from check.sh (enforced by codeql.yml)
CodeQL is the slowest gate (~minutes) and depends on nothing else in the local pipeline. It was already enforced independently by the codeql.yml workflow, and ci.yml's check job never ran it anyway (no codeql on the hosted runner's PATH, so the step self-skipped there). Removing it from check.sh therefore loses no CI coverage and roughly halves the local gate wall-clock (~165s -> ~83s on a 4-core box). scripts/codeql_gate.py is kept so a code-scanning alert can still be reproduced locally on demand. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TSGokAz8uYHj5PnWfYh8LP
1 parent 3ae8404 commit 65da3d8

2 files changed

Lines changed: 7 additions & 14 deletions

File tree

AGENTS.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ uv run assembly --help # run the CLI from the locked environment
2525

2626
Dev tooling is a PEP 735 `[dependency-groups]` group with `default-groups = ["dev"]`, not a `[project]` extra — `uv sync --extra dev` errors.
2727

28-
`scripts/check.sh` is the authoritative gate; keep this list in sync with it. It runs, in order: `uv lock --check` → `ruff check` → `ruff format --check` → `mypy` → `pyright` (src strict) → `pyright` (tests) → `vulture` (dead code) → `deptry` (dependency hygiene) → `lint-imports` (import-linter architecture contracts) → max-file-length (500 lines) → `xenon` (cyclomatic complexity: function max B, module avg A, project avg A) → `swiftlint` + swift compile (macOS only, skipped elsewhere) → `markdownlint` → `codespell` (spell-check code/comments/docs via `uvx`; config in `[tool.codespell]`) → `prettier` (init template JS/CSS) → `shellcheck` → `actionlint` + `zizmor` (workflow lint/audit) → `gitleaks` (secret scan) → generated `--show-code` compile gate → init template contract gate → unused snapshot/fixture gate (`scripts/unused_fixtures_gate.py`: orphaned `.ambr`/API fixtures, since xdist disables syrupy's own unused detection) → docs consistency gate (`scripts/docs_consistency_gate.py`: REFERENCE.md/README.md env vars, exit codes, and `assembly …` command refs stay in sync with the code) → docstring coverage gate (`scripts/docstring_coverage_gate.py`: public-API docstring ratchet, an `interrogate` stand-in that handles PEP 695 generics) → `brew audit --strict` (the shipped `Formula/assembly.rb`; self-skips without Homebrew) → `pytest` (90% branch coverage) → `diff-cover` (100% patch coverage vs `origin/main`) → **mutation gate** (diff-scoped: mutates each changed line and reruns the tests that cover it — a surviving mutant fails the gate, so changed lines need assertions that would *fail* if the line broke, not just coverage; suppress a genuinely unassertable line with `# pragma: no mutate`) → a "no new escape hatches" gate (`# type: ignore` / `# noqa` / `pragma: no cover` / `Any` / `cast(` / test skip/xfail/sleep, all **count-gated against the merge-base** so moving an existing hatch in a refactor doesn't false-positive but a net-new one fails) → **CodeQL gate** (`scripts/codeql_gate.py`: the same security + quality suites the CodeQL workflow uploads to GitHub's code-scanning/quality tabs, run locally over python/actions/javascript so alerts fail before push instead of on the PR; needs the CodeQL bundle on PATH — self-skips otherwise, `codeql.yml` covers CI, and the web session-start hook provisions it) → `uv build` + `twine check --strict`. The `vulture`/`deptry`/`lint-imports`/`xenon`, patch-coverage, and mutation stages catch the failures that `ruff`+`mypy` alone won't — don't claim the gate is green until the script prints `All checks passed.`
28+
`scripts/check.sh` is the authoritative gate; keep this list in sync with it. It runs, in order: `uv lock --check` → `ruff check` → `ruff format --check` → `mypy` → `pyright` (src strict) → `pyright` (tests) → `vulture` (dead code) → `deptry` (dependency hygiene) → `lint-imports` (import-linter architecture contracts) → max-file-length (500 lines) → `xenon` (cyclomatic complexity: function max B, module avg A, project avg A) → `swiftlint` + swift compile (macOS only, skipped elsewhere) → `markdownlint` → `codespell` (spell-check code/comments/docs via `uvx`; config in `[tool.codespell]`) → `prettier` (init template JS/CSS) → `shellcheck` → `actionlint` + `zizmor` (workflow lint/audit) → `gitleaks` (secret scan) → generated `--show-code` compile gate → init template contract gate → unused snapshot/fixture gate (`scripts/unused_fixtures_gate.py`: orphaned `.ambr`/API fixtures, since xdist disables syrupy's own unused detection) → docs consistency gate (`scripts/docs_consistency_gate.py`: REFERENCE.md/README.md env vars, exit codes, and `assembly …` command refs stay in sync with the code) → docstring coverage gate (`scripts/docstring_coverage_gate.py`: public-API docstring ratchet, an `interrogate` stand-in that handles PEP 695 generics) → `brew audit --strict` (the shipped `Formula/assembly.rb`; self-skips without Homebrew) → `pytest` (90% branch coverage) → `diff-cover` (100% patch coverage vs `origin/main`) → **mutation gate** (diff-scoped: mutates each changed line and reruns the tests that cover it — a surviving mutant fails the gate, so changed lines need assertions that would *fail* if the line broke, not just coverage; suppress a genuinely unassertable line with `# pragma: no mutate`) → a "no new escape hatches" gate (`# type: ignore` / `# noqa` / `pragma: no cover` / `Any` / `cast(` / test skip/xfail/sleep, all **count-gated against the merge-base** so moving an existing hatch in a refactor doesn't false-positive but a net-new one fails) → `uv build` + `twine check --strict`. The `vulture`/`deptry`/`lint-imports`/`xenon`, patch-coverage, and mutation stages catch the failures that `ruff`+`mypy` alone won't — don't claim the gate is green until the script prints `All checks passed.` **CodeQL is intentionally NOT in this gate** — it's the slowest check (~minutes) and is enforced separately by the `codeql.yml` workflow (which also covers CI; `check.sh` self-skipped it on the hosted runner anyway), so dropping it keeps the local gate fast with no loss of CI coverage. `scripts/codeql_gate.py` still exists to reproduce a code-scanning alert locally (`uv run python scripts/codeql_gate.py`).
2929

3030
**Commits are gated.** On success `check.sh` records a working-tree signature (`scripts/gate_marker.py record``.git/aai-gate-pass`), and a PreToolUse hook (`.claude/hooks/require-gate-before-commit.sh`) blocks `git commit` unless that signature still matches — so run the full gate to completion *before* committing (a single-file `pytest` does not satisfy it), and re-run it after any further edit. Iterate with the fast targeted commands above, gate once at the end. For a deliberate work-in-progress commit, prefix `AAI_ALLOW_COMMIT=1 git commit …`.
3131

scripts/check.sh

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -329,19 +329,12 @@ else
329329
echo " origin/main not found; skipping escape-hatch diff gate (CI provides it)"
330330
fi
331331

332-
echo "==> codeql (security + quality suites, mirrors codeql.yml minus swift)"
333-
# Runs the same query suites the CodeQL workflow uploads to GitHub's code-scanning
334-
# and quality tabs, so an alert fails here instead of surfacing on the PR after
335-
# push. The CLI ships as a ~1 GB bundle with no PyPI/npm distribution, so this
336-
# self-skips when absent — codeql.yml is the CI enforcement (the hosted runner's
337-
# PATH has no codeql, so ci.yml's check job skips this too and the PR isn't
338-
# double-scanned), and the web session-start hook provisions the bundle. Last of
339-
# the analysis gates because it's the slowest (~minutes, not diff-scoped).
340-
if command -v codeql >/dev/null 2>&1; then
341-
uv run python scripts/codeql_gate.py
342-
else
343-
echo " codeql not found; skipping (codeql.yml runs it in CI; install: https://github.com/github/codeql-action/releases)"
344-
fi
332+
# CodeQL is NOT run here. It's the single slowest gate (~minutes) and is enforced in CI
333+
# by codeql.yml, which runs the same security + quality suites on its own schedule and
334+
# uploads them to GitHub's code-scanning/quality tabs. ci.yml's check job never ran it
335+
# either (the hosted runner has no codeql on PATH, so this step self-skipped there), so
336+
# dropping it from the local gate loses no CI coverage — it just keeps `check.sh` fast.
337+
# To reproduce a code-scanning alert locally: `uv run python scripts/codeql_gate.py`.
345338

346339
echo "==> build + twine check (PyPI publish readiness)"
347340
# Build sdist + wheel into ./dist, then validate the metadata and README render

0 commit comments

Comments
 (0)