Rules / GRN-T004
GRN-T004 no-matching-tag
| Default severity | warn |
| Kind | diff rule: fires only when the trusted version had the property and the new version lost it, or the new version gained a risky property the trusted version lacked. |
| Status | Implemented in 0.1 |
What it checks
The trusted version has a matching git tag in the project's source repository and the new
version has none. A tag matches if it is named X, vX, <name>-X or <name>-vX, where
<name> is the package name. An exact name wins; otherwise X is compared as a PEP 440
version, so tag 2026.01.04 matches release 2026.1.4.
Garnet Guard looks for the tag in the repository named by the attestation first, then in the repository in the package's project URLs, and accepts a tag in either. Some projects publish from a separate release repository but tag the main one. When no tag is found, the finding lists every repository it searched. GitHub repositories only, for now.
Why it matters
Projects that tag releases normally tag every release. A version on the registry with no tag in the repository was probably not built from the repository's history, which is what a token-based upload looks like.
Example finding
From the replay of lightning 2.6.2 (MAL-2026-3201), checked against the tags as they exist today.
lightning 2.6.1 → 2.6.2: WARN
WARN GRN-T004 no-matching-tag: github.com/Lightning-AI/pytorch-lightning has a tag for 2.6.1 but none for 2.6.2
- 2.6.1 → tag 2.6.1 at 655a3a91828694b9bfc241177f474741e483aeaa <https://github.com/Lightning-AI/lightning/tree/2.6.1>
- 2.6.2: no tag named 2.6.2, v2.6.2, lightning-2.6.2 or lightning-v2.6.2 <https://github.com/Lightning-AI/pytorch-lightning/tags>
The same rule reported lightning 2.6.3 and elementary-data 0.23.3 (MAL-2026-3083) in the replay.
How to resolve it
- Check the repository's tags and releases pages. Tags are sometimes pushed late, so look again if the release is only minutes old.
- A missing tag can be an oversight. Ask the maintainers before merging, or wait for the tag.
- If the project has stopped tagging releases, or uses a tag format Garnet Guard doesn't recognize, add an ignore and say so in the reason.
Allowlisting
Once you've reviewed a release, ignore this rule for that package and version range.
Every ignore needs a reason and an expiry date; after until it stops applying and the
report notes that it expired.
[[garnet.ignore]]
package = "examplelib"
versions = "==2.6.2"
rules = ["GRN-T004"]
reason = "project tags releases as release/X, confirmed in example/examplelib#90"
until = "2027-06-30"
To change the rule's severity for every package instead:
[garnet.rules]
"GRN-T004" = "block" # "off" | "info" | "warn" | "block"
Suppressed findings still appear in JSON and SARIF output, marked with the ignore that
matched. The policy format is in SPEC §7; 0.1's garnet diff
doesn't read policy files yet.