From 4e787a3f23d6d50942d13d191ba9062402c823b7 Mon Sep 17 00:00:00 2001 From: Nils Lehnen <30603423+iderex@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:42:12 +0200 Subject: [PATCH 1/2] Give the five contexts that can never be required a verdict The document is where issue #26 assembles the required set from, and a check name it gives no verdict to can be read as kept or as dropped with equal justice, so two readings produce two gates. A comment on that issue recorded that every declared name carried a verdict and evidenced it with a sweep whose only output was the six build entries. Re-run at 9208ceb, that sweep prints ten, and four of the new ones are a gap rather than the deliberate absence the build row covers: the three smoke entries and the smoke workflow's verify job. A fifth, release, the sweep cannot see at all, because the word matches inside the reason on another row and a fixed-string comparison cannot tell that from a verdict. All five read a tag or a published release, which a pull request has neither of, so they arrive on nothing a merge waits for. Requiring one would hold every merge open for a tick that is not coming, which is what required-context-nothing-reports refuses, so they are dropped permanently rather than until #26 and this document now says so in the same terms the table uses. What it prevents is the gate being assembled from a document that gives five of the names it is assembled from no answer, and the smoke jobs are the ones where reading it wrong costs most: they are the only check here that reads what an operator downloads rather than the source it was built from, so a reader who took them for droppable would drop the rule along with the tick. The paragraph separates the two. The means is prose in the existing parity document rather than a new file or a check, because what was missing is a verdict a person reads when assembling a required set by hand, and internal/contexts already holds the machine-readable half and already agrees with these five. Both pasted commands were run at the commit they name before the paragraph was written. The sweep is pinned to 9208ceb rather than to origin/main because this change is what moves its output. Refs #26 Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com> --- docs/quality-parity.md | 73 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/docs/quality-parity.md b/docs/quality-parity.md index 4f40654..4bca09b 100644 --- a/docs/quality-parity.md +++ b/docs/quality-parity.md @@ -152,6 +152,79 @@ it is outside the target's. It publishes from the default branch and cannot gate a pull request, so requiring it would require a context that never arrives on the thing being gated. +Five more names this tree declares carried no verdict here until this +paragraph, and they are a different case from the five above. Those are waiting +for a required set to join. These can never join one. + +The sweep, read at `9208ceb599a294328bde3d8b660c65a5fd3c5fb5` rather than at +`origin/main`, because the paragraphs below are what change its output and a +paste that stops reproducing the moment it lands is the drift this document +warns about at the top: + +``` +git show 9208ceb599a294328bde3d8b660c65a5fd3c5fb5:internal/contexts/contexts.go \ + | grep -oE 'Name: +"[^"]+"' | sed 's/Name: *"//; s/"$//' | sort -u \ + | while read -r n; do + git grep -q -F "$n" 9208ceb599a294328bde3d8b660c65a5fd3c5fb5 \ + -- docs/quality-parity.md || echo "no literal: $n" + done +no literal: build (darwin/amd64) +no literal: build (darwin/arm64) +no literal: build (linux/amd64) +no literal: build (linux/arm64) +no literal: build (windows/amd64) +no literal: build (windows/arm64) +no literal: smoke (darwin/arm64) +no literal: smoke (linux/amd64) +no literal: smoke (windows/amd64) +no literal: verify the published artefacts +``` + +The six `build` entries are the one place a literal is deliberately absent. +Their verdict is the `build` row of the table above, which reaches them through +`docs/decisions/0012-the-supported-platforms.md`, and writing the six strings +out here would be this document enumerating what that record decides. The other +four are a gap. A fifth name is one too and this sweep cannot show it: +`release` matches as a word inside the reason on the SBOM row rather than as a +verdict of its own, which is the false pass a fixed-string comparison gives and +the reason the tree holds the list that decides this in +`internal/contexts/contexts.go` instead. + +All five are dropped from the required set, permanently rather than until #26. +What their jobs read is a tag or a published release, and a pull request has +neither, so these contexts arrive on nothing a merge is waiting for and +requiring one would hold every merge open for a tick that is not coming. That +is what `required-context-nothing-reports` exists to refuse, so the two +directions of the comparison would contradict each other. Four of the five +carry that reason as a shared constant: + +``` +git show origin/main:internal/contexts/contexts.go \ + | awk '/^var Absences/,/^}$/' | tr '\n' ' ' \ + | grep -oE '\{[^{}]*neverOnAPullRequest[^{}]*\}' | grep -oE 'Name: +"[^"]+"' +Name: "verify the published artefacts" +Name: "smoke (linux/amd64)" +Name: "smoke (windows/amd64)" +Name: "smoke (darwin/arm64)" +``` + +`release` carries a reason of its own in the same list because its job runs on a +tag push and on nothing else, which is narrower than what the shared sentence +says. The workflow files agree with the list rather than being described by it: +`.github/workflows/release.yml` triggers on `push` with a tag pattern and +declares no pull-request trigger, and `.github/workflows/smoke.yml` says at its +own trigger block that the names its jobs report under arrive on no pull +request at all and that `internal/contexts` carries them as permanent +deliberate absences. + +Dropped from the gate is not dropped as a rule, and the smoke jobs are the case +where the difference matters most. They are the only thing in this repository +that reads what an operator downloads rather than the source it was built from, +which is the distance every other check here is blind to. They hold that rule +on a published release and on a schedule instead of on a pull request, so what +is given up by leaving them out of the required set is the moment the failure is +caught rather than whether it is caught. + ## What each side reports today Neither list is written here. Both are printed, from a completed run rather From 110d26f2ae680073d520e12e0f5b2ccb0981f866 Mon Sep 17 00:00:00 2001 From: Nils Lehnen <30603423+iderex@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:44:19 +0200 Subject: [PATCH 2/2] Re-read the trigger and condition walk at a commit whose pastes reproduce Two of the five pastes in the section that reads which contexts arrive had stopped reproducing. The branch-filter grep names three files and returns five; the type-filter grep names one line and returns two. Both moved for the same reason, which is that this board gained the release and smoke workflows since the reading was made, and neither of those runs on a pull request at all. The section already disclosed the commit it was read at, so nothing here was hidden. What was wrong is that the commands beside the pastes resolve origin/main, so a reader who ran one got an output the document did not carry and had no way to tell a workflow that narrows a pull request from one that runs on none. That is the failure this repair prevents: the section exists to find a context arriving on some pull requests and not on others, and a grep whose membership grows with every tag-triggered workflow buries that signal under files the question does not apply to. The new prose says which of the two a member is and what a reader should look for. Every paste was re-run before the sentence beside it was written, and the three that reproduce unchanged are named as such rather than left for a reader to re-derive. The means is prose in the document the issue names as the place for the result, and the readings stay commands a reader re-runs rather than a table, because a list of workflow files here would drift against the directory that decides it. Refs #62 Signed-off-by: Nils Lehnen <30603423+iderex@users.noreply.github.com> --- docs/quality-parity.md | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/docs/quality-parity.md b/docs/quality-parity.md index 4bca09b..0b56746 100644 --- a/docs/quality-parity.md +++ b/docs/quality-parity.md @@ -438,8 +438,15 @@ unaffected. A context that arrives on some pull requests and not on others is what this section is written against, and three of the ways to build one are readable in -these files rather than walked. The readings below were made at `1fc6961` and -cover every workflow file in the tree at that commit. +these files rather than walked. The readings below were made at +`9208ceb599a294328bde3d8b660c65a5fd3c5fb5` and cover every workflow file in the +tree at that commit. They replace a reading made at `1fc6961`, two of whose five +pastes had stopped reproducing by the time this one was taken: five files carry +no branch filter that reads every branch where three did, and two carry a type +filter where one did. Both differences are this board gaining the release and +smoke workflows, and neither of those runs on a pull request. The other three, +the path filters, the branch filter under `dependency-review.yml` and the `if:` +keys, reproduce unchanged at this commit. A path filter is the ordinary way it happens, and no workflow here carries one: @@ -449,30 +456,43 @@ exit=1 ``` A trigger narrowed to some branches is the same failure by a second route, and -three of these files carry no branch filter that reads every branch: +five of these files carry no branch filter that reads every branch: ``` git grep -L 'branches: \[ *"\*\*" *\]' origin/main -- .github/workflows/ origin/main:.github/workflows/dco.yml origin/main:.github/workflows/dependency-review.yml +origin/main:.github/workflows/release.yml origin/main:.github/workflows/scorecard.yml +origin/main:.github/workflows/smoke.yml ``` -The third is the supply-chain self-audit, which declares no pull-request -trigger at all and is outside the required set already. Neither of the other -two narrows anything. `dependency-review.yml` writes no branch filter under any -of its triggers, which is every branch: +Three of the five declare no pull-request trigger at all and are outside the +required set already, permanently rather than until #26. The supply-chain +self-audit publishes from the default branch; the release and smoke workflows +read a tag or a published release, which is the verdict written for them above +under what this board adds. A file that runs on no pull request cannot narrow +one, so the membership of this command grows every time this board gains a +workflow of that shape, and the growth answers nothing the section asks. What +it is worth reading for is a file that does run on a pull request appearing in +it. + +Neither of the two that do narrows anything. `dependency-review.yml` writes no +branch filter under any of its triggers, which is every branch: ``` git grep -n 'branches:' origin/main -- .github/workflows/dependency-review.yml ; echo "exit=$?" exit=1 ``` -`dco.yml` carries the only type filter in these files: +`dco.yml` carries the only type filter on a pull-request trigger in these +files. One other carries the key, on a trigger that is not a pull request at +all: ``` git grep -n 'types:' origin/main -- .github/workflows/ origin/main:.github/workflows/dco.yml:13: types: [opened, synchronize, reopened] +origin/main:.github/workflows/smoke.yml:41: types: [published] ``` The claim about the three types it names is that they are the three the