What happened

The release build for Simple CVE Tracker v1.2.0 failed on its lint step, minutes after the same code passed a local lint check. The failure stopped the build before it could package or publish anything.

The artifact

The release workflow ran ruff check . --select E4,E7,E9,F,B and printed:

B905 `zip()` without an explicit `strict=` parameter
   |
90 |     for seg_a, seg_b in zip(key_a, key_b):
   |
help: Add explicit value for parameter `strict=`
Found 1 error.

The flagged line was the version comparison in matcher.py. The build stopped at the release / build job and never reached release / publish. The failed run is public at Simple-CVE-Tracker actions run 29617190618.

Root cause

ruff check . with no rule selection uses ruff’s default set: a subset of the pycodestyle E rules plus the Pyflakes F rules. It does not include flake8-bugbear, the B rules, and B905 is a bugbear rule. A bare local ruff check . never sees it.

The release workflow selects E4,E7,E9,F,B, which turns bugbear on. That single B is the whole difference: code a plain local run calls clean fails the moment bugbear is switched on, and the release build is the first place that happens.

The fix

The immediate fix was one argument: zip(key_a, key_b, strict=False). That is the correct answer, not a way to silence the rule, because the two version-part lists can legitimately differ in length and the intent is to stop at the shorter one. B905 exists to force that choice to be written down. Where equal length is actually required, strict=True raises if the lengths differ.

The durable fix is to make the local check run the same rules as the build. Build-Tools ships a templates/dev/requirements.txt that tool repos copy as requirements-dev.txt, along with the same --select string, so a developer’s check matches the release build’s. A lint that only runs one way finds problems at the worst time.

Evidence boundary

This is a gap between two rule sets, not a claim that bugbear catches every bug or that a passing lint means correct code. B905 flags an unstated strict=; it does not judge whether stopping at the shorter list is right for the logic, and that judgment stayed with the author.

Source ledger

Source owner Primary URL Review class Last reviewed Exact claim or evidence mapped
JDE-Projects Simple CVE Tracker https://github.com/JDE-Projects/Simple-CVE-Tracker/actions/runs/29617190618 Production evidence August 18, 2026 The v1.2.0 release build failed on B905 with the quoted output.
JDE-Projects Simple CVE Tracker https://github.com/JDE-Projects/Simple-CVE-Tracker/commit/fc56f039dc586e5573617b641129999a3f6ecb2b Production evidence August 18, 2026 The fix added strict=False to the version-compare zip.
JDE-Projects Build-Tools https://github.com/JDE-Projects/Build-Tools/blob/01090b68a33074fda7fcd97d088cb29aa9718f61/README.md Production evidence August 18, 2026 CI selects E4,E7,E9,F,B, not ruff’s defaults, and dev requirements match CI.
Astral https://docs.astral.sh/ruff/rules/zip-without-explicit-strict/ Framework-critical August 18, 2026 B905 is the flake8-bugbear zip-without-explicit-strict rule.