forked from heavy-duty/ceremony
docs: spell out crew's four-edit migration; fold in crew#250 field facts (#209)
crew#250 verified two facts the design prose now carries: a queue- displaced run is not independently rerunnable (gh run rerun / --failed / --job all refuse), so a victim PR had no manual escape hatch; and the displacing burst is deterministic — one review_requested event per panelist per request — so displacement is the steady state of a working fleet, scaling with panel size, not a traffic spike. CONSUMERS.md now walks the adoption as one atomic four-edit PR with crew as the worked example: the pin bump in every ceremony uses: reference, the new labels-sweep.yml caller, the cron RELOCATED (bold warning: a copied-not-moved schedule double-fires sweeps into the one shared group and reads as the bug getting worse after the fix), and actions: write replacing the labels caller's actions: read. Refs #209 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
45aa806207
commit
be660358f2
3 changed files with 46 additions and 9 deletions
9
.github/workflows/labels-sweep.yml
vendored
9
.github/workflows/labels-sweep.yml
vendored
|
|
@ -12,8 +12,13 @@ name: labels-sweep
|
|||
# one-running-plus-one-pending queue records every extra run as CANCELLED.
|
||||
# That displacement is semantically lossless — the surviving sweep does the
|
||||
# displaced run's work — but while the sweep rode pull_request_target runs
|
||||
# the ❌ landed on that PR's checks and read as red CI. Here a displaced
|
||||
# run attaches to no PR: the cancellations live on the Actions tab only.
|
||||
# the ❌ landed on that PR's checks and read as red CI, with no manual
|
||||
# escape hatch: GitHub refuses to rerun a queue-displaced run (crew#250).
|
||||
# And displacement is the steady state of a working fleet, not a spike —
|
||||
# one panel request emits one review_requested event per reviewer, so
|
||||
# every review round over-fills the one-running-plus-one-pending queue.
|
||||
# Here a displaced run attaches to no PR: the cancellations live on the
|
||||
# Actions tab only.
|
||||
#
|
||||
# Bootstrap semantics: a manual dispatch of the caller bootstraps the
|
||||
# taxonomy (its `bootstrap` input defaults to "yes"), exactly what
|
||||
|
|
|
|||
7
.github/workflows/labels.yml
vendored
7
.github/workflows/labels.yml
vendored
|
|
@ -12,7 +12,12 @@ name: labels
|
|||
# The reconcile sweep lived here until #209. Riding the PR-triggered run
|
||||
# meant every displacement in the sweep's shared concurrency queue recorded
|
||||
# a CANCELLED `reconcile` check on some PR — read as red CI by every human
|
||||
# and agent, though the surviving sweep does the displaced run's work. The
|
||||
# and agent, though the surviving sweep does the displaced run's work. Two
|
||||
# field facts made that untenable (crew#250): a displaced run cannot be
|
||||
# rerun — `gh run rerun`, `--failed`, and `--job` all refuse — so a victim
|
||||
# PR has no manual escape hatch; and the displacing burst is deterministic,
|
||||
# one `review_requested` event per panelist per request, so every review
|
||||
# round displaces runs and the rate scales with panel size. The
|
||||
# sweep now lives in labels-sweep.yml behind its own caller, and the
|
||||
# trigger job below is its wake: it fires on every event this caller
|
||||
# subscribes — the exact surface that used to run reconcile directly — so
|
||||
|
|
|
|||
|
|
@ -289,7 +289,9 @@ together at the same pin:
|
|||
one shared concurrency group, and GitHub records every queue-displaced
|
||||
run as CANCELLED — harmless (the surviving sweep does its work) until it
|
||||
rode a `pull_request_target` run and the ❌ landed on that PR's checks
|
||||
as fake red CI. Behind its own caller, a displaced sweep cancels on the
|
||||
as fake red CI that GitHub refuses to rerun (crew#250: `gh run rerun`
|
||||
and its `--failed`/`--job` forms all decline a queue-displaced run).
|
||||
Behind its own caller, a displaced sweep cancels on the
|
||||
Actions tab, attached to no PR; PR checks show `scope` and the green
|
||||
`trigger` only.
|
||||
|
||||
|
|
@ -437,11 +439,36 @@ the stub and ceremony's own caller stay byte-for-byte identical, the parity
|
|||
The two-caller split (ceremony#209) is **unreleased**. A consumer pinned to
|
||||
`0.4.0` or earlier keeps the previous single-caller shape — the labels
|
||||
caller carrying the cron, `workflow_dispatch`, and `actions: read` — and
|
||||
adopts the split at the pin bump to the first tag carrying ceremony#209,
|
||||
as one atomic PR: the pin, the reshaped labels caller (cron and dispatch
|
||||
removed, `actions: write` added), and the new sweep caller file. Never mix
|
||||
refs to adopt it early, and never bump without the sweep caller — that is
|
||||
the red-trigger failure mode above.
|
||||
adopts the split at the pin bump to the first tag carrying ceremony#209.
|
||||
Never mix refs to adopt it early.
|
||||
|
||||
The migration is **one atomic PR** with exactly four edits — crew, the
|
||||
consumer whose displaced-check evidence drove #209 (crew#227, crew#250),
|
||||
is the worked example; written here against `0.4.1` as the illustrative
|
||||
first tag carrying the split:
|
||||
|
||||
1. **Pin bump, every reference together** ([Version pinning](#version-pinning)):
|
||||
`0.4.0` → `0.4.1` in the labels caller's `uses:` line **and in every
|
||||
other ceremony `uses:` in the repo** — crew also pins in
|
||||
`release.yml` and its `ci.yml` guard steps. A repo on the doctrine
|
||||
mirror re-runs `docs-sync --fix` in the same PR.
|
||||
2. **New file `.github/workflows/labels-sweep.yml`** — the sweep caller
|
||||
stub above, verbatim, `bootstrap` input included (the trigger's
|
||||
`-f bootstrap=no` dispatch is refused if the input is undeclared).
|
||||
3. **The hourly cron RELOCATES — it is moved, never copied.** Delete the
|
||||
`schedule:` block (and the bare `workflow_dispatch:`) from the labels
|
||||
caller in the same edit that adds the sweep caller.
|
||||
**Warning**: a consumer that copies the sweep caller and leaves the
|
||||
old schedule on the labels caller gets DOUBLE sweeps — every cron tick
|
||||
fires both callers into the one shared `labels-reconcile` group — so
|
||||
displacement goes **up**, and the fix reads as the bug getting worse.
|
||||
4. **`actions: write` on the labels caller** — consumers carry
|
||||
`actions: read` today (crew does); the trigger job's `gh workflow run`
|
||||
is a write. The sweep caller keeps `actions: read`.
|
||||
|
||||
Bump without the sweep caller and the trigger job goes red on every PR
|
||||
and issue event — the loud failure mode above — so never split these
|
||||
four edits across PRs.
|
||||
|
||||
`pull_request_target` is intentional: fork PRs need the base repository's
|
||||
token to write labels. The reusable workflows execute no PR code. They check
|
||||
|
|
|
|||
Loading…
Reference in a new issue