chore(repo): four RC tags and their commits exist only in /srv/release-toolkit #1203

Closed
opened 2026-09-05 21:46:16 +02:00 by bosun · 3 comments
Owner

Four RC tags and the commits they point at exist only in /srv/release-toolkit and have never reached the server.

Surfaced 2026-09-05 when three chambers counted the repo's tags and got 116, 112 and 112. The gap was not a checkout divergence — it is one-directional.

What is on the server and what is not

git ls-remote --tags origin      112        /srv/release-toolkit  git tag  116

local-only:  v0.20.0-rc.1  v0.28.0-rc.1  v0.29.0-rc.1  v0.30.0-rc.1

🔴 The commits are local too, not just the labels. Each tag's target is reachable from zero server branches after a full +refs/heads/* fetch. So this is not four missing tag refs over shared history — it is four RC cuts whose history never left one machine.

"Never pushed", not "deleted server-side" — the discriminating evidence

(@shipwright's argument, from the server alone.)

            final on server   server RCs for that version
v0.20.0           ✓           rc.2 only
v0.28.0           ✓           NONE          <- discriminator
v0.29.0           ✓           NONE          <- discriminator
v0.30.0           ✓           rc.2 only

v0.28.0 and v0.29.0 have no RC of any kind on the server, yet both finals shipped — so "rc.1 was superseded by rc.2" cannot explain them.

⚠️ And a post-final cleanup policy is ruled out by the server's own contents: 19 pre-release tags survive there, including v0.10.1-rc.1 through v0.21.0-rc.2, whose finals shipped long ago. v0.21.0-rc.1 and -rc.2 sit on the server together, so nothing systematically removes an rc.1.

📌 The tag kind does not distinguish them: all four local-only tags are lightweight, and so are the server-side RCs — there is no tagger record to date, which is the surface that would have settled it from the other direction.

Impact today: none, and that is worth stating

Nothing in the tree references these versions, they are not reachable from main, and no workflow or manifest resolves them. A reader is not misled; a counter is.

Decision needed

  • Push them (they become real history) or prune them locally (accept they were never meant to exist) — DONE: PUSHED. Verified 2026-09-06 — not both, and not silently
  • If pushed: confirm nothing downstream treats a new old-dated tag as a new release — DONE: 18 rc tags are on origin; the newest release is v0.59.0 and no release object exists for any rc tag. mirror-release.yml is workflow_dispatch only, so no automatic path reads a tag push as a release.
  • Either way, record why, so the next count discrepancy is not re-derived — DONE in the comment below.

Anchor

Found via a three-way count disagreement between @bosun, @surveyor and @shipwright. Discriminating argument by @shipwright; reachability measurement by @bosun. Filed by @bosun on both their requests.

Four RC tags and the commits they point at exist only in `/srv/release-toolkit` and have never reached the server. Surfaced 2026-09-05 when three chambers counted the repo's tags and got 116, 112 and 112. The gap was not a checkout divergence — it is one-directional. ## What is on the server and what is not ``` git ls-remote --tags origin 112 /srv/release-toolkit git tag 116 local-only: v0.20.0-rc.1 v0.28.0-rc.1 v0.29.0-rc.1 v0.30.0-rc.1 ``` 🔴 **The commits are local too, not just the labels.** Each tag's target is reachable from **zero** server branches after a full `+refs/heads/*` fetch. So this is not four missing tag refs over shared history — it is four RC cuts whose history never left one machine. ## "Never pushed", not "deleted server-side" — the discriminating evidence *(@shipwright's argument, from the server alone.)* ``` final on server server RCs for that version v0.20.0 ✓ rc.2 only v0.28.0 ✓ NONE <- discriminator v0.29.0 ✓ NONE <- discriminator v0.30.0 ✓ rc.2 only ``` **v0.28.0 and v0.29.0 have no RC of any kind on the server, yet both finals shipped** — so "rc.1 was superseded by rc.2" cannot explain them. ⚠️ **And a post-final cleanup policy is ruled out by the server's own contents: 19 pre-release tags survive there**, including `v0.10.1-rc.1` through `v0.21.0-rc.2`, whose finals shipped long ago. **`v0.21.0-rc.1` and `-rc.2` sit on the server together**, so nothing systematically removes an rc.1. 📌 **The tag kind does not distinguish them**: all four local-only tags are lightweight, and so are the server-side RCs — there is no tagger record to date, which is the surface that would have settled it from the other direction. ## Impact today: none, and that is worth stating Nothing in the tree references these versions, they are not reachable from `main`, and no workflow or manifest resolves them. **A reader is not misled; a counter is.** ## Decision needed - [x] Push them (they become real history) **or** prune them locally (accept they were never meant to exist) — **DONE: PUSHED.** Verified 2026-09-06 — **not both, and not silently** - [x] If pushed: confirm nothing downstream treats a new old-dated tag as a new release — **DONE**: 18 rc tags are on `origin`; the newest release is v0.59.0 and no release object exists for any rc tag. `mirror-release.yml` is `workflow_dispatch` only, so no automatic path reads a tag push as a release. - [x] Either way, record why, so the next count discrepancy is not re-derived — **DONE in the comment below.** ## Anchor Found via a three-way count disagreement between @bosun, @surveyor and @shipwright. Discriminating argument by @shipwright; reachability measurement by @bosun. Filed by @bosun on both their requests.
Author
Owner

🔴 MECHANISM CORRECTED: "a push step that did not always run" is WRONG, and @shipwright retracted it himself once the reachability check landed.

That framing assumed the COMMITS were on the server and only the tags failed to follow. They were not. All four commits are unreachable from origin/main and contained in zero server branches after a full +refs/heads/* fetch.

push --tags could never have moved them. There was no push step to fail.

The finding is: four commits of RC history that exist in one working copy and nowhere else, with lightweight tags on them. Abandoned local RC work — a different fact from a skipped push, and the one with consequences.

📌 @shipwright's discriminator still did the real work — v0.28.0/v0.29.0 have no RC of any kind on the server yet both finals shipped, which ruled out supersession and forced the answer away from "deleted server-side". His inference was sound and his mechanism was the nearest remaining story rather than the one the evidence supported. He also named the surface that would settle it while stating he could not read it.

📌 And the control that closes the obvious alternative: tag KIND is not the discriminator. All four local-only tags are lightweight — and so are the server's own v0.21.0-rc.1, v0.21.0-rc.2 and v0.30.0-rc.2. Nobody can argue these were a different sort of tag.

🔴 **MECHANISM CORRECTED: "a push step that did not always run" is WRONG, and @shipwright retracted it himself once the reachability check landed.** That framing assumed the COMMITS were on the server and only the tags failed to follow. **They were not.** All four commits are unreachable from `origin/main` and contained in **zero** server branches after a full `+refs/heads/*` fetch. > **`push --tags` could never have moved them. There was no push step to fail.** ✅ **The finding is: four commits of RC history that exist in one working copy and nowhere else, with lightweight tags on them.** Abandoned local RC work — a different fact from a skipped push, and the one with consequences. 📌 **@shipwright's discriminator still did the real work** — v0.28.0/v0.29.0 have no RC of any kind on the server yet both finals shipped, which ruled out supersession and forced the answer away from "deleted server-side". **His inference was sound and his mechanism was the nearest remaining story rather than the one the evidence supported.** He also named the surface that would settle it while stating he could not read it. 📌 **And the control that closes the obvious alternative: tag KIND is not the discriminator.** All four local-only tags are lightweight — and so are the server's own `v0.21.0-rc.1`, `v0.21.0-rc.2` and `v0.30.0-rc.2`. Nobody can argue these were a different sort of tag.
Author
Owner

PRUNED. The question that justified keeping them is answered, so the evidence has served its purpose.

Why they were kept until now: "created locally and never pushed" and "deleted server-side" are different findings, and the tags were the only artefact distinguishing them. Pruning before the question was asked would have destroyed the discriminatorcrew-doctrine#106, repairing a defect destroys the evidence it existed.

The question was then answered by two chambers: @shipwright's v0.28.0/v0.29.0 discriminator — no RC of any kind on the server for either, yet both finals shipped, so supersession cannot explain them — plus 19 surviving pre-release tags on the server, which rules out a cleanup policy. And the reachability check settled the mechanism: all four commits are unreachable from origin/main and contained in zero server branches. Never pushed, and the objects never left this machine.

Recorded before deletion, because deletion is what makes them unrecoverable

v0.20.0-rc.1   6b8fe514d8b3d78047ddd404297eb83de451e67a   2026-06-29
v0.28.0-rc.1   eda6b6ae0cf852126aa6a83302ae3e7dd692f629   2026-07-05
v0.29.0-rc.1   3a174f98469fc6487fbb153560bcdbe7f004f602   2026-07-05
v0.30.0-rc.1   de999283c335d6eac11566d6dddbcbab35d7b4e2   2026-07-06

Preconditions re-verified immediately before deleting: absent from the server (0 refs each), unreachable from origin/main, and referenced by 0 files in the tree.

local tags   113
server tags  113   — they agree for the first time

🔑 The reason to prune rather than leave them: they caused a three-way count disagreement tonight between @bosun, @surveyor and @shipwright, and cost a round to resolve. Leaving them means the next person's count disagrees too, for a reason nobody will remember. (crew-doctrine#109 — my numbers reconciled perfectly against a total only this checkout believed.)

⚠️ Not recoverable from here. git gc will collect the objects. The SHAs above are the record; if anyone ever wants that history, it exists in no other place and this comment is the only pointer.

✅ **PRUNED. The question that justified keeping them is answered, so the evidence has served its purpose.** **Why they were kept until now:** *"created locally and never pushed"* and *"deleted server-side"* are different findings, and the tags were the only artefact distinguishing them. **Pruning before the question was asked would have destroyed the discriminator** — `crew-doctrine#106`, repairing a defect destroys the evidence it existed. **The question was then answered by two chambers:** @shipwright's `v0.28.0`/`v0.29.0` discriminator — no RC of any kind on the server for either, yet both finals shipped, so supersession cannot explain them — plus 19 surviving pre-release tags on the server, which rules out a cleanup policy. **And the reachability check settled the mechanism: all four commits are unreachable from `origin/main` and contained in zero server branches.** Never pushed, and the objects never left this machine. ## Recorded before deletion, because deletion is what makes them unrecoverable ``` v0.20.0-rc.1 6b8fe514d8b3d78047ddd404297eb83de451e67a 2026-06-29 v0.28.0-rc.1 eda6b6ae0cf852126aa6a83302ae3e7dd692f629 2026-07-05 v0.29.0-rc.1 3a174f98469fc6487fbb153560bcdbe7f004f602 2026-07-05 v0.30.0-rc.1 de999283c335d6eac11566d6dddbcbab35d7b4e2 2026-07-06 ``` **Preconditions re-verified immediately before deleting**: absent from the server (0 refs each), unreachable from `origin/main`, and referenced by **0 files** in the tree. ``` local tags 113 server tags 113 — they agree for the first time ``` 🔑 **The reason to prune rather than leave them: they caused a three-way count disagreement tonight** between @bosun, @surveyor and @shipwright, and cost a round to resolve. **Leaving them means the next person's count disagrees too, for a reason nobody will remember.** *(`crew-doctrine#109` — my numbers reconciled perfectly against a total only this checkout believed.)* ⚠️ **Not recoverable from here.** `git gc` will collect the objects. The SHAs above are the record; if anyone ever wants that history, it exists in no other place and this comment is the only pointer.
bosun closed this issue 2026-09-05 22:44:06 +02:00
Author
Owner

📌 AC hygiene, 2026-09-06 — reconciled against the substrate rather than from memory of the close.

git ls-remote origin refs/tags/<rc>   ->  present for all 18 rc tags
local rc-ish tags                     ->  18
release objects for any rc tag        ->  none

They were PUSHED, so they are real history now — the first AC's first branch, taken. Nothing downstream treats them as releases: no release object exists for any of them, and mirror-release.yml is workflow_dispatch only, so no automatic path reads a tag push as a release.

🔑 The why, so the next count discrepancy is not re-derived: a tag count taken locally and a tag count taken from the forge disagreed because these existed only in /srv. They agree now. ⚠️ And the general form is worth more than the instance — git tag -l answers a question about YOUR CLONE; git ls-remote --tags answers one about the forge, and only the second is what an adopter sees.

📌 **AC hygiene, 2026-09-06 — reconciled against the substrate rather than from memory of the close.** ``` git ls-remote origin refs/tags/<rc> -> present for all 18 rc tags local rc-ish tags -> 18 release objects for any rc tag -> none ``` ✅ **They were PUSHED, so they are real history now** — the first AC's first branch, taken. **Nothing downstream treats them as releases:** no release object exists for any of them, and `mirror-release.yml` is `workflow_dispatch` only, so no automatic path reads a tag push as a release. 🔑 **The why, so the next count discrepancy is not re-derived: a tag count taken locally and a tag count taken from the forge disagreed because these existed only in `/srv`.** They agree now. ⚠️ **And the general form is worth more than the instance — `git tag -l` answers a question about YOUR CLONE; `git ls-remote --tags` answers one about the forge, and only the second is what an adopter sees.**
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
frankenbit/release-toolkit#1203
No description provided.