Second occurrence, in a different repository
CommitLore, earlier: 03b4bfe carried Follows: r-8c31f7, a record that never existed — the commit that would have created it died in a revert conflict.
gitseed, today: 4d99a48 carries Follows: r-gsa007. No such record exists in history.
$ commitlore validate --commit 4d99a48
$ echo $?
0
$ commitlore stale
dangling refs
Follows: r-gsa007 want an existing Record-Id in history
Once is a bug. Twice, in two repositories, by two different authors, is a defect in the tool.
Why it survives
The commit-msg hook runs validate. validate checks a trailer's shape — r-[a-z0-9]{6,} — and it is right to do so, because shape is decidable from the message alone. Whether the referenced record exists needs the repository, and validate --commit <sha> already has it.
stale does the check. Nothing in the commit path, CI, or the hook set runs stale. So a dangling reference is written, accepted, pushed, and only found if a human types stale — which happened here by accident, while investigating something else.
What a fix has to get right
A reference can only point backwards: the referenced record must already be in history when the referring commit is made. So this is decidable at commit time when the repository is available, and is not decidable from a message alone.
That asymmetry is the design constraint. validate reading a file on stdin cannot do it; validate --commit <sha> can. The check must therefore be conditional on having a repository, and must not become a reason to reject a message the hook cannot fully evaluate.
Consider also: the failing side is silent. A dangling Follows: makes the record chain lie about its own continuity, which is the one property this tool sells.
Both instances are real and unfixed
03b4bfe in this repository, 4d99a48 in gitseed. Fixing the checker should be verified against both, not against a synthetic case.
Second occurrence, in a different repository
CommitLore, earlier:
03b4bfecarriedFollows: r-8c31f7, a record that never existed — the commit that would have created it died in a revert conflict.gitseed, today:
4d99a48carriesFollows: r-gsa007. No such record exists in history.Once is a bug. Twice, in two repositories, by two different authors, is a defect in the tool.
Why it survives
The commit-msg hook runs
validate.validatechecks a trailer's shape —r-[a-z0-9]{6,}— and it is right to do so, because shape is decidable from the message alone. Whether the referenced record exists needs the repository, andvalidate --commit <sha>already has it.staledoes the check. Nothing in the commit path, CI, or the hook set runsstale. So a dangling reference is written, accepted, pushed, and only found if a human typesstale— which happened here by accident, while investigating something else.What a fix has to get right
A reference can only point backwards: the referenced record must already be in history when the referring commit is made. So this is decidable at commit time when the repository is available, and is not decidable from a message alone.
That asymmetry is the design constraint.
validatereading a file on stdin cannot do it;validate --commit <sha>can. The check must therefore be conditional on having a repository, and must not become a reason to reject a message the hook cannot fully evaluate.Consider also: the failing side is silent. A dangling
Follows:makes the record chain lie about its own continuity, which is the one property this tool sells.Both instances are real and unfixed
03b4bfein this repository,4d99a48in gitseed. Fixing the checker should be verified against both, not against a synthetic case.