While validating a plugin submission against the real install path, I hit a packaging
hazard that is worth recording in its own issue rather than leaving buried in a PR.
What happened
I published plugin zips as release assets, deleted the release, and re-cut it under the
same tag and the same asset filename with different bytes. After that:
zeroclaw plugin install <name> --registry <url> succeeded — but installed the
deleted release's bytes, with a stale manifest.toml.
curl <asset-url> | sha256sum returned the old digest, not the new one.
GitHub's release-asset CDN served the previous object for the same tag/filename pair.
The install did not fail, because the stale bytes still matched the stale digest that
the stale index recorded — the integrity check was internally consistent and wrong.
Why this is a note and not a bug report
publish.yml already defends against this: it verifies an existing asset's digest and
refuses to upload over it, requiring a new name@version for any byte change. This
report is confirmation that the defense is doing real work rather than being belt-and-
braces — remove it and a re-cut release would silently distribute stale plugin bytes to
every zeroclaw plugin install.
Suggestions, take or leave
- A line in
README.md under "Add a plugin" stating that re-cutting a release under an
existing tag is unsupported, and why — so nobody reintroduces it as a convenience.
- Optionally, have the install path warn when a downloaded asset's
Last-Modified
predates the registry entry it was resolved from. Cheap, and it turns a silent stale
install into a visible one.
Happy to open a PR for either if useful.
While validating a plugin submission against the real install path, I hit a packaging
hazard that is worth recording in its own issue rather than leaving buried in a PR.
What happened
I published plugin zips as release assets, deleted the release, and re-cut it under the
same tag and the same asset filename with different bytes. After that:
zeroclaw plugin install <name> --registry <url>succeeded — but installed thedeleted release's bytes, with a stale
manifest.toml.curl <asset-url> | sha256sumreturned the old digest, not the new one.GitHub's release-asset CDN served the previous object for the same tag/filename pair.
The install did not fail, because the stale bytes still matched the stale digest that
the stale index recorded — the integrity check was internally consistent and wrong.
Why this is a note and not a bug report
publish.ymlalready defends against this: it verifies an existing asset's digest andrefuses to upload over it, requiring a new
name@versionfor any byte change. Thisreport is confirmation that the defense is doing real work rather than being belt-and-
braces — remove it and a re-cut release would silently distribute stale plugin bytes to
every
zeroclaw plugin install.Suggestions, take or leave
README.mdunder "Add a plugin" stating that re-cutting a release under anexisting tag is unsupported, and why — so nobody reintroduces it as a convenience.
Last-Modifiedpredates the registry entry it was resolved from. Cheap, and it turns a silent stale
install into a visible one.
Happy to open a PR for either if useful.