From 98bfeae01970ee5344c7ba230324205cbeb1a463 Mon Sep 17 00:00:00 2001 From: Julien Martel Date: Sat, 12 Sep 2026 07:11:21 -0500 Subject: [PATCH] ci: hausfold.co fixed what rule 3's paragraph still calls out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `docs/ci.md`'s hausfold.co paragraph closed on two sentences that named its drift jobs as "the place rules 2 and 3 are least applied (`push:` with `paths:` and no `branches:`, and no `concurrency` at all), which is a thing to fix there rather than a thing to copy". hausfold.co#338 fixed exactly that, and a standard that assigns work to another repo is the one document nobody re-reads when the work lands. Verified at hausfold.co `a45e661`, all 11 workflows: 11 of 11 carry a `concurrency:` block, all 9 `push:` triggers carry `branches: [main]`, and 10 of 11 carry `workflow_dispatch`. The four drift jobs are now the fullest statement of both rules in the family, not the thinnest. So the two sentences say what those jobs are now worth copying FOR. Each of the four checks the site's copy against a checkout of `hausfold/haus` (`check-bar-tables`, `check-rice-bindings`, `gen-options --check`, `check-rooms`), and a `paths:` filter cannot see a change made in another repo. Each pairs the filter with a Monday `schedule:`: the filter keeps the gate quiet while only this site moves, the cron catches an upstream that moved without it. That is the answer to the blind spot rule 3 just spent a paragraph recommending. The endorsement stops at the pairing — `deploy` and `dns` put non-PR runs in shared groups, deliberately and for reasons of their own, and rule 3 still reads them the way it reads anyone. The one real gap is `preview.yml`, `pull_request`-only and the single workflow in the family without `workflow_dispatch` outside the release workflows rule 2 already exempts. It stays that way, and rule 2 now says why rather than leaving it to be re-opened: it deploys a preview Worker named from `github.event.pull_request.number`, keys its concurrency group on the same number, and gates both jobs on `head.repo.full_name`, so a branch with no PR has nothing there for it to check. Adding the line would hand someone a button whose run groups as `preview-` with both jobs skipped, which is worse than no button. The exemption is written at the width of its evidence — triggered by `pull_request` alone, so it narrowed no `push` and took nothing away to hand back — and not at the width of "a workflow about pull requests", which `preview-sweep.yml` also is while correctly carrying the line. That exemption falsified a clause 120 lines down, in *The Nix store cache*: "a `workflow_dispatch` — which rule 2 requires of every workflow here". It now reads "of every workflow whose `push` was narrowed to `main`", the same formulation as the exemption. The reasoning downstream is unaffected; only the universal phrasing was. The first half of the hausfold.co paragraph is untouched: it is still the family's one instance of the `paths:` rule, and still the place to look for it. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01UMUHVTxRfgADnACNXzc6Ef --- docs/ci.md | 35 ++++++++++++++++++++++++----------- 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/ci.md b/docs/ci.md index a8e36606..1dfa15d8 100644 --- a/docs/ci.md +++ b/docs/ci.md @@ -76,6 +76,15 @@ own headline — it takes a deliberate button press, so it stays. That block is the floor, not the whole `on:`. `scruff`'s `check.yml` also carries `workflow_call`, because its release workflow calls the gate at a tag. +The one line that may be dropped is `workflow_dispatch`, and only by a +workflow triggered by `pull_request` alone: it narrowed no `push`, so it took +nothing away to hand back. `hausfold.co`'s `preview.yml` is the family's only +one. It deploys a preview Worker named from `github.event.pull_request.number` +and keys its concurrency group on the same number, and both its jobs are gated +on `head.repo.full_name`, so a branch with no PR has nothing there for it to +check. Adding the line would hand someone a button whose run groups as +`preview-` with both jobs skipped, which is a worse answer than no button. + **3. Cancel a superseded PR run.** A second push to a branch has already made the first run's answer worthless, and the abandoned run still holds its runners. On the macOS ones that is a queue slot the next PR waits behind, which @@ -104,10 +113,14 @@ cancel there would be a half-published release. its workflows carry a `paths:` filter, so a PR that touches no content runs no content check. That is the rule the rest of the family has the least of — most of these gates are small enough that a filter would cost more reading than it -saves, but it is the first thing to reach for when one is not. Its drift jobs -are also the place rules 2 and 3 are least applied (`push:` with `paths:` and -no `branches:`, and no `concurrency` at all), which is a thing to fix there -rather than a thing to copy. +saves, but it is the first thing to reach for when one is not. Its four drift +jobs are where a filter is paired with the thing that covers for it: each +checks the site's copy against a checkout of `hausfold/haus`, and a `paths:` +filter cannot see a change made in another repo. So each carries a weekly +`schedule:` beside its filtered `push` and `pull_request` — the filter keeps +the gate quiet while only this site moves, and the cron is the half that +catches an upstream that moved without it. The pairing is what to copy; the +rest of that repo is read the same as any other against the five rules. **4. Pin third-party actions to a tag.** `@main` is whatever that vendor pushed this morning, running on the machine that compiles what we ship. @@ -187,13 +200,13 @@ entry the whole thing exists for. **The test reads the ref and not the event, and rule 2 is why.** `github.event_name != 'pull_request'` bounds only one of the two cases a write can come from. A `workflow_dispatch` — which rule 2 requires of every workflow -here, as the only way a branch with no PR gets checked at all — is not a pull -request, so a dispatch from a feature branch passes that test and saves a whole -store scoped to that branch. No run on `main` can purge it, because the sweep -below is scoped to the run's own ref too; GitHub drops a cache only after seven -days with nothing reading it, and every further dispatch from that branch -restarts that clock. The ref form is the one that says it: a push to main -writes, everything else only reads. +whose `push` was narrowed to `main`, as the only way a branch with no PR gets +checked at all — is not a pull request, so a dispatch from a feature branch +passes that test and saves a whole store scoped to that branch. No run on +`main` can purge it, because the sweep below is scoped to the run's own ref +too; GitHub drops a cache only after seven days with nothing reading it, and +every further dispatch from that branch restarts that clock. The ref form is +the one that says it: a push to main writes, everything else only reads. It is one such line in nebelung and three in haus, one per nix job; *One key per JOB* below is why no two of them share a key.