Skip to content

Give dependency alerts a path to a pull request, and document the gate layering - #253

Merged
hellices merged 2 commits into
mainfrom
chore/dependency-hygiene
Aug 11, 2026
Merged

Give dependency alerts a path to a pull request, and document the gate layering#253
hellices merged 2 commits into
mainfrom
chore/dependency-hygiene

Conversation

@hellices

Copy link
Copy Markdown
Owner

Nine GitPython advisories (six high) were open against uv.lock, all cleared by a single bump to 3.1.58. They accumulated for a structural reason: there was no dependabot.yml, so an alert had no route to a change.

Why CI was green, correctly

GitPython reaches the tree only as tach's transitive dependency in the dev group. The security job audits uv export --no-dev — the resolution users actually install — so a dev-only flaw does not fail it. That is the right gate: turning CI red for a vulnerability no user can reach, sometimes with no fixed version upstream, trains people to ignore it.

Dependabot is the mechanism for the other half, and it was simply absent. Added for uv and github-actions, grouped so a routine dev-tool bump does not arrive with the same weight as a runtime one.

The GitPython bump itself is left to Dependabot rather than done here: this machine cannot reach files.pythonhosted.org (corporate TLS interception — TCP connects, the handshake is reset), so the lock cannot be regenerated locally. That is itself a good argument for the automation living on GitHub.

Gate layering, documented

docs/dev/quality-gates.md records what runs where and why, verified against the workflows rather than assumed:

layer checks
pre-commit ruff, format, typos, pyproject, mypy, no-bare-type-ignore
make check ruff → mypy → pytest → tach
CI 3×Python matrix + Windows, deptry, tach, coverage ≥80%, pip-audit, zizmor, CodeQL, dependency-review
release verify re-runs the full gate, then build → smoke → sbom → offline → attest → stage → publish → finalize

The one non-obvious placement is verify: it repeats layer 3 instead of trusting it, because a tag can point at any commit — including one CI never ran.

Copilot AI balanced review requested due to automatic review settings August 11, 2026 13:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds automated dependency updates and documents quality-gate responsibilities.

Changes:

  • Configures weekly uv and GitHub Actions updates.
  • Documents local, CI, and release checks.
  • Links the new quality-gates guide.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
.github/dependabot.yml Adds grouped dependency updates.
docs/dev/quality-gates.md Documents validation layers.
docs/dev/README.md Links the new guide.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread .github/dependabot.yml
Comment thread .github/dependabot.yml Outdated
Comment thread docs/dev/quality-gates.md Outdated
Comment thread docs/dev/quality-gates.md Outdated

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 4 changed files in this pull request and generated no new comments.

Suppressed comments (3)

docs/dev/quality-gates.md:70

  • “Dev-dependency vulnerabilities are not gated” is too broad. The security job deliberately omits the dev resolution, but dependency-review has no scope exclusion and therefore rejects a pull request that introduces a high-severity development dependency too. Qualify this as existing dev advisories not being continuously gated, while retaining the new-dependency protection documented above.
- **Dev-dependency vulnerabilities** are not gated. Dev packages do not

docs/dev/quality-gates.md:46

  • This linear sequence does not match the release DAG: smoke, sbom, and offline fan out after build; collect waits for the SBOM/offline branches, and attest joins collect with smoke. Since this document explains gate placement, representing these as serial stages gives an incorrect picture of which failures block which work.
`verify` → `build` → `smoke` → `sbom` → `offline` → `collect` → `attest` →
`stage-github-release` → `publish-pypi` → `finalize-github-release`.

docs/dev/quality-gates.md:24

  • This heading says the table describes .github/workflows/ci.yml, but the CodeQL row below is implemented in the separate .github/workflows/codeql.yml workflow. It also runs only for pushes to main (plus pull requests and a weekly schedule), not every push. Name both workflows and the actual push scope so readers can find the documented gate.

This issue also appears on line 70 of the same file.

## 3. Every push and pull request — CI (`.github/workflows/ci.yml`)

hellices and others added 2 commits August 12, 2026 00:40
Nine GitPython advisories (six high) sat open against uv.lock, all fixed by
one bump. They accumulated because nothing was configured to act on them:
there was no dependabot.yml, so the alerts had no route to a change.

The alerts were not a CI failure, and that part is by design. GitPython
reaches the tree only as tach's transitive dependency in the dev group, and
the `security` job audits `uv export --no-dev` - the resolution users
actually install. Gating on dev-only flaws would turn CI red for something
no user can reach, sometimes with no fixed version available. Dependabot is
the right mechanism for that half, and it was missing.

Also documents the gate layering the release depends on, because "run the
right check at the right layer" is currently knowledge rather than a
document: pre-commit for what is cheap on staged files, `make check` before
pushing, CI for the matrix and the audits, and the release workflow's
`verify` job re-running the whole gate rather than trusting a green CI run -
a tag can point at a commit CI never saw.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Round 1, four findings, all upheld. One is a real coverage gap; three were
claims the workflows do not support.

CI audited `uv export --no-dev` without `--all-extras`, so an advisory in
httpx, keyring, mcp, starlette, uvicorn or azure-identity - every one of
them a dependency of a supported `korvid[...]` install - could not fail a
pull request. Only release verification, which does pass `--all-extras`,
would have caught it, and only after a tag. CI now audits the same set.

Dependabot's uv updater reports every dependency as production, so a
`dependency-type: development` group matches nothing and the production
group silently absorbs the dev tools the split exists to separate. Grouped
by name instead, with the runtime list kept beside pyproject.toml.

Two documentation claims were stronger than the workflows:

- the `changes` classifier gates pytest only. Every matrix leg still syncs
  and runs ruff, format, mypy, tach and deptry, and Windows starts before
  skipping its pytest step. Three redundant suite runs are saved, not the
  matrix.
- release `verify` re-runs the correctness half of CI on one environment. It
  omits the format check, pre-commit, Windows, the other interpreters,
  zizmor, dependency-review, CodeQL and ty. Calling it "the entire gate"
  claimed release assurance the workflow does not provide.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@hellices
hellices force-pushed the chore/dependency-hygiene branch from 5191480 to 107fec2 Compare August 11, 2026 15:40
@hellices
hellices merged commit 974c6f4 into main Aug 11, 2026
17 of 20 checks passed
@hellices
hellices deleted the chore/dependency-hygiene branch August 11, 2026 16:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants