The commit-msg hook correctly warns that a wrapped Limit: line is not a trailer, then refuses the git commit --amend that fixes it. The only way out is --no-verify.
Sequence
Commit with a trailer block where two Limit: values are wrapped across two lines each, so they sit in their own paragraph above the real trailer block:
Limit: Fixtures intentionally copy the live authority tree; replacing that
structure with a wholly synthetic fixture is outside D0-013 exact ownership.
Limit: cleanupFixture intentionally suppresses cleanup errors so teardown
cannot obscure the test result; the known teardown-race tradeoff remains.
Warn: render witnesses depend on the live catalog and authority-tree fixture shape
Blast: local
...
Record-Id: r-d0013executionviewshardening
The hook lets the commit through with an accurate warning:
shape ok · references ok
commitlore: line 15 looks like a Limit trailer, but git did not parse it;
the trailer block needs a blank line before it
commitlore: line 17 looks like a Limit trailer, but git did not parse it;
the trailer block needs a blank line before it
git log --format='%(trailers:only=true,keyonly=true)' -1 confirms it: Warn Blast Undo Certainty Record-Id Follows Provenance X-Ticket. The two Limit values are absent from the record.
Amend the message to put both Limit: values on single lines inside the final block, keeping the same Record-Id:
$ git commit --amend -F fixed-message.txt
shape ok · references failed
21: duplicate-id Record-Id — got "r-d0013executionviewshardening",
want "exactly one record per Record-Id"
commitlore: 1 violation (SPEC §6) — the message was not modified
Why this is wrong
--amend replaces the commit. After it, the old commit is unreachable from the branch and there is exactly one commit carrying that Record-Id. The duplicate the check reports does not exist in the resulting history — it exists only because the pre-amend commit was already recorded and the check does not know it is about to be replaced.
The two rules combine into a trap. The first rule tells you the message is malformed. The second rule blocks the correction, unless you either change the Record-Id — which is semantically wrong, since it is the same record — or bypass the hook. I used --no-verify, which is the outcome the hook exists to prevent.
Reproduction
- macOS,
commitlore --version → 0.8.2
- Repository policy:
{"mode": "auto", "unattended": true, "max_records_per_commit": 1, "require_verified_evidence": true}
- Commit a message with a wrapped
Limit: paragraph above the trailer block; observe the warning and that the trailer is absent from %(trailers)
git commit --amend with the same Record-Id and corrected formatting; observe duplicate-id
git commit --amend --no-verify succeeds and %(trailers:key=Limit) then returns both values
What would resolve it
The uniqueness check needs to exclude the commit being amended. GIT_COMMIT is not set for commit-msg on amend, but git rev-parse HEAD during an amend is the commit being replaced, so the check can compare against it and skip a match. Alternatively the check could scan only commits reachable after the operation rather than the recorded set.
A narrower fix that would also help: refuse the original commit instead of warning. If a malformed trailer is worth a warning, and correcting it is blocked, the warning has no action attached to it.
What I could not determine
Whether the same trap applies to rebase -i reword and to commit --amend on a commit whose record was staged through the capture pipeline rather than written by hand. I only exercised the hand-written trailer path.
The commit-msg hook correctly warns that a wrapped
Limit:line is not a trailer, then refuses thegit commit --amendthat fixes it. The only way out is--no-verify.Sequence
Commit with a trailer block where two
Limit:values are wrapped across two lines each, so they sit in their own paragraph above the real trailer block:The hook lets the commit through with an accurate warning:
git log --format='%(trailers:only=true,keyonly=true)' -1confirms it:Warn Blast Undo Certainty Record-Id Follows Provenance X-Ticket. The twoLimitvalues are absent from the record.Amend the message to put both
Limit:values on single lines inside the final block, keeping the sameRecord-Id:Why this is wrong
--amendreplaces the commit. After it, the old commit is unreachable from the branch and there is exactly one commit carrying thatRecord-Id. The duplicate the check reports does not exist in the resulting history — it exists only because the pre-amend commit was already recorded and the check does not know it is about to be replaced.The two rules combine into a trap. The first rule tells you the message is malformed. The second rule blocks the correction, unless you either change the
Record-Id— which is semantically wrong, since it is the same record — or bypass the hook. I used--no-verify, which is the outcome the hook exists to prevent.Reproduction
commitlore --version→0.8.2{"mode": "auto", "unattended": true, "max_records_per_commit": 1, "require_verified_evidence": true}Limit:paragraph above the trailer block; observe the warning and that the trailer is absent from%(trailers)git commit --amendwith the sameRecord-Idand corrected formatting; observeduplicate-idgit commit --amend --no-verifysucceeds and%(trailers:key=Limit)then returns both valuesWhat would resolve it
The uniqueness check needs to exclude the commit being amended.
GIT_COMMITis not set forcommit-msgon amend, butgit rev-parse HEADduring an amend is the commit being replaced, so the check can compare against it and skip a match. Alternatively the check could scan only commits reachable after the operation rather than the recorded set.A narrower fix that would also help: refuse the original commit instead of warning. If a malformed trailer is worth a warning, and correcting it is blocked, the warning has no action attached to it.
What I could not determine
Whether the same trap applies to
rebase -ireword and tocommit --amendon a commit whose record was staged through the capture pipeline rather than written by hand. I only exercised the hand-written trailer path.