diff --git a/.github/workflows/shell-analysis.yml b/.github/workflows/shell-analysis.yml index eae2150..65c3520 100644 --- a/.github/workflows/shell-analysis.yml +++ b/.github/workflows/shell-analysis.yml @@ -22,9 +22,18 @@ # NOT one of those: the paragraph at the upload step carries the run log that # refutes the sentence that said it was. # -# This covers the shell and nothing else. The analysis over the core's own language -# is the other half of #81 and waits on #11, because there is no code in this tree -# and no language chosen. +# This covers the shell and nothing else. The analysis over the core's own +# language is `.github/workflows/codeql.yml`, which reads `src/` and refuses a +# finding the register beside it does not excuse by name. +# +# THESE SENTENCES SAID THAT ANALYSIS WAS THE OTHER HALF OF #81 AND WAITED ON #11, +# BECAUSE THERE WAS NO CODE IN THIS TREE AND NO LANGUAGE CHOSEN. All four were +# true on 2026-08-22, the day they were written, and none of them is now. #11 +# closed on 2026-08-25, `src/` holds the code the language it chose is written +# in, that leg landed on 2026-08-26 naming this file in its own header, and #81 +# closed on 2026-08-31. Nothing opened this comment in between, because no change +# that made one of the four false had a reason to, and #404 is where it was found +# by reading the sentence against the directory it sits in. name: shell-analysis on: diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index b32e076..0c5a745 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -11,10 +11,17 @@ # # That leg uploads its own findings to the code-scanning tab now, under its own # category, so the two sets sit beside each other there rather than one of them -# being readable only in a job log. What #81 still holds is the analysis over the -# core's own language, which waits on #11 because no code is in this tree. How many +# being readable only in a job log. The analysis over the core's own language is a +# third leg again, `.github/workflows/codeql.yml`, which reads `src/`. How many # shell scripts there are moves whenever one lands, so it is not counted here. # +# THIS PARAGRAPH SAID #81 STILL HELD THAT ANALYSIS AND THAT IT WAITED ON #11 +# BECAUSE NO CODE WAS IN THIS TREE. Both were true on 2026-08-22, the day they +# were written, and neither is now: that leg landed on 2026-08-26 naming this file +# in its own header, #11 closed on 2026-08-25 and #81 on 2026-08-31. No change +# that made one of the three false had a reason to open this comment, and #404 is +# where it was found by reading the sentence against the directory it sits in. +# # The gate runs zizmor's regular persona at --min-severity=low: it fails the # build on any actionable (low/medium/high/critical) security finding - # template-injection, cache-poisoning, dangerous-triggers, excessive-permissions, diff --git a/docs/gate-parity.md b/docs/gate-parity.md index ce86909..9f57dae 100644 --- a/docs/gate-parity.md +++ b/docs/gate-parity.md @@ -262,7 +262,7 @@ work is. | `wiki-lint.yml` | `wiki-lint` | Prose that names a path or a command that no longer exists, so the first thing a reader follows is the first thing that is wrong | satisfied | `doc-paths.yml` runs here, landed through #110 in a changed shape, and it covers the path half of that protection and not the command half. There the documentation is a separate repository with no gate of its own, so the check cannot run on a pull request without a typo already in the wiki reddening every unrelated change. Here the documents and the code are in one tree and move in one commit, so the check runs on the pull request, which is where the change that moves a file can fix the sentence naming it. Its rules sit in `.github/doc-paths/doc-paths.sh` rather than in the workflow file, and each run proves them against their own fixtures before it judges anything. A command a document tells a reader to run is not checked: that needs a verb in the tree or a pinned toolchain to look in, #14 landed the pin and no check that looks in it has been written, and the run prints the absence on every pull request rather than leaving it to be assumed. The external addresses are a second job that returns zero whatever it finds, since an address outside this repository that is down for an hour is not a defect here. | | `zizmor.yml` | `Audit workflows (zizmor)` | Workflow YAML treated as configuration when it is release-critical attack surface | satisfied | `zizmor.yml` runs here. | | none on that gate | `thread-detector` | A concurrency claim broken under a load nobody reproduces by hand, found as a rare wrong answer rather than as a failure | satisfied | #117, and it is added here rather than adopted: parity is a floor rather than a ceiling, and this is the first row added above it. This repository is a library hosted inside other people's processes rather than one process on a server, and 0009 makes promises about which thread a caller is left on, so a detector that reddens when one of those promises is broken is a check this board needs and that gate does not run. `.github/workflows/thread-detector.yml` runs here on every pull request and on every push to the default branch, and `.github/thread-detector/thread-detector.sh` is the verdict: the suite runs under the detector and a report against it fails the run, and then a target holding a data race written on purpose runs under the same detector and a run of it that reports nothing fails the run too, because a detector that was never switched on reports nothing and prints a page indistinguishable from a clean tree. A finding it does not refuse is written in `.github/thread-detector/suppressions` with the reason, an entry there carrying no reason is itself refused, and the detector's own suppression file is derived from that register rather than being a second file. Two bounds it prints on every run: the detector reaches neither the Windows nor the Android target, so a race that appears only there is outside every run this leg makes, and it reports an interleaving it observed rather than one that is possible. | -| none on that gate | `Analyse the shell the gate runs (shellcheck)` | A defect in the language this gate's own checks are written in, and in particular an expansion left unquoted, which word-splits its input and points a rule at something nobody named | satisfied | #81. `.github/workflows/shell-analysis.yml` runs here, and its settings and its fixtures are in `.github/shell-analysis/shell-analysis.sh`. A rule it does not refuse is written in `.github/shell-analysis/excluded-rules` with the reason it is not refused, an identifier written there with no reason is itself refused, and every run prints that file beside its verdict. Its findings reach the code-scanning tab as well as the job log: the same script writes them as SARIF, the workflow uploads that file under its own category, and the upload is skipped on a pull request from a fork, where the token cannot write to that surface and the gate still refuses. Parity is a floor rather than a ceiling and this is the second row added above it. That gate runs no shell analyser: the single mention of shellcheck in that repository is a disable directive inside a composite action rather than a run, and no workflow file there invokes it. Here two of this gate's own legs are shell scripts that read paths and pull-request bodies, so the language the checks are written in was the one body of executable code in this tree that nothing read. It covers the shell and not the core's own language, which is the half of #81 that waits on #11. | +| none on that gate | `Analyse the shell the gate runs (shellcheck)` | A defect in the language this gate's own checks are written in, and in particular an expansion left unquoted, which word-splits its input and points a rule at something nobody named | satisfied | #81. `.github/workflows/shell-analysis.yml` runs here, and its settings and its fixtures are in `.github/shell-analysis/shell-analysis.sh`. A rule it does not refuse is written in `.github/shell-analysis/excluded-rules` with the reason it is not refused, an identifier written there with no reason is itself refused, and every run prints that file beside its verdict. Its findings reach the code-scanning tab as well as the job log: the same script writes them as SARIF, the workflow uploads that file under its own category, and the upload is skipped on a pull request from a fork, where the token cannot write to that surface and the gate still refuses. Parity is a floor rather than a ceiling and this is the second row added above it. That gate runs no shell analyser: the single mention of shellcheck in that repository is a disable directive inside a composite action rather than a run, and no workflow file there invokes it. Here two of this gate's own legs are shell scripts that read paths and pull-request bodies, so the language the checks are written in was the one body of executable code in this tree that nothing read. It covers the shell and not the core's own language, which is `.github/workflows/codeql.yml` and has its own row above. THIS SENTENCE SAID THAT HALF WAS ONE #81 STILL HELD AND THAT IT WAITED ON #11. It was true on 2026-08-22, the day it was written, and stopped being true on 2026-08-26, when that leg landed; #11 closed on 2026-08-25 and #81 on 2026-08-31, and no change that moved one of the three had a reason to open this cell. #404 is where it was found by reading the sentence against the row above. | | none on that gate | `targets` | A defect that only appears on a platform the runner is not, found in a client repository by somebody who was not looking for it | satisfied | #113, added here rather than adopted. That gate builds one artifact for one runtime; this repository is a library eleven clients link on Android, on iOS, on a desktop and on a television, and 0011 states that the cost of this means is one build leg per target triple. `.github/workflows/targets.yml` runs here on every pull request and on every push to the default branch, and `.github/targets/targets.sh` is the verdict: the library is compiled once for every triple `.github/targets/targets` names, an entry there carrying no reason is itself refused, so is a triple this compiler does not know, and so is a register naming nothing, because an empty register compiles nothing, exits zero and prints a page indistinguishable from a run that compiled every platform. It reports under one check-run name rather than one per platform, and 0113 is where that was argued against the matrix alternative. Two bounds it prints on every run: it compiles and never runs, so nothing in the suite executes on any triple but the runner's own, and it reaches no binding layer, because 0011 puts a generated interface between this library and every client and no such artefact is in this tree. | ## What this table does not cover