mirror of
https://github.com/hanzoai/chat.git
synced 2026-08-07 11:07:52 +00:00
package.json said 1.0.77 while ghcr.io/hanzoai/chat shipped 1.0.113 — 36 patches of drift that broke nothing on the way, which is why it lasted. The cause is one sentence: the declared version is an INPUT to imgver (max(declared, published)+1) that no writer ever writes. published advances once per release, declared never moves, and the gap grows by exactly one forever. So CI becomes the writer. The release job stamps package.json BEFORE the build, then commits that exact tree and tags THAT commit — the tag now names both the bytes that shipped and the number they call themselves. Ordering preserves every existing invariant: verify-pullable, then commit+tag, then pin (the deploy), then push main last, so bookkeeping can never un-ship a good build. It also tags at all, which it never did — the tag stream stalled at v1.0.109 while images ran to 1.0.113, so `git tag` was not evidence of anything. scripts/version.sh check enforces one invariant: the declared version must never be BEHIND the highest published version of its stream. Equal means CI wrote it; ahead means a human is preparing a release. Wired as a version-drift gate in hanzo.yml, which hanzoai/ci runs on every push and PR. It works without a GH_PAT — the registry half degrades to git tags and SAYS SO on stderr rather than silently passing. Corrected forward only, 1.0.77 -> 1.0.113. Nothing renumbered, nothing retagged; the next release is 1.0.114. Co-authored-by: Hanzo Dev <dev@hanzo.ai>