The previous commit meant to do this and edited a heading that exists only in
the planning notes, not in PLAN.md -- so the replacement matched nothing and
said nothing, which is the failure mode this file is half a catalogue of.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Every version bump gets an entry in the same commit. Not afterwards: the reason
a change was made is known while it is being made and gone a week later, and a
changelog assembled from commit subjects at release time is a list of things
nobody can act on.
Backfilled 0.8.2 through 0.9.8, because those shipped as a running deployment
rather than as releases and 1.0.0's notes have to be assembled from something.
The rule that earns the file its place is the last one in CLAUDE.md: a fix to
something that *looked* like it worked gets a line, always. Those are the
entries somebody stops working around a bug because of, and they are invisible
from outside -- nobody reports a control that silently does nothing, they just
quietly stop using it. Half of what is in here is that shape: a group delete
that left its grants, a share panel that only saved if you also saved the
resource, an update script that stopped after "== fetching ==".
A release is a signed annotated tag whose message is that version's entry, and
that is not decoration -- /admin/updates reads release notes out of the tag
object, so the tag message is literally what an administrator sees on the update
page.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Found by documenting it. `_notes_for` stripped `-----BEGIN PGP SIGNATURE-----`
from an annotated tag's contents and nothing else, and which header appears
depends on `gpg.format`: `openpgp` writes that one, `ssh` writes
`-----BEGIN SSH SIGNATURE-----`. This repository signs with an SSH key, so the
first signed release tag would have rendered its whole signature block as the
release notes on the update page.
`%(contents:subject)` and `%(contents:body)` would have avoided the question,
and would also have thrown away every blank line in a body written as a list --
which is what release notes are.
The suite caught the other half of the same change: `tag.gpgSign` makes a bare
`git tag <name>` behave as `-s`, so the lightweight tags a test was making now
wait for an editor it does not have.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>