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.
|
# one-running-plus-one-pending queue records every extra run as CANCELLED.
|
||||||
# That displacement is semantically lossless — the surviving sweep does the
|
# That displacement is semantically lossless — the surviving sweep does the
|
||||||
# displaced run's work — but while the sweep rode pull_request_target runs
|
# 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
|
# the ❌ landed on that PR's checks and read as red CI, with no manual
|
||||||
# run attaches to no PR: the cancellations live on the Actions tab only.
|
# 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
|
# Bootstrap semantics: a manual dispatch of the caller bootstraps the
|
||||||
# taxonomy (its `bootstrap` input defaults to "yes"), exactly what
|
# 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
|
# The reconcile sweep lived here until #209. Riding the PR-triggered run
|
||||||
# meant every displacement in the sweep's shared concurrency queue recorded
|
# 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
|
# 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
|
# 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
|
# trigger job below is its wake: it fires on every event this caller
|
||||||
# subscribes — the exact surface that used to run reconcile directly — so
|
# 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
|
one shared concurrency group, and GitHub records every queue-displaced
|
||||||
run as CANCELLED — harmless (the surviving sweep does its work) until it
|
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
|
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
|
Actions tab, attached to no PR; PR checks show `scope` and the green
|
||||||
`trigger` only.
|
`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
|
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
|
`0.4.0` or earlier keeps the previous single-caller shape — the labels
|
||||||
caller carrying the cron, `workflow_dispatch`, and `actions: read` — and
|
caller carrying the cron, `workflow_dispatch`, and `actions: read` — and
|
||||||
adopts the split at the pin bump to the first tag carrying ceremony#209,
|
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
|
Never mix refs to adopt it early.
|
||||||
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 migration is **one atomic PR** with exactly four edits — crew, the
|
||||||
the red-trigger failure mode above.
|
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
|
`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
|
token to write labels. The reusable workflows execute no PR code. They check
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue