v0.4.9
Signedpublished August 18, 2026What changed
Added
-
The changelog reaches the people running DevGrail. This file was the only place a release was described in human terms, and it never left the repo:
publish.shopened it twice — once to take the version from the newest heading, once to stamp today's date onto it — and read no further. The registry has carried anotesfield for every release since releases existed, served in the manifest and rendered on both the dashboard and the public release page, and nothing had ever written to it. So a customer whose/healthzsaidv0.4.8could learn thatv0.4.9existed and could not learn what was in it, and/registry/releaseswas a column of version numbers and badges. Publishing now sends the section body,/registry/releases/vX.Y.Zrenders it as markdown, and Settings → About links to it as "What's new in vX.Y.Z" — arelease_notes_urlthe server had been computing and no screen had ever shown. A heading with nothing under it is now refused before anything is built, because shipping a version nobody can find out about is the failure this is meant to prevent.scripts/publish.sh --sync-notesre-sends every section to the release of the same name, which is how the ten releases published before this one got their notes. It builds and uploads nothing, skips versions the registry does not have rather than inventing them, and is also the way to fix a typo in prose after a release has shipped: it goes through a newPATCHthat touches one column, where re-posting the release would replace the artifact set and move the pointers customers are downloading from. The dashboard grows an editor on the same path.
Fixed
publish.shread### Addedas a release named#. The heading regex accepted##followed by no space, so every subsection heading in this file produced a phantom entry in the version list. Only the first line was ever used, which is why it stayed invisible — but a changelog whose first###came before its first##would have taken#as the version to publish.
Container images
Installer files
Signature
One signature covers every artifact above. It is made off this host, and neither this site nor the registry behind it can check it — that is the point, and it is why verifying it catches things a checksum from the same server cannot. How to verify it.
curl -fsSL https://web-dev.trixibot.com/api/registry/releases/v0.4.9 -o release.json
# -j, not -r: -r appends a newline the signer never saw, and the check fails.
jq -j '.signature.payload' release.json > payload
jq -r '.signature.signature' release.json | base64 -d > payload.sig
openssl dgst -sha256 -verify devgrail-release.pem -signature payload.sig payload
# -> Verified OK
# The payload must name this release, so an older signed one cannot be replayed.
head -2 payload
# ...and it must name this exact file. -qxF: whole line, literal.
grep -qxF 'image devgrail-container 17 amd64 026e87af8cf5899aac9db5f3756e3b162bcec524b1f10487de25a42cf2bf300c' payload && echo "digest is covered by the signature"The signed payload — shown for reading, not for verifying
Copy this from the manifest with jq -j, never from this page: the signature covers exact bytes, and rendering here drops the trailing newline the signer included.
devgrail-release-signature-v1
release v0.4.9
asset docker-compose.yml 16 4681b04b3e2b93b79c76846b51c9e0b529dc59742311e42d77716bda482c6a9b
asset install.sh 16 b8fcfae6b2d6dcb50c8bcb51415d3e8ff2def96ca39d1f89e0476bde16d0d464
asset traefik-dynamic-http.yml 15 e344c8efd13c7d84996e2ebfbc75dcee2d995d8538c8a245c89c0e44fad0089b
asset traefik-dynamic.yml 16 d18fa561b8eb7d53b015284e0246b2d05953bf281b65269c1fae3d6883530db6
asset uninstall.sh 16 d8dc586f38e0cf33eadc126d75b303c660e970e55028f60ad4e2872c40cbaa71
image devgrail-container 17 amd64 026e87af8cf5899aac9db5f3756e3b162bcec524b1f10487de25a42cf2bf300c
image devgrail-container 17 arm64 5dca79f8d0d1777d4d982924a10d5e5fb68479cf313f5491dbb66d882345d6c5
image devgrail-server 17 amd64 879b60f96a982e913124529ceac07e9dea0a20315bec8e29abf69f736dbfa6bb
image devgrail-server 17 arm64 69093f1623a345bade1e4e5fb7c0ff485254014ed29cb0252271999a290a7f78