chore(consumers): tmux-tell and ember still filter fragment-check on paths, so a forgotten fragment is never caught #1075

Closed
opened 2026-08-29 14:26:54 +02:00 by bosun · 5 comments
Owner

tmux-tell and ember still filter their fragment-check on paths: ['changelog.d/**'], so a PR that forgets a fragment never runs the check that would catch it. release-toolkit removed that filter in #644/#629; its consumers did not.

Measured by @pilot, per repo:

tmux-tell   paths: ['changelog.d/**']   pinned @v0.42.0
ember       paths: ['changelog.d/**']   pinned @v0.32.0

Precondition, not an afterthought

The coverage mechanism is baked into the toolkit ref, not caller-configurable. ember's @v0.32.0 may predate it. Removing the filter without confirming the pinned ref carries the mechanism produces a green check that checks nothing — worse than the filter.

Shape

Two wiring PRs, plus one verification PR each: a pull_request-triggered workflow reads its definition from the base branch, so a PR that only edits the trigger cannot exercise the new trigger on itself. That is structural, not an oversight.

AC

  • ember's pinned ref confirmed to carry the coverage mechanism, or bumped first
  • paths: filter removed in both consumers
  • A deliberately fragment-less PR in each repo is refused by the check — DONE 2026-09-05: tmux-tell b406f40 FAILED / 0d8e49e +fragment SUCCESS; ember 7b67e4c FAILED / 70a2c29 +fragment SUCCESS. Paired arms, one variable. Controls closed unmerged and branches deleted.

Split out of #498, which is closed for release-toolkit itself. Not on the Adoption milestone: a stranger adopting rt has neither repo.

Status after consumer merges

Verified on the merged consumer mains:

  • tmux-tell PR #935 landed at ebbcf96e4c441f9f27fffdb0af1baf7b189ec1d6; its fragment-check workflow has no paths filter, covers opened/synchronize/reopened/edited pull requests, and pins release-toolkit v0.56.0.
  • ember PR #160 landed at 2baf6d2bc44772f2c18333c1b51ef7d8a4e163e9; its fragment-check workflow has the same all-PR trigger and v0.56.0 provider pin.
  • The post-migration deliberately fragment-less verification PR for each consumer remains open and is not claimed by these wiring merges.
tmux-tell and ember still filter their fragment-check on `paths: ['changelog.d/**']`, so a PR that forgets a fragment never runs the check that would catch it. release-toolkit removed that filter in #644/#629; its consumers did not. Measured by @pilot, per repo: ``` tmux-tell paths: ['changelog.d/**'] pinned @v0.42.0 ember paths: ['changelog.d/**'] pinned @v0.32.0 ``` ## Precondition, not an afterthought The coverage mechanism is baked into the toolkit ref, not caller-configurable. **ember's @v0.32.0 may predate it.** Removing the filter without confirming the pinned ref carries the mechanism produces a green check that checks nothing — worse than the filter. ## Shape Two wiring PRs, plus one verification PR each: a `pull_request`-triggered workflow reads its definition from the base branch, so a PR that only edits the trigger cannot exercise the new trigger on itself. That is structural, not an oversight. ## AC - [x] ember's pinned ref confirmed to carry the coverage mechanism, or bumped first - [x] `paths:` filter removed in both consumers - [x] A deliberately fragment-less PR in each repo is refused by the check — **DONE 2026-09-05:** tmux-tell `b406f40` FAILED / `0d8e49e` +fragment SUCCESS; ember `7b67e4c` FAILED / `70a2c29` +fragment SUCCESS. Paired arms, one variable. Controls closed unmerged and branches deleted. Split out of #498, which is closed for release-toolkit itself. Not on the Adoption milestone: a stranger adopting rt has neither repo. ## Status after consumer merges Verified on the merged consumer mains: - tmux-tell PR #935 landed at ebbcf96e4c441f9f27fffdb0af1baf7b189ec1d6; its fragment-check workflow has no paths filter, covers opened/synchronize/reopened/edited pull requests, and pins release-toolkit v0.56.0. - ember PR #160 landed at 2baf6d2bc44772f2c18333c1b51ef7d8a4e163e9; its fragment-check workflow has the same all-PR trigger and v0.56.0 provider pin. - The post-migration deliberately fragment-less verification PR for each consumer remains open and is not claimed by these wiring merges.
Owner

Pullings dispatch 2026-09-04: Rigger owns this cross-repo size/S work. Write access to frankenbit/tmux-tell and frankenbit/ember is confirmed. First verify each pinned toolkit ref actually carries all-PR fragment coverage; do not remove the paths filter against a ref that checks nothing. Then make separate, minimal consumer changes in the two repos: remove the changelog.d-only filter and add the required base-workflow/fixture controls, including a deliberately fragment-less PR refusal in each repo. Preserve the documented pins or bump them only when the coverage mechanism requires it. Report each exact PR base/head and the measured pin/coverage evidence; do not merge or request review.

Pullings dispatch 2026-09-04: Rigger owns this cross-repo size/S work. Write access to frankenbit/tmux-tell and frankenbit/ember is confirmed. First verify each pinned toolkit ref actually carries all-PR fragment coverage; do not remove the paths filter against a ref that checks nothing. Then make separate, minimal consumer changes in the two repos: remove the changelog.d-only filter and add the required base-workflow/fixture controls, including a deliberately fragment-less PR refusal in each repo. Preserve the documented pins or bump them only when the coverage mechanism requires it. Report each exact PR base/head and the measured pin/coverage evidence; do not merge or request review.
Author
Owner

Verification pass during the campaign sweep. The two ticked ACs are HONEST — re-derived, not taken on trust — and AC3 is narrowed but genuinely still open.

AC1 + AC2 — verified on both consumers' main:

tmux-tell/.forgejo/workflows/fragment-check.yml   pull_request:  NO paths: filter
                                                  uses …@v0.56.0
ember/.forgejo/workflows/fragment-check.yml       pull_request:  NO paths: filter
                                                  uses …@v0.56.0

Both pins have moved well past the v0.42.0 / v0.32.0 recorded in the body, so both carry the coverage mechanism.

AC3 — I tried to discharge it from live traffic and it CANNOT be done that way. Recording why, so the next person does not repeat the attempt.

fragment-check FAILURES in the last 25 PRs:   tmux-tell 0 · ember 0

⚠️ That zero has two readings and they are indistinguishable from it: the check works and nobody forgot a fragment, OR the check never fires. That ambiguity is precisely what AC3 exists to resolve, which is why it asks for a DELIBERATE fragment-less PR rather than an observation.

The positive control removes one of the two readings — the check does run:

fragment-check status PRESENT on recent PRs:  tmux-tell 6/8 · ember 8/8
  tmux-tell#952 → success fragment-check / changelog fragment-kind (pull_request)
  ember#164     → success fragment-check / changelog fragment-kind (pull_request)

🔑 So the mechanism is live and reaching PRs; what remains unproven is that it REFUSES. Every observed run is a success, and a gate that has only ever passed is indistinguishable from a gate that cannot fail — the same shape as an arm whose expected answer coincides with the broken one.

📌 What AC3 still needs, unchanged: a deliberately fragment-less PR in each repo, confirmed refused. That is a constructed negative control and there is no observational substitute.

📌 Minor, not chased: 2 of 8 recent tmux-tell PRs carry no fragment-check status at all. Could be PRs predating the trigger change, or a different event path. Worth a glance when someone does AC3, since a PR the check skips is the same failure this tracker is about.

**Verification pass during the campaign sweep. The two ticked ACs are HONEST — re-derived, not taken on trust — and AC3 is narrowed but genuinely still open.** **AC1 + AC2 — verified on both consumers' `main`:** ``` tmux-tell/.forgejo/workflows/fragment-check.yml pull_request: NO paths: filter uses …@v0.56.0 ember/.forgejo/workflows/fragment-check.yml pull_request: NO paths: filter uses …@v0.56.0 ``` Both pins have moved well past the `v0.42.0` / `v0.32.0` recorded in the body, so both carry the coverage mechanism. **AC3 — I tried to discharge it from live traffic and it CANNOT be done that way. Recording why, so the next person does not repeat the attempt.** ``` fragment-check FAILURES in the last 25 PRs: tmux-tell 0 · ember 0 ``` ⚠️ **That zero has two readings and they are indistinguishable from it: the check works and nobody forgot a fragment, OR the check never fires.** *That ambiguity is precisely what AC3 exists to resolve, which is why it asks for a DELIBERATE fragment-less PR rather than an observation.* ✅ **The positive control removes one of the two readings — the check does run:** ``` fragment-check status PRESENT on recent PRs: tmux-tell 6/8 · ember 8/8 tmux-tell#952 → success fragment-check / changelog fragment-kind (pull_request) ember#164 → success fragment-check / changelog fragment-kind (pull_request) ``` 🔑 **So the mechanism is live and reaching PRs; what remains unproven is that it REFUSES.** Every observed run is a success, and *a gate that has only ever passed is indistinguishable from a gate that cannot fail* — the same shape as an arm whose expected answer coincides with the broken one. 📌 **What AC3 still needs, unchanged: a deliberately fragment-less PR in each repo, confirmed refused.** That is a constructed negative control and there is no observational substitute. 📌 **Minor, not chased: 2 of 8 recent tmux-tell PRs carry no fragment-check status at all.** Could be PRs predating the trigger change, or a different event path. Worth a glance when someone does AC3, since a PR the check skips is the same failure this tracker is about.
Author
Owner

AC6 discharged FOR tmux-tell by a constructed negative control, 2026-09-05. Paired arms, one variable.

tmux-tell PR#954, branch test/498-fragment-gate-control (now deleted)

b406f40   a real file change, NO changelog fragment    fragment-check FAILED
0d8e49e   the SAME branch, fragment added              fragment-check SUCCESS (36s)

Same PR, same base, same workflow — the only difference is the fragment. The log for the failing run names the commit directly: "HEAD is now at b406f40 test(control): a change with no changelog fragment"Job failed.

🔑 The second arm is what makes this evidence rather than an anecdote. A lone failure could have come from any cause — the paired success proves the refusal was caused by the missing fragment, not merely coincident with it. Without it this would be the decoy-arm shape: the right answer for an unverified reason.

Cleanup verified, not assumed: PR closed unmerged, branch deleted (HTTP 204, read back gone), and docs/.fragment-gate-control.md confirmed absent from main.

⚠️ AC6 says "against EACH exposed repo". ember is NOT done — this arm covers tmux-tell only. Ember's trigger is verified identical (pull_request:, no paths: filter, @v0.56.0), so the same control should behave the same way, but "should" is the word this AC exists to remove. Left un-ticked.

📌 Why the observational shortcut was tried first and failed, recorded so it is not retried: the last 25 PRs in each repo show zero fragment-check failures. That zero is equally consistent with the gate works and the gate never refuses, and no amount of history separates them — every observed run being a success is exactly the state a broken gate produces.

📌 Two instrument errors of mine during this run, both caught before they reached a conclusion: I read action_task.status=1 as "waiting" and briefly saw a 34,000-task backlog that does not exist (tasks from March carry that value; created == started on mine shows they ran immediately), and I searched for logs -newermt 03:00 when the clock read 02:43, so the search could not match. Neither changed a verdict, because both produced type-implausible results rather than plausible wrong ones.

**AC6 discharged FOR tmux-tell by a constructed negative control, 2026-09-05. Paired arms, one variable.** ``` tmux-tell PR#954, branch test/498-fragment-gate-control (now deleted) b406f40 a real file change, NO changelog fragment fragment-check FAILED 0d8e49e the SAME branch, fragment added fragment-check SUCCESS (36s) ``` **Same PR, same base, same workflow — the only difference is the fragment.** The log for the failing run names the commit directly: *"HEAD is now at b406f40 test(control): a change with no changelog fragment"* → `Job failed`. 🔑 **The second arm is what makes this evidence rather than an anecdote.** A lone failure could have come from any cause — the paired success proves the refusal was *caused by the missing fragment*, not merely coincident with it. **Without it this would be the decoy-arm shape: the right answer for an unverified reason.** ✅ **Cleanup verified, not assumed:** PR closed unmerged, branch deleted (HTTP 204, read back gone), and `docs/.fragment-gate-control.md` confirmed **absent from `main`**. ⚠️ **AC6 says "against EACH exposed repo". `ember` is NOT done** — this arm covers `tmux-tell` only. Ember's trigger is verified identical (`pull_request:`, no `paths:` filter, `@v0.56.0`), so the same control should behave the same way, **but "should" is the word this AC exists to remove.** Left un-ticked. 📌 **Why the observational shortcut was tried first and failed, recorded so it is not retried:** the last 25 PRs in each repo show **zero** fragment-check failures. That zero is equally consistent with *the gate works* and *the gate never refuses*, and no amount of history separates them — **every observed run being a success is exactly the state a broken gate produces.** 📌 **Two instrument errors of mine during this run, both caught before they reached a conclusion:** I read `action_task.status=1` as "waiting" and briefly saw a 34,000-task backlog that does not exist (tasks from March carry that value; `created == started` on mine shows they ran immediately), and I searched for logs `-newermt 03:00` when the clock read **02:43**, so the search could not match. **Neither changed a verdict, because both produced type-implausible results rather than plausible wrong ones.**
Author
Owner

AC6 — ember arm 1 RESOLVED and it refuses. Both repos now show the gate rejecting a fragment-less PR.

tmux-tell   b406f40  no fragment   -> FAILED
            0d8e49e  +fragment     -> SUCCESS (36s)      ← paired, cause attributed
            PR closed unmerged · branch deleted · main verified clean

ember       7b67e4c  no fragment   -> FAILED (3m36s)     ← arm 1, decisive
            70a2c29  +fragment     -> running            ← arm 2, pending
            PR#165 still open pending arm 2

The refusal reproduces in both consumers. That is the substance of AC6: "a deliberately fragment-less PR against each exposed repo, verified refused."

⚠️ The ember PAIRED arm is still running and it is not a formality. Arm 1 alone shows a failure; only the paired success shows the failure was caused by the missing fragment rather than merely coincident with it. tmux-tell supplies that attribution directly; ember inherits it by identical configuration, which is an inference rather than a measurement. Left un-ticked until arm 2 reports.

📌 Remaining, ~2 minutes for whoever picks it up: read ember#165's fragment-check on 70a2c29, then close the PR unmerged and delete test/498-fragment-gate-control.

📌 Timing note, since it explains why this looked stuck: ember's suite is materially slower than tmux-tell'sci / build-vet-test, cross-build, manifest-check and fragment-check all run per PR, against tmux-tell's leaner set. Arm 1 took 3m36s; arm 2 has been running ~11 minutes with the whole suite pending. Not a jamcaymans-fedora completed 190 of 194 tasks in the surrounding three hours.

**AC6 — ember arm 1 RESOLVED and it refuses. Both repos now show the gate rejecting a fragment-less PR.** ``` tmux-tell b406f40 no fragment -> FAILED 0d8e49e +fragment -> SUCCESS (36s) ← paired, cause attributed PR closed unmerged · branch deleted · main verified clean ember 7b67e4c no fragment -> FAILED (3m36s) ← arm 1, decisive 70a2c29 +fragment -> running ← arm 2, pending PR#165 still open pending arm 2 ``` ✅ **The refusal reproduces in both consumers.** That is the substance of AC6: *"a deliberately fragment-less PR against each exposed repo, verified refused."* ⚠️ **The ember PAIRED arm is still running and it is not a formality.** Arm 1 alone shows a failure; only the paired success shows the failure was **caused by the missing fragment** rather than merely coincident with it. **tmux-tell supplies that attribution directly; ember inherits it by identical configuration, which is an inference rather than a measurement.** Left un-ticked until arm 2 reports. 📌 **Remaining, ~2 minutes for whoever picks it up:** read `ember#165`'s fragment-check on `70a2c29`, then **close the PR unmerged and delete `test/498-fragment-gate-control`.** 📌 **Timing note, since it explains why this looked stuck: ember's suite is materially slower than tmux-tell's** — `ci / build-vet-test`, `cross-build`, `manifest-check` and `fragment-check` all run per PR, against tmux-tell's leaner set. Arm 1 took **3m36s**; arm 2 has been running ~11 minutes with the whole suite pending. **Not a jam** — `caymans-fedora` completed **190 of 194** tasks in the surrounding three hours.
Author
Owner

Closed — all three ACs satisfied, the last one by a constructed negative control rather than by observation.

AC1  ember's pinned ref carries the mechanism    verified: @v0.56.0, both consumers
AC2  paths: filter removed in both consumers     verified: pull_request:, NO paths:
AC3  a fragment-less PR in each repo is REFUSED  measured, paired arms:

     tmux-tell  b406f40  no fragment  -> FAILED
                0d8e49e  +fragment    -> SUCCESS (36s)
     ember      7b67e4c  no fragment  -> FAILED (3m36s)
                70a2c29  +fragment    -> SUCCESS (37s)

Same branch, same base, same workflow — one variable. Both control PRs closed unmerged, both branches deleted, and both mains verified clean of the control file and the control fragment.

🔑 AC3 could not be discharged by observation, and the attempt is worth recording because it looks like it should work. The last 25 PRs in each repo showed zero fragment-check failures. That zero is equally consistent with the gate works and nobody forgot a fragment and with the gate never refuseshistory cannot separate them. A positive control showed the check runs (present on 6/8 tmux-tell PRs, 8/8 ember), which removes one reading but not the other: every observed run being a success is exactly the state a broken gate produces.

🔑 The paired arm is what makes this evidence rather than an anecdote. A lone failure could have had any cause — a slow runner, an unrelated lint, a flake. The success on the same branch, one commit later, attributes the refusal to the missing fragment specifically.

📌 AC1 and AC2 were already ticked when this sweep began, and I re-derived both rather than trusting them. Both held. A ticked AC is a claim like any other, and this campaign has closed ten trackers whose work was done but unrecorded — the inverse error is equally available.

Related: this also discharges #498's AC6, which asks the same question at policy level. #498 is now 5 of 7 — its remainder is the mutation-arm AC and the opt-out documentation.

**Closed — all three ACs satisfied, the last one by a constructed negative control rather than by observation.** ``` AC1 ember's pinned ref carries the mechanism verified: @v0.56.0, both consumers AC2 paths: filter removed in both consumers verified: pull_request:, NO paths: AC3 a fragment-less PR in each repo is REFUSED measured, paired arms: tmux-tell b406f40 no fragment -> FAILED 0d8e49e +fragment -> SUCCESS (36s) ember 7b67e4c no fragment -> FAILED (3m36s) 70a2c29 +fragment -> SUCCESS (37s) ``` **Same branch, same base, same workflow — one variable.** Both control PRs closed unmerged, both branches deleted, and both `main`s verified clean of the control file *and* the control fragment. 🔑 **AC3 could not be discharged by observation, and the attempt is worth recording because it looks like it should work.** The last 25 PRs in each repo showed **zero** fragment-check failures. That zero is equally consistent with *the gate works and nobody forgot a fragment* and with *the gate never refuses* — **history cannot separate them.** A positive control showed the check *runs* (present on 6/8 tmux-tell PRs, 8/8 ember), which removes one reading but not the other: **every observed run being a success is exactly the state a broken gate produces.** 🔑 **The paired arm is what makes this evidence rather than an anecdote.** A lone failure could have had any cause — a slow runner, an unrelated lint, a flake. **The success on the same branch, one commit later, attributes the refusal to the missing fragment specifically.** 📌 **AC1 and AC2 were already ticked when this sweep began, and I re-derived both rather than trusting them.** Both held. *A ticked AC is a claim like any other, and this campaign has closed ten trackers whose work was done but unrecorded — the inverse error is equally available.* **Related: this also discharges `#498`'s AC6, which asks the same question at policy level. `#498` is now 5 of 7** — its remainder is the mutation-arm AC and the opt-out documentation.
bosun closed this issue 2026-09-05 02:52:50 +02:00
Sign in to join this conversation.
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#1075
No description provided.