Skip to content

ci: hausfold.co fixed what rule 3's paragraph still calls out - #587

Merged
JulienMartel merged 1 commit into
mainfrom
worktree-ci-doc-hausfoldco-stale
Sep 12, 2026
Merged

JulienMartel merged 1 commit into
mainfrom
worktree-ci-doc-hausfoldco-stale

Conversation

@JulienMartel

Copy link
Copy Markdown
Contributor

What

docs/ci.md, three edits, docs only.

  1. Rule 3's hausfold.co paragraph — the last two sentences went. They 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". They now say what those jobs are worth copying for. The first half of the paragraph is untouched.
  2. Rule 2 gains the preview.yml exemption, stated at the width of its evidence.
  3. The Nix store cache section's "which rule 2 requires of every workflow here" becomes "of every workflow whose push was narrowed to main" — the new exemption falsified the universal phrasing 120 lines down.

Why

hausfold.co#338 fixed the thing rule 3 was still calling out. A standard that assigns work to another repo is the one document nobody re-reads when the work lands, so the criticism outlived its subject and the doc was recommending a fix that was already in.

What replaces it is the reason those four jobs are the family's best statement of rules 2 and 3: each checks the site's copy against a checkout of hausfold/haus, 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 the site moves, the cron catches an upstream that moved without it. That pairing is the answer to the blind spot rule 3 had just spent a paragraph recommending.

The endorsement stops at the pairing. deploy and dns put non-PR runs in shared groups, deliberately and for their own reasons, and rule 3 reads them the way it reads anyone.

The one real gap is preview.yml, pull_request-only and the only 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: the workflow 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. A branch with no PR has nothing there for it to check, so adding the line would hand someone a button whose run groups as preview- with both jobs skipped — worse than no button. No hausfold.co PR needed.

Verify

Every claim checked against hausfold/hausfold.co at a45e661 (git show origin/main:<path>, read-only), all 11 workflows:

claim result
every file carries concurrency: 11 / 11
every push: carries branches: [main] 9 / 9 push triggers
workflow_dispatch present 10 / 11 — preview.yml the only gap
the four *-drift.yml check out hausfold/haus 4 / 4, path: .haus
those four carry a Monday cron 4 / 4 (0, 15, 15, 30 past 9 on Mon)
preview.yml group keyed on the PR number preview-${{ github.event.pull_request.number }}
both preview.yml jobs gate on head.repo.full_name preview and cleanup both

A dispatched preview.yml run: head.repo.full_name is null, so preview's if fails; action is absent, so cleanup's action == 'closed' fails. Both skipped, group preview-.

Widened past hausfold.co: the only other dispatch-less workflows anywhere in the family are the five release.ymls, already out of scope at docs/ci.md's release-workflow paragraph. "The family's only one" holds.

Pre-PR assurance pass run on git diff main...HEAD + AGENTS.md; nothing landed at 4 or 5, and every finding at 2 or 3 is fixed in this commit (the falsified clause at line 201, the over-wide exemption lede, the unstated concurrency-group fact, the paragraph order that left "that block" pointing two paragraphs back, and the endorsement's scope).

No test in this repo asserts on docs/ci.md.

Watch out

🤖 Generated with Claude Code

https://claude.ai/code/session_01UMUHVTxRfgADnACNXzc6Ef

`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) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UMUHVTxRfgADnACNXzc6Ef
@JulienMartel
JulienMartel merged commit f3df17c into main Sep 12, 2026
1 check passed
@JulienMartel
JulienMartel deleted the worktree-ci-doc-hausfoldco-stale branch September 12, 2026 12:36
JulienMartel added a commit that referenced this pull request Sep 13, 2026
Rule 3 states an absolute — "**Only a PR run is ever in a shared group**" —
and the family has three standing counterexamples, all in `hausfold.co`:
`deploy.yml`, `dns.yml` and `preview-sweep.yml`, each keying every run into
one constant group named for the workflow, each on purpose, and the doc said
nothing about any of them. An unstated exemption is what the next PR "fixes".

Census over the org's public repos at their `origin/main`: 27 workflows, 21
carrying a `concurrency:` block, exactly 3 with a constant top-level group.
The near misses are `scruff`'s `release.yml` (`release-${{ github.ref }}`) and
hausfold.co's `preview.yml` (keyed on the PR number), both correctly keyed.
`ops` is private and outside the sweep; it runs a scheduled `scoreboard` and
nothing on a push.

The property, written so the count is not load-bearing: what a gate loses when
an intermediate run is dropped is that commit's answer, which nothing else
will produce. These three converge something outside the repo instead — the
deployed site, the DNS zone, this repo's own preview Workers — and a converge
has no answer to lose, because the surviving run redoes the whole job from the
current state. For them the constant group is the point of the line, not a
cost of it: what it serializes is the resource.

The guard against reading that wider than it is: check for a `pull_request`
trigger first. None of the three has one, and `preview.yml` is the standing
example of a workflow that converges something external AND has a PR run, and
keys on the PR number anyway. The one other constant group in the family,
`pounce`'s job-level `bump-pin`, is in a release workflow and off this list by
the doc's own line; a reader who greps finds four and now knows why.

`cancel-in-progress` is a second and separate question, about what a stopped
run leaves behind, and the three do not share one reason. `deploy` cancels, a
newer build superseding an older outright. `dns` does not, because a converge
stopped between two tables leaves the zone half-way. The preview sweep does
not for a different reason entirely: its deletes are independent and a Worker
already gone counts as success, so nothing is half-written — there is just
nothing for a later run to supersede, and a `dry_run` dispatch would otherwise
take out a live sweep.

And the cost is stated rather than papered over. `dns`'s scheduled `check`
shares `group: dns` with `publish`, a *pending* run is cancelled outright when
a newer one joins whatever `cancel-in-progress` says, so a Monday check queued
behind a running converge can be dropped and that week's drift answer waits
seven days. One writer on the zone is worth more than one week's report. It is
a trade made once, for a converge, and not a reason to key a gate this way.

Follow-up to #587, which narrowed rule 3's endorsement of `hausfold.co` so the
paragraph could not be read as blessing these three, but left the exemption
itself unwritten.


Claude-Session: https://claude.ai/code/session_01UMUHVTxRfgADnACNXzc6Ef

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant