Repository navigation
v1.7.3
A paragraph that holds no record was being inherited as one
If you squash-merge with squash-preserve, take this one.
A squash merge in another repository was refused by commitlore validate and
could not land:
shape failed · 169: unknown-key Claude-Session — got "Claude-Session", want "a key from SPEC §3, or X-Claude-Session if this is your own metadata"
The range held an ordinary merge commit with no record at all. Its last
paragraph was a single line:
Claude-Session: https://claude.ai/code/session_…
squash-preserve collected that paragraph as an inherited record, stamped
Provenance: inherited <sha> onto it, and composed a message its own validator
then refused — blocking the merge the command had been run to protect.
Why it happened
Git decides what a trailer block is, and a message's last paragraph qualifies
whatever its keys mean. So the paragraph cannot be refused at parse time; the
question has to be asked of what the parse returns. types.ts isCommitLoreKey
already answers it for the index, where paragraphs like sha256: and Tests:
were once served to agents as recorded decisions (#335). The squash path never
asked.
What changes
An inherited block now carries only the keys SPEC §3 defines, and a block left
with none contributes nothing.
The filter is per trailer, not per block: a paragraph mixing Limit: with a
foreign key is a real record, so dropping the whole block would lose it while
inheriting it whole would still fail validate. Signed-off-by: goes the same
way as any other key outside the vocabulary — it is an attestation about the
commit that carried it, and inheriting it would assert a sign-off on a commit
nobody signed.
The identity-collision check had to agree. Stripping those keys makes a faithful
copy differ from its origin, so the mixed case stopped failing on unknown-key
and started failing on duplicate-id. An inherited copy is now compared by its
record content — the same exemption 1.7.2 made for the transport stamp, one key
class over.
Known residual
A commit that already landed with an inherited non-record block re-squashes to a
block whose only key is Provenance:. It validates, and it says nothing. That
shape is recorded as a Warn: on the fix rather than filtered, because nothing
reported it and the output is valid.
Also in this release
@modelcontextprotocol/sdk 1.30.1, js-yaml 5.4.2 (dev), and
docker/setup-qemu-action v4.4.0 in CI. @types/node stays on 22.x:
engines.node is >=22.23.2, and types from a later major admit APIs that
runtime does not have — the only thing that would refuse them is the type
checker.
This is a patch release. No command, flag, trailer key, or host setting changes.
Canonical source: c04d20a; Canonical
dist/commitlore.mjs SHA-256:
9e3b770f9248d50e2abc86a5616de65bf195260cce9085faa7273036d5df5919
Full Changelog: v1.7.2...v1.7.3