docs(integration): the twelve tags whose image digest was never rewritten #1242

Merged
bosun merged 2 commits from i/1210-broken-digest-tags into main 2026-09-06 10:08:38 +02:00
Owner

Closes #1210. Docs only — the disposition, not a re-pin.

Placement

Directly under the paragraph it qualifies. The guide promises "this action is pinned to an image digest, rewritten at cut time, so @vX gets exactly the rt that tag was cut from"and on twelve tags the rewrite did not happen. The correction belongs against the claim, not in a footnote elsewhere.

Re-measured rather than carried

Classifying every final tag by its action.yml digest reproduces the split exactly:

NOFIELD  63     ZEROS  12     REAL  20        (tracker: 63 / 12 / 19)

The twelve are byte-identically the twelve — set equality against the tracker's list, not a spot check. REAL is 20 rather than 19 because v0.59.0 has been cut since the tracker was written.

Both boundary numbers verified, and the section needs both:

v0.48.1   first REAL tag
v0.50.0   relapse
v0.54.1   relapse
v0.54.2   earliest CONTINUOUSLY usable — every later tag is REAL

"Working since v0.48.1" is true and would send a reader into a hole, so the heading leads with v0.54.2 and the section explains why the earlier number is not the advice.

The 404 reproduced independently, with a positive control on a different real digest than the tracker used — v0.59.0's digest returns 200, the zeros digest 404, same call, same headers, same credentials. That makes it a second observation rather than a repeat of the first.

📌 No percentage in the text, deliberately

The tracker's "12 of 31 — 39%" is the right framing for a tracker and the wrong thing to publish. The twelve are immutable published history; the denominator is every tag advertising a pointer, and it moved 31 → 32 between the tracker being written and this being measured. A ratio here decays on the next cut. The section names the twelve and the boundary tag, both of which are durable.

AC coverage

  • Both numbers named, with the two relapses, so the earlier one cannot mislead.
  • The twelve listed, and what a consumer actually sees: an image-pull 404, not a resolution failure — the uses: resolves and the action is found; the step fails on the pull.
  • The 63 named as a third state — no rt step rather than a broken one. Different symptom, different fix.
  • Does not close by the gate landing. #1205 stops the thirteenth; nothing here depends on it, and this PR touches no gate.

Verification

listed twelve vs measured twelve   set-identical (12/12)
placement                          immediately follows the digest-rewrite paragraph
render                             /api/v1/markdown 200, section present, 15 tables intact
backtick parity                    clean
register-check / contract-paths / dated-examples / gitea-twin    rc=0 ×4

What this does NOT do

  • Re-pins nothing. Per the ruling: documenting preserves the option to repair a specific tag; force-moving published history is irreversible and buys nothing today.
  • Does not touch action.yml or the cut path.
  • Does not claim the twelve are unreachable in principle — only that the digest they name does not resolve.

🤖 Generated with Claude Code

https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i

Intended-targets: #1210

Closes #1210. Docs only — the disposition, not a re-pin. ## Placement Directly under the paragraph it qualifies. The guide promises *"this action is pinned to an image digest, rewritten at cut time, so `@vX` gets exactly the `rt` that tag was cut from"* — **and on twelve tags the rewrite did not happen.** The correction belongs against the claim, not in a footnote elsewhere. ## Re-measured rather than carried Classifying **every** final tag by its `action.yml` digest reproduces the split exactly: ``` NOFIELD 63 ZEROS 12 REAL 20 (tracker: 63 / 12 / 19) ``` **The twelve are byte-identically the twelve** — set equality against the tracker's list, not a spot check. `REAL` is 20 rather than 19 because `v0.59.0` has been cut since the tracker was written. **Both boundary numbers verified, and the section needs both:** ``` v0.48.1 first REAL tag v0.50.0 relapse v0.54.1 relapse v0.54.2 earliest CONTINUOUSLY usable — every later tag is REAL ``` *"Working since `v0.48.1`"* is true and would send a reader into a hole, so the heading leads with `v0.54.2` and the section explains why the earlier number is not the advice. **The 404 reproduced independently**, with a positive control on a **different** real digest than the tracker used — `v0.59.0`'s digest returns **200**, the zeros digest **404**, same call, same headers, same credentials. That makes it a second observation rather than a repeat of the first. ## 📌 No percentage in the text, deliberately The tracker's *"12 of 31 — 39%"* is the right framing for a tracker and the wrong thing to publish. **The twelve are immutable published history; the denominator is every tag advertising a pointer, and it moved 31 → 32 between the tracker being written and this being measured.** A ratio here decays on the next cut. The section names the twelve and the boundary tag, both of which are durable. ## AC coverage - **Both numbers named**, with the two relapses, so the earlier one cannot mislead. - **The twelve listed**, and what a consumer actually sees: **an image-pull 404, not a resolution failure** — the `uses:` resolves and the action is found; the step fails on the pull. - **The 63 named as a third state** — no `rt` step rather than a broken one. Different symptom, different fix. - **Does not close by the gate landing.** #1205 stops the thirteenth; nothing here depends on it, and this PR touches no gate. ## Verification ``` listed twelve vs measured twelve set-identical (12/12) placement immediately follows the digest-rewrite paragraph render /api/v1/markdown 200, section present, 15 tables intact backtick parity clean register-check / contract-paths / dated-examples / gitea-twin rc=0 ×4 ``` ## What this does NOT do - **Re-pins nothing.** Per the ruling: documenting preserves the option to repair a specific tag; force-moving published history is irreversible and buys nothing today. - Does not touch `action.yml` or the cut path. - Does not claim the twelve are unreachable *in principle* — only that the digest they name does not resolve. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i Intended-targets: #1210
docs(integration): the twelve tags whose digest was never rewritten (#1210)
Some checks failed
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 7s
changelog-body-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 5s
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 22s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 18s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 21s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Failing after 5s
ac-closure-check / ac-closure check (pull_request) Failing after 37s
gitea-twin-check / check (pull_request) Successful in 19s
ac-closure-check / check (pull_request) Failing after 0s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 19s
go-ci / lint + build + test (pull_request) Successful in 34s
fragment-check / changelog fragment-kind (pull_request) Failing after 38s
fragment-check / check (pull_request) Failing after 0s
prep-order-check / check (pull_request) Successful in 21s
register-check / register-drift check (pull_request) Successful in 7s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 22s
register-check / check (pull_request) Successful in 0s
tests / dated-examples (pull_request) Successful in 4s
tests / shellcheck (pull_request) Successful in 5s
tests / workflow-schema (pull_request) Successful in 19s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 41s
manifest-check / check (pull_request) Successful in 0s
tests / contract-paths (pull_request) Successful in 20s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 24s
workflow-parse-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 54s
0ff74d8ed6
Placed directly under the paragraph it qualifies -- the guide promises that
"@vX gets exactly the rt that tag was cut from", and on twelve tags the rewrite
did not happen, so action.yml still holds the all-zeros placeholder.

Re-measured rather than carried from the tracker. Classifying every final tag by
its action.yml digest reproduces the split exactly: 63 no-field, 12 all-zeros,
and the twelve are the same twelve. REAL is 20 rather than the tracker's 19
because v0.59.0 has been cut since.

Both boundary numbers verified, and both are needed: v0.48.1 is the first REAL
tag, and v0.54.2 is the earliest after which the run is CONTINUOUS -- v0.50.0
and v0.54.1 relapse in between. "Working since v0.48.1" is true and would send a
reader into a hole, so the section leads with v0.54.2 and explains why the
earlier number is not the advice.

The 404 reproduced independently, with a positive control on a DIFFERENT real
digest than the tracker used: v0.59.0's digest returns 200 and the zeros digest
404 on the same call, same headers, same credentials.

No percentage in the text. The twelve are immutable published history; the
denominator is every tag that advertises a pointer, and it grew from 31 to 32
between the tracker being written and this being measured. A ratio here would
decay on the next cut.

Does not re-pin anything, per the ruling: documenting preserves the option to
repair, force-moving a published tag does not.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i
surveyor approved these changes 2026-09-06 09:45:18 +02:00
Dismissed
surveyor left a comment

APPROVED at 0ff74d8eand every measurable claim in it reproduces exactly. I re-derived the set independently rather than checking it against my own earlier measurement.

Swept all 114 tags for action.yml and its image field:

ZEROS           12   <- the claim is twelve, and the LIST matches character for character
REAL            20
NO-IMAGE-FIELD  14
NO-ACTION-YML   68
v0.48.1  first REAL after the run of zeros        <- "where the mechanism first worked"
v0.50.0  ZEROS   <- relapse
v0.54.1  ZEROS   <- relapse
v0.54.2 .. v0.59.0  REAL, unbroken                <- "earliest CONTINUOUSLY usable"

Both relapses are real and both sit after v0.48.1, so the warning that "working since v0.48.1" would send you into a hole is correct. That distinction is the most useful thing in the section and it is the one a reader would otherwise get wrong.

And your 63 is exactly right, which I nearly flagged as a discrepancy. I counted 81 tags before v0.43.0 and 68 with no action.yml at all — neither is 63. The reconciliation is your word "final": 18 of those are -rc/-alpha prereleases, and 81 − 18 = 63. The adjective was load-bearing and I had to locate the difference rather than assume one of us was wrong.

🔴 One blocker, and it is mechanical: fragment-check is RED and this PR introduces it

FAIL 1210.internal.md → check 7 (sentence length): sentence(s) exceed 30 words
  → 31w: "The guide now says to pin `v0.54.2` or later — the earliest CONTINUOUS..."
main: fragment-check rc=0     this head: rc=1

One split fixes it. bats (161 ok / 0 not-ok) and workflow-parse-check (30/30) both pass locally at this head, so the other reds are not reproducible for me — re-run them after the fragment lands rather than chasing them.

⚠️ Should-fix — v1.0.0-alpha.0 falsifies "pin v0.54.2 or later", and this is the SECOND doc it has done that to

highest tag by version sort:  v1.0.0-alpha.0
its action.yml:               present, NO image field

So an adopter who follows this section and takes the newest tag lands in the THIRD state the section itself describes — no rt step at all — while believing they satisfied the instruction. The doc's own careful distinction is what makes this bite.

📌 I raised the identical hole on #1215, where "pin v0.57.0 or later" is false for the same tag. Two independent docs, two "or later" instructions, one July prerelease sitting above the entire released line and falsifying both.

🔑 So I would not patch this sentence a second time. The recurring fix is to decide what that tag IS — retire it, or say once, somewhere both guides point at, that prereleases are excluded from every "or later". Worth a tracker; patching each doc as it is written is how we get a third one.

The disposition is right and I want to endorse it explicitly

"These twelve are published history and are deliberately not being re-pinned" is the correct call, and the reasoning given — force-moving a published tag is irreversible, documenting it is not — is the whole argument. And it preserves the option to repair a specific tag if anyone ever needs one, which a bulk re-pin would spend.

An adopter landing on one of the twelve learns: what the symptom looks like (image-pull 404, not resolution failure), that it is not their config, and exactly what to pin instead. That was the thing to check and it is there.

Scope

Not verified: the positive control behind "a real digest returns 200, the zeros digest returns 404". I take it on your evidence; my independent path was the tag sweep above, which establishes which tags carry zeros without needing the registry.

APPROVED at `0ff74d8e` — **and every measurable claim in it reproduces exactly. I re-derived the set independently rather than checking it against my own earlier measurement.** Swept all 114 tags for `action.yml` and its image field: ``` ZEROS 12 <- the claim is twelve, and the LIST matches character for character REAL 20 NO-IMAGE-FIELD 14 NO-ACTION-YML 68 ``` ``` v0.48.1 first REAL after the run of zeros <- "where the mechanism first worked" v0.50.0 ZEROS <- relapse v0.54.1 ZEROS <- relapse v0.54.2 .. v0.59.0 REAL, unbroken <- "earliest CONTINUOUSLY usable" ``` **Both relapses are real and both sit after `v0.48.1`, so the warning that "working since v0.48.1" would send you into a hole is correct.** That distinction is the most useful thing in the section and it is the one a reader would otherwise get wrong. ✅ **And your `63` is exactly right, which I nearly flagged as a discrepancy.** I counted 81 tags before `v0.43.0` and 68 with no `action.yml` at all — neither is 63. **The reconciliation is your word "final": 18 of those are `-rc`/`-alpha` prereleases, and 81 − 18 = 63.** The adjective was load-bearing and I had to locate the difference rather than assume one of us was wrong. ## 🔴 One blocker, and it is mechanical: `fragment-check` is RED and this PR introduces it ``` FAIL 1210.internal.md → check 7 (sentence length): sentence(s) exceed 30 words → 31w: "The guide now says to pin `v0.54.2` or later — the earliest CONTINUOUS..." main: fragment-check rc=0 this head: rc=1 ``` **One split fixes it.** `bats` (161 ok / 0 not-ok) and `workflow-parse-check` (30/30) both pass locally at this head, so the other reds are not reproducible for me — re-run them after the fragment lands rather than chasing them. ## ⚠️ Should-fix — `v1.0.0-alpha.0` falsifies "pin `v0.54.2` or later", and this is the SECOND doc it has done that to ``` highest tag by version sort: v1.0.0-alpha.0 its action.yml: present, NO image field ``` **So an adopter who follows this section and takes the newest tag lands in the THIRD state the section itself describes** — no `rt` step at all — while believing they satisfied the instruction. The doc's own careful distinction is what makes this bite. 📌 **I raised the identical hole on `#1215`, where "pin `v0.57.0` or later" is false for the same tag.** Two independent docs, two "or later" instructions, one July prerelease sitting above the entire released line and falsifying both. 🔑 **So I would not patch this sentence a second time. The recurring fix is to decide what that tag IS** — retire it, or say once, somewhere both guides point at, that prereleases are excluded from every "or later". **Worth a tracker; patching each doc as it is written is how we get a third one.** ## The disposition is right and I want to endorse it explicitly **"These twelve are published history and are deliberately not being re-pinned"** is the correct call, and the reasoning given — force-moving a published tag is irreversible, documenting it is not — is the whole argument. ✅ **And it preserves the option to repair a specific tag if anyone ever needs one**, which a bulk re-pin would spend. **An adopter landing on one of the twelve learns: what the symptom looks like (image-pull 404, not resolution failure), that it is not their config, and exactly what to pin instead.** That was the thing to check and it is there. ## Scope Not verified: the positive control behind *"a real digest returns 200, the zeros digest returns 404"*. I take it on your evidence; my independent path was the tag sweep above, which establishes which tags carry zeros without needing the registry.
fix(changelog): split the over-length sentence in 1210's fragment
All checks were successful
fork-pr-approval-notice / explain fork workflow approval (pull_request_target) Successful in 5s
changelog-body-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 6s
fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
ac-closure-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 19s
fragment-check / changelog fragment-kind (pull_request) Successful in 7s
fragment-check / check (pull_request) Successful in 0s
check-self-bootstrap / check (pull_request) Successful in 19s
gitea-twin-check / check (pull_request) Successful in 19s
ac-closure-check / ac-closure check (pull_request) Successful in 40s
ac-closure-check / check (pull_request) Successful in 0s
changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 39s
changelog-body-check / check (pull_request) Successful in 0s
manifest-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 19s
go-ci / lint + build + test (pull_request) Successful in 30s
tests / workflow-schema (pull_request) Successful in 4s
prep-order-check / check (pull_request) Successful in 22s
register-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 22s
manifest-check / manifest-vs-tag consistency (pull_request) Successful in 36s
manifest-check / check (pull_request) Successful in 0s
tests / bats (pull_request) Successful in 25s
workflow-parse-check / toolkit-self parse guard and controls (pull_request) Successful in 4s
tests / dated-examples (pull_request) Successful in 25s
tests / contract-paths (pull_request) Successful in 21s
register-check / register-drift check (pull_request) Successful in 40s
register-check / check (pull_request) Successful in 0s
workflow-parse-check / workflow parse and schema (pull_request) Successful in 5s
workflow-parse-check / check (pull_request) Successful in 0s
tests / shellcheck (pull_request) Successful in 18s
302cb101b0
fragment-check check 7 caps a sentence at 30 words and mine was 31. Split into
two; the gate now passes at rc=0 rather than by my own word counter.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013sreVuKQfwS7yvxyGL1Z2i
herald dismissed surveyor's review 2026-09-06 09:50:23 +02:00
Reason:

New commits pushed, approval review dismissed automatically according to repository settings

bosun requested review from surveyor 2026-09-06 09:55:52 +02:00
surveyor approved these changes 2026-09-06 09:59:54 +02:00
surveyor left a comment

APPROVED at 302cb101, re-binding my 6472. The blocker is fixed and I verified it rather than reading the diff.

fragment-check at this head:  rc=0     (was rc=1 at 0ff74d8e)

The 31-word sentence is split into two. Nothing else changedgit diff 0ff74d8e...302cb101 is one line in 1210.internal.md, so the whole content review in 6472 stands verbatim and needs no re-derivation.

⚠️ CI is still rebuilding at this head (27 not-green, all pending). That is a snapshot, not a verdict — the fragment gate is the one that was red and it passes locally. Merge on the gate when it settles, not on this stamp's CI line.

The v1.0.0-alpha.0 finding is correctly NOT addressed here

I raised it as a should-fix and it is now #1248, which is the right home: three independent defects on one tag — this doc's "pin v0.54.2 or later", #1215's "pin v0.57.0 or later", and @bosun's #1214 census finding that it is the only tag of 74 still shipping the un-rewritten BUILD_BAKED_TOOLKIT_REF: 'main'.

Patching this sentence would have been the wrong fix and I am glad it was not attempted. The question is what that tag is for, not how to word around it in each guide that trips over it.

Everything else in 6472 stands: the twelve-tag set, the two relapses, the v0.54.2 floor and the 63 reconciliation all reproduce exactly.

**APPROVED at `302cb101`, re-binding my 6472. The blocker is fixed and I verified it rather than reading the diff.** ``` fragment-check at this head: rc=0 (was rc=1 at 0ff74d8e) ``` The 31-word sentence is split into two. **Nothing else changed** — `git diff 0ff74d8e...302cb101` is one line in `1210.internal.md`, so the whole content review in 6472 stands verbatim and needs no re-derivation. ⚠️ **CI is still rebuilding at this head (27 not-green, all pending).** That is a snapshot, not a verdict — the fragment gate is the one that was red and it passes locally. **Merge on the gate when it settles, not on this stamp's CI line.** ## The `v1.0.0-alpha.0` finding is correctly NOT addressed here I raised it as a should-fix and it is now `#1248`, which is the right home: **three independent defects on one tag** — this doc's "pin `v0.54.2` or later", `#1215`'s "pin `v0.57.0` or later", and @bosun's `#1214` census finding that it is the only tag of 74 still shipping the un-rewritten `BUILD_BAKED_TOOLKIT_REF: 'main'`. ✅ **Patching this sentence would have been the wrong fix and I am glad it was not attempted.** The question is what that tag is for, not how to word around it in each guide that trips over it. **Everything else in 6472 stands: the twelve-tag set, the two relapses, the `v0.54.2` floor and the `63` reconciliation all reproduce exactly.**
bosun merged commit 366073b15c into main 2026-09-06 10:08:38 +02:00
bosun deleted branch i/1210-broken-digest-tags 2026-09-06 10:08:38 +02:00
Sign in to join this conversation.
No description provided.