Pin trace references to a specific upstream version and detect when the upstream changes.

How version pins work#

A downstream requirement can pin the upstream version it was last verified against using the ~N suffix:

## UP-001
```attr
status: approved
version: 3
```
## DN-001
```attr
status: approved
trace: [UP-001~2]   # verified against UP-001 v2, but UP-001 is now v3
```

When the upstream version is bumped, the pin becomes stale and reqmd flags the downstream as needing re-verification.

Findings#

ConditionMeaningLevelDemote with
pin < upstream.versionOutdated — upstream bumped, downstream needs re-verifyERROR--relaxed-versions
pin > upstream.versionPredated — downstream claims a non-existent versionERROR(never — data integrity)
pin == upstream.versionCurrent
No pinNo version check applies

Try it#

The spec tree in Step 2 doesn’t use version pins, so no version-pin findings fire. To see it in action, add version: 1 to an upstream requirement and ~1 to a downstream trace, then bump the upstream to version: 2:

reqmd check 02-trace-your-spec/
# ❌ DN-001  version-pin: outdated — UP-001 is at version 2, pinned to ~1

# Demote to WARNING (CI-friendly: fails on predated, warns on outdated)
reqmd check --relaxed-versions 02-trace-your-spec/
# ⚠ DN-001  version-pin: outdated — UP-001 is at version 2, pinned to ~1

Suppression#

Suppress the check per-requirement:

reqmd-suppress:
  - version-pin

Stale verdicts#

Version pins also apply to result→measure traces: pin a result with MEASURE-ID~3 against a measure now at version: 4 and the outdated finding fires. This is how stale-verdict is detected — no new check, just the existing version-pin check on a new edge type. See Step 5.

Bulk-update pins#

When you’ve bumped a spec version and a wave of outdated findings appear, reqmd repin rewrites the affected pins in place. See Repin.

What’s next#

Now export your spec tree — go to Step 3.