All releases

v0.4.9

Signedpublished August 18, 2026

What 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.sh opened 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 a notes field 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 /healthz said v0.4.8 could learn that v0.4.9 existed and could not learn what was in it, and /registry/releases was a column of version numbers and badges. Publishing now sends the section body, /registry/releases/vX.Y.Z renders it as markdown, and Settings → About links to it as "What's new in vX.Y.Z" — a release_notes_url the 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-notes re-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 new PATCH that 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.sh read ### Added as 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

registry build 17
amd64747 MB
sha256:026e87af8cf5899aac9db5f3756e3b162bcec524b1f10487de25a42cf2bf300c
Download
arm64621 MB
sha256:5dca79f8d0d1777d4d982924a10d5e5fb68479cf313f5491dbb66d882345d6c5
Download
registry build 17
amd6445 MB
sha256:879b60f96a982e913124529ceac07e9dea0a20315bec8e29abf69f736dbfa6bb
Download
arm6444 MB
sha256:69093f1623a345bade1e4e5fb7c0ff485254014ed29cb0252271999a290a7f78
Download

Installer files

docker-compose.yml14 KBsha256:4681b04b3e2b93b79c76846b51c9e0b529dc59742311e42d77716bda482c6a9b
install.sh123 KBsha256:b8fcfae6b2d6dcb50c8bcb51415d3e8ff2def96ca39d1f89e0476bde16d0d464
traefik-dynamic-http.yml5 KBsha256:e344c8efd13c7d84996e2ebfbc75dcee2d995d8538c8a245c89c0e44fad0089b
traefik-dynamic.yml6 KBsha256:d18fa561b8eb7d53b015284e0246b2d05953bf281b65269c1fae3d6883530db6
uninstall.sh31 KBsha256:d8dc586f38e0cf33eadc126d75b303c660e970e55028f60ad4e2872c40cbaa71

Signature

ecdsa-p256-sha256key f1f1eaf642454d65

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.

Verify devgrail-container (amd64)
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