diff --git a/.gitea/workflows/checks.yml b/.gitea/workflows/checks.yml index 289965c..425738e 100644 --- a/.gitea/workflows/checks.yml +++ b/.gitea/workflows/checks.yml @@ -341,10 +341,26 @@ jobs: # that detects its own workflow having been skipped) as impossible. That # option is impossible because a skipped workflow runs no steps, so there # is nothing alive to notice. This is the different, tractable case: it - # fires on the pull request that REINTRODUCES a filter, and that pull - # request is still graded by the unfiltered workflow which is on the base - # today. The edit has to get past this step before it can start causing - # skips. It is a ratchet, not a skip detector. + # fires on the pull request that REINTRODUCES a filter, and it does so + # whenever the filter being reintroduced STILL NAMES THAT PULL REQUEST'S + # OWN BASE - the ordinary case, because a filter put back by hand names + # the release branch people are actually targeting. The edit then has to + # get past this step before it can start causing skips. It is a ratchet, + # not a skip detector. + # + # ⚠️ AND IT IS THE HEAD'S WORKFLOW THAT DECIDES WHETHER ANYTHING RUNS, NOT + # THE BASE'S. An earlier draft of this comment claimed the reintroducing + # pull request "is still graded by the unfiltered workflow which is on the + # base today". That was wrong, it contradicted the checkout step's own note + # a few lines below, and the error was not cosmetic: it made this step + # sound like an unconditional ratchet, which is exactly the false comfort + # CI-9 exists to stamp out. MEASURED on PR #101 - head carrying a filter + # that excludes the base, base carrying the unfiltered workflow - and the + # result was no run at all, the context posted `skipped`, the rollup + # reading `success`, and the gate CLEARED (409). Gitea takes the workflow + # file from refs/pull//head, so a head that filters itself out is simply + # never graded, and nothing on the base can reach out and stop it. That is + # what blind spot 3 below is made of. # # WHAT IT INSPECTS is the MERGED tree in $WS - the content that would # actually land on the base - not the branch tip and not the copy of this @@ -352,18 +368,44 @@ jobs: # trees here (see the long note on the checkout step) and only the merged # one is the thing being authorised. # - # ⚠️ TWO ACKNOWLEDGED BLIND SPOTS, both needing a branch-protection change - # to close, which is the repository owner's call and not this file's: + # ⚠️ THREE ACKNOWLEDGED BLIND SPOTS. NOT ONE OF THEM IS CLOSEABLE FROM + # INSIDE THIS FILE, and the reason is the same in all three: each is a case + # where THIS WORKFLOW IS ITSELF THE THING THAT GETS SKIPPED, and a guard + # that lives inside a skipped workflow does not run. Closing them needs a + # SECOND, permanently unfiltered workflow whose own context is added to + # release/1.0's `status_check_contexts`, so that something survives to + # report when this file is sat out. That is a forge change and the + # repository owner's decision; it is being put to them separately and is + # deliberately NOT held as a blocker on CI-9. # # 1. A reintroduced `paths:` filter crafted to exclude the reintroducing # pull request's OWN diff would skip that pull request, so this step # would not run to object to it. + # # 2. An edit that lands on a feature branch through a stacked pull # request is graded by the HEAD's workflow, so a filter already # present in the head hides the edit from this step - until that - # branch is proposed for release/1.0, where the base matches the - # reintroduced filter and this step runs and bites. Caught at the - # release boundary, which is the boundary that matters. + # branch is proposed for release/1.0, where (unless it is case 3) the + # base matches the reintroduced filter and this step runs and bites. + # Caught at the release boundary, which is the boundary that matters. + # + # 3. ⚠️ THE WORST OF THE THREE, AND WORSE THAN BOTH OF THE OTHERS PUT + # TOGETHER: a reintroduced `branches:` filter that simply DOES NOT + # NAME THE BASE escapes this step entirely, because the pull request + # carrying it is itself skipped. It takes no craft and no malice to + # write - `branches: [main]` copied out of a GitHub template, or a + # tidy-up to `[master]`, a branch that NO pull request in this + # repository's history has ever targeted - and it arrives as a + # skipped, laundered, untested merge into release/1.0. + # + # What makes it categorically worse is what happens the moment after. + # Once that file is ON release/1.0, every subsequent pull request is + # graded against it and every one of them is skipped too. This is not + # the stacked case leaking through a crack; it is the gate off + # completely, for everything, silently, with every badge green. The + # only thing standing between the repository and that state today is + # a human reading this file - which is precisely the kind of defence + # this step exists because it has already failed once (9c1a23328a). # # It is deliberately a FAILURE and not a warning: a warning would leave # the required context green, which is the precise defect CI-9 is about.