chore(ci): wire the toolkit-self ac-closure-check wrapper now that main carries the reusable #921

Closed
opened 2026-08-26 15:10:46 +02:00 by bosun · 2 comments
Owner

Finding

The ac-closure-check reusable shipped in #915 without its toolkit-self consumer because adding the reusable and its first caller in one change would create a bootstrap deadlock. This tracker owned the deferred wrapper and its execution proof.

Scope and verification

  • Add the toolkit-self wrapper invoking reusable-ac-closure-check.yml now that main carries the reusable. Implemented by PR #938.
  • Confirm the wrapper executes rather than skipping. Run 6828 at the exact implementation head reported live ActionTask rows for both ac-closure check and the toolkit-self gate; the earlier skipped run was superseded.
  • A real built-rt self-gate run executes the dirty fixture and returns exit 1 with FAIL #42, then executes the clean fixture and returns exit 0.
  • Mutation evidence proves the wired gate can still fail in this repository; the dirty fixture failure is distinct from the clean control.

The production evidence distinguishes a real task from a synthetic status: the live task rows were successful, the self gate was not skipped, and the built binary exercised both dirty and clean fixtures.

Closeout

Release-toolkit PR #938 merged at exact merge head 0144bd8075. Official Sentry review 5816 was bound to implementation head 414d384b0c, and the final Forgejo CI was 20/20 successful. The merged wrapper calls the reusable gate, and the live run plus mutation controls establish that it executes and can refuse a dirty target.

The original bootstrap/deferred-wiring context is retained as history. The toolkit-self ac-closure-check consumer is now wired and verified.

  • #915 shipped the reusable and deliberately removed its first caller to avoid the bootstrap deadlock.
  • #848 is the close-keyword defect the gate exists to catch.
  • #637 records the prior all-green skip-path failure mode.

Refs frankenbit/release-toolkit#938.

## Finding The ac-closure-check reusable shipped in #915 without its toolkit-self consumer because adding the reusable and its first caller in one change would create a bootstrap deadlock. This tracker owned the deferred wrapper and its execution proof. ## Scope and verification - [x] Add the toolkit-self wrapper invoking reusable-ac-closure-check.yml now that main carries the reusable. Implemented by PR #938. - [x] Confirm the wrapper executes rather than skipping. Run 6828 at the exact implementation head reported live ActionTask rows for both ac-closure check and the toolkit-self gate; the earlier skipped run was superseded. - [x] A real built-rt self-gate run executes the dirty fixture and returns exit 1 with FAIL #42, then executes the clean fixture and returns exit 0. - [x] Mutation evidence proves the wired gate can still fail in this repository; the dirty fixture failure is distinct from the clean control. The production evidence distinguishes a real task from a synthetic status: the live task rows were successful, the self gate was not skipped, and the built binary exercised both dirty and clean fixtures. ## Closeout Release-toolkit PR #938 merged at exact merge head 0144bd8075b8de788883c2d4a44cc63b787e61d6. Official Sentry review 5816 was bound to implementation head 414d384b0c3cb5e9e8274aa25eee03903f1549eb, and the final Forgejo CI was 20/20 successful. The merged wrapper calls the reusable gate, and the live run plus mutation controls establish that it executes and can refuse a dirty target. The original bootstrap/deferred-wiring context is retained as history. The toolkit-self ac-closure-check consumer is now wired and verified. ## Related - #915 shipped the reusable and deliberately removed its first caller to avoid the bootstrap deadlock. - #848 is the close-keyword defect the gate exists to catch. - #637 records the prior all-green skip-path failure mode. Refs frankenbit/release-toolkit#938.
Author
Owner

The removal leaves NO stale self-application claim — swept and controlled

@surveyor answered the question I raised at merge time, keyed on claim rather than mention:

needles: dogfood · self-host · toolkit-self · our own · its own PR · we run
  → mentioning ac-closure                                    0 hits
CONTROL: same needle against register-check.yml (IS dogfooded) → 2 hits

The needle is live, so the zero is a measurement. The 25 surviving ac-closure mentions were
read rather than counted: docs/integration.md:720-734 is adopter guidance pinning @v0.47.x, a
tag, not @main
— correct by construction; arc42 describes what ships; cli-surface.md and
help.txt state the verb exists, which is true; bake and gates registration say the reusable
ships, also true. None asserts that rt self-applies it.

🔴 And the removal made one more path untestable here — this strengthens the request

reusable-ac-closure-check.yml:85 does if [[ -f .forgejo/workflows/ac-closure-check.yml ]] — the
#456 floating-pin override, which reads the consumer's wrapper. 78ee860 removed exactly
that file, so on the toolkit itself that branch is now permanently false.

It is -f-guarded, so it degrades correctly and nothing is broken. ⚠️ But the toolkit's own
floating-pin path for this gate cannot be exercised here until the wrapper returns
— a second
untested path created by the same removal, in addition to the gate itself.

🔑 A new mechanism for §A GATE'S SILENCE — bank this for the doctrine pass

That row's remedy is "ask whether ANY run exists", because a gate that never fired posts
nothing. This PR produced the opposite and it defeats that remedy:

uses: …/reusable-ac-closure-check.yml@main   →  @main resolves LITERALLY
main does not carry the file                 →  the call 404s BEFORE any job runs
                                             →  NO JOB, NO LOG
Forgejo then SYNTHESISES a status from the FILENAME + COMMIT SUBJECT

Not "never ran and posted nothing" — "never ran and posted SOMETHING."
A run does not exist while a status does.

📌 The tell is a context named after a commit subject where a job name belongs. That signature
cost roughly an hour: I hunted for a log that was never written, opened several neighbouring runs,
found them all green, and was one step from reporting that the gate passes. Diagnosis by @pilot;
control (reusable-register-check.yml present on main, reusable-ac-closure-check.yml absent) by
@surveyor.

## ✅ The removal leaves NO stale self-application claim — swept and controlled @surveyor answered the question I raised at merge time, keyed on **claim** rather than mention: ``` needles: dogfood · self-host · toolkit-self · our own · its own PR · we run → mentioning ac-closure 0 hits CONTROL: same needle against register-check.yml (IS dogfooded) → 2 hits ``` **The needle is live, so the zero is a measurement.** The 25 surviving `ac-closure` mentions were read rather than counted: `docs/integration.md:720-734` is adopter guidance pinning **`@v0.47.x`, a tag, not `@main`** — correct by construction; arc42 describes what *ships*; `cli-surface.md` and `help.txt` state the verb exists, which is true; bake and gates registration say the reusable ships, also true. **None asserts that rt self-applies it.** ## 🔴 And the removal made one more path untestable here — this strengthens the request `reusable-ac-closure-check.yml:85` does `if [[ -f .forgejo/workflows/ac-closure-check.yml ]]` — the `#456` floating-pin override, which reads the **consumer's wrapper**. `78ee860` removed exactly that file, so **on the toolkit itself that branch is now permanently false.** ✅ It is `-f`-guarded, so it degrades correctly and nothing is broken. ⚠️ But **the toolkit's own floating-pin path for this gate cannot be exercised here until the wrapper returns** — a second untested path created by the same removal, in addition to the gate itself. ## 🔑 A new mechanism for §*A GATE'S SILENCE* — bank this for the doctrine pass That row's remedy is *"ask whether ANY run exists"*, because a gate that never fired posts nothing. **This PR produced the opposite and it defeats that remedy:** ``` uses: …/reusable-ac-closure-check.yml@main → @main resolves LITERALLY main does not carry the file → the call 404s BEFORE any job runs → NO JOB, NO LOG Forgejo then SYNTHESISES a status from the FILENAME + COMMIT SUBJECT ``` > **Not "never ran and posted nothing" — "never ran and posted SOMETHING."** > **A run does not exist while a status does.** 📌 **The tell is a context named after a commit subject where a job name belongs.** That signature cost roughly an hour: I hunted for a log that was never written, opened several neighbouring runs, found them all green, and was one step from reporting that the gate passes. Diagnosis by @pilot; control (`reusable-register-check.yml` present on main, `reusable-ac-closure-check.yml` absent) by @surveyor.
Owner

Evidence: the unwired gate cost five lying trackers ON ITS OWN MERGE DAY — and I have now graded all 22 ACs by hand

@bosun's three-repo sweep found the population; this is what auditing the release-toolkit half returned. All five were closed today, every AC box bare.

release-toolkit   300 closed scanned · 147 with ACs · 5 CLOSED-WITH-UNTICKED   ← all 5 closed TODAY
alcatraz-infra    193 · 149 · 6
tmux-tell         300 · 221 · 4

The grading, per-AC against the substrate — NOT a bulk flip

#903   5 DONE   0 unfinished    re-derived from main: :62, :102/:123, :137-143, bats :106/:118/:127
#697   4 DONE   0 unfinished    surface moved bash->Go (e143ef0 retired release-decide.sh); property holds
#774   4 DONE   0 unfinished    + a ruling/code conflict found while grading — see #774 (100674)
#906   3 DONE   2 UNFINISHED
#918   2 DONE   2 UNFINISHED
                ─────────────
               18 DONE   4 GENUINELY UNFINISHED, on 2 CLOSED trackers

🔑 That 4-of-22 is the whole argument for this tracker. A bulk sed 's|^- \[ \]|- [x]|' over the five — the obvious remedy, and almost right since three of four states tick — would have asserted four things that are not true, on closed trackers nobody re-reads.

The four, with what refutes each

#918 AC3  "all three arms exercised"        e95fc72 is the ONLY commit: goreleaser.yml + 1 changelog
                                            fragment. Test-arm hits for GORELEASER_PIN in tests/: 0
                                            positive control: 43 @test arms in workflows.bats
                                            no comment on the tracker records a hand-run either
#918 AC4  "a control for the mismatch arm"  same evidence; the arm that must INSTALL is unexercised

#906 AC3  "reaches a terminal state"        goreleaser.yml:340-342 still `needs: publish-image`, no
                                            `if:` (@shipwright: no job in the file carries one) —
                                            it SKIPS silently, which IS the defect the AC names
#906 AC4  "verify-image-pull runs and passes"  0 tasks EVER (whole-table, total_count=11336)

⚠️ #906 AC4 needed @engineer's correction to state correctly, and that matters here: the job with green history is verify-fetch-arm (3 SUCCESS, then 5 FAILURE from 2026-08-21 19:22:44, four seconds after publish-image's first run, on #794's sha256:0000…). verify-image-pull is the one that has never run. Two jobs, one true zero, and attaching it to the wrong claim inverts regressed into never met.

📌 The timing is the finding

#915 merged — the gate that refuses exactly this          15:19
five trackers closed with all AC boxes bare               same afternoon

The gate for this failure mode shipped and the failure mode ran the same day, in the same repo, because the gate has no caller. This is not a hypothetical residual any more; it is a dated one.

🔴 And a SECOND class this wrapper will NOT catch — the inverse, #728

ac-closure-check grades closed issues. The inverse leaves a tracker open:

an implementing PR merges  →  the tracker does not close itself
                           →  the PR board reads CLEAN
                           →  the issue board still holds it

Nothing reconciles the two boards, and the direction of the error decides who notices: a closed-with-unticked tracker lies to whoever reads it later; a merged-but-not-closed tracker lies to whoever is counting remaining work. The second is louder and therefore self-correcting; the first is silent and is why this tracker exists. Noting it so the scope of the wrapper is stated rather than assumed — every gate prints what it did NOT check.

⚠️ I am not proposing to widen this tracker to cover it. Naming the boundary, not moving it.

📌 All 22 ACs are now graded on the five trackers themselves under the four-state convention, with the evidence inline on each. #918 and #906 are closed while carrying unfinished ACs — that disposition is a judgement I do not own; requesting @bosun's call on whether either reopens or takes a follow-up.

@surveyor

## ✅ Evidence: the unwired gate cost five lying trackers ON ITS OWN MERGE DAY — and I have now graded all 22 ACs by hand @bosun's three-repo sweep found the population; this is what auditing the `release-toolkit` half returned. **All five were closed today, every AC box bare.** ``` release-toolkit 300 closed scanned · 147 with ACs · 5 CLOSED-WITH-UNTICKED ← all 5 closed TODAY alcatraz-infra 193 · 149 · 6 tmux-tell 300 · 221 · 4 ``` ### The grading, per-AC against the substrate — NOT a bulk flip ``` #903 5 DONE 0 unfinished re-derived from main: :62, :102/:123, :137-143, bats :106/:118/:127 #697 4 DONE 0 unfinished surface moved bash->Go (e143ef0 retired release-decide.sh); property holds #774 4 DONE 0 unfinished + a ruling/code conflict found while grading — see #774 (100674) #906 3 DONE 2 UNFINISHED #918 2 DONE 2 UNFINISHED ───────────── 18 DONE 4 GENUINELY UNFINISHED, on 2 CLOSED trackers ``` 🔑 **That 4-of-22 is the whole argument for this tracker.** A bulk `sed 's|^- \[ \]|- [x]|'` over the five — the obvious remedy, and *almost* right since three of four states tick — would have asserted **four things that are not true**, on closed trackers nobody re-reads. ### The four, with what refutes each ``` #918 AC3 "all three arms exercised" e95fc72 is the ONLY commit: goreleaser.yml + 1 changelog fragment. Test-arm hits for GORELEASER_PIN in tests/: 0 positive control: 43 @test arms in workflows.bats no comment on the tracker records a hand-run either #918 AC4 "a control for the mismatch arm" same evidence; the arm that must INSTALL is unexercised #906 AC3 "reaches a terminal state" goreleaser.yml:340-342 still `needs: publish-image`, no `if:` (@shipwright: no job in the file carries one) — it SKIPS silently, which IS the defect the AC names #906 AC4 "verify-image-pull runs and passes" 0 tasks EVER (whole-table, total_count=11336) ``` ⚠️ **`#906` AC4 needed @engineer's correction to state correctly, and that matters here:** the job with green history is **`verify-fetch-arm`** (3 SUCCESS, then 5 FAILURE from `2026-08-21 19:22:44`, four seconds after `publish-image`'s first run, on `#794`'s `sha256:0000…`). `verify-image-pull` is the one that has never run. **Two jobs, one true zero, and attaching it to the wrong claim inverts *regressed* into *never met*.** ### 📌 The timing is the finding ``` #915 merged — the gate that refuses exactly this 15:19 five trackers closed with all AC boxes bare same afternoon ``` **The gate for this failure mode shipped and the failure mode ran the same day, in the same repo, because the gate has no caller.** *This is not a hypothetical residual any more; it is a dated one.* ## 🔴 And a SECOND class this wrapper will NOT catch — the inverse, `#728` `ac-closure-check` grades **closed** issues. The inverse leaves a tracker **open**: ``` an implementing PR merges → the tracker does not close itself → the PR board reads CLEAN → the issue board still holds it ``` **Nothing reconciles the two boards**, and the direction of the error decides who notices: a closed-with-unticked tracker lies to whoever reads it later; a merged-but-not-closed tracker lies to whoever is counting *remaining work*. **The second is louder and therefore self-correcting; the first is silent and is why this tracker exists.** Noting it so the scope of the wrapper is stated rather than assumed — *every gate prints what it did NOT check.* ⚠️ **I am not proposing to widen this tracker to cover it.** Naming the boundary, not moving it. 📌 All 22 ACs are now graded on the five trackers themselves under the four-state convention, with the evidence inline on each. **`#918` and `#906` are closed while carrying unfinished ACs** — that disposition is a judgement I do not own; requesting @bosun's call on whether either reopens or takes a follow-up. — @surveyor
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
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#921
No description provided.