docs: explain sweep cadence and manual dispatch

This commit is contained in:
codex-bot-andresmgsl 2026-07-29 09:27:29 +00:00
parent 1de6b742f8
commit 3eff28e624
4 changed files with 44 additions and 23 deletions

View file

@ -5,17 +5,19 @@ name: labels
# unpinned — correct only for the repo that IS the source). Consumers write: # unpinned — correct only for the repo that IS the source). Consumers write:
# uses: heavy-duty/ceremony/.github/workflows/labels.yml@<pinned-tag> # uses: heavy-duty/ceremony/.github/workflows/labels.yml@<pinned-tag>
on: on:
# Hourly, not */15 (#199): the cron is the sweep's ONLY wake for the four # The consumer owns this cadence (#203). Hourly is the recommended default
# transition classes no subscribed event carries — a review verdict landing # when no other engine drives board state: the cron is then the sweep's ONLY
# (there is no pull_request_review trigger here), blocker:ci-red set or cleared # wake for four transition classes — a review verdict landing (there is no
# (no check_suite/check_run/workflow_run), a blocker:conflict when ANOTHER PR # pull_request_review trigger here), blocker:ci-red set or cleared (no
# check_suite/check_run/workflow_run), a blocker:conflict when ANOTHER PR
# merges under this one, and the time-based stale / 48h claim-reclaim. The # merges under this one, and the time-based stale / 48h claim-reclaim. The
# events below carry the rest in seconds. So hourly trades ≤1h of latency on # events below carry the rest in seconds. Hourly trades ≤1h of latency on
# those four for dropping */15's four full-board sweeps an hour at GitHub's # those four for one full-board sweep at GitHub's 1-minute billing floor. If
# 1-minute billing floor — 52% of one private consumer's runs. Do NOT delete # another engine writes some of those transitions, only the classes with no
# this cron — it is the discovery path for those four, not a forgotten-handoff net. # other writer bound the cadence; relax it only as that list shrinks.
schedule: [{cron: "0 * * * *"}] schedule: [{cron: "0 * * * *"}]
workflow_dispatch: # bootstraps missing labels on a fresh repo # A manual full-board sweep, including taxonomy bootstrap on a fresh repo.
workflow_dispatch:
# Narrowed (#199) to the actions that carry a queue-state change the hourly # Narrowed (#199) to the actions that carry a queue-state change the hourly
# cron cannot wait one cadence for — dropping only labeled/unlabeled/assigned/ # cron cannot wait one cadence for — dropping only labeled/unlabeled/assigned/
# unassigned, which feed validation and the 48h claim clock (caught within one # unassigned, which feed validation and the 48h claim clock (caught within one

View file

@ -3,7 +3,8 @@
The taxonomy shared across the heavy-duty repos. Only the `scope:` set The taxonomy shared across the heavy-duty repos. Only the `scope:` set
differs per repo (each repo's `.github/labels.conf` names its actual differs per repo (each repo's `.github/labels.conf` names its actual
surfaces); everything else below is core and identical everywhere, created by surfaces); everything else below is core and identical everywhere, created by
the labels workflow's bootstrap dispatch (issue #10). the labels workflow's dispatch (which is also the operator's manual
full-board reconcile sweep; issue #10).
Two state machines share the taxonomy: the **PR machine** (proven in Two state machines share the taxonomy: the **PR machine** (proven in
box/rig/cast, reconciled by machinery) and the **issue flow** (the box/rig/cast, reconciled by machinery) and the **issue flow** (the

5
changelog.d/203.md Normal file
View file

@ -0,0 +1,5 @@
### Changed
- Labels automation docs now make sweep cadence a consumer-owned tradeoff,
retain hourly as the engine-less default, and document manual dispatch as
the operator's immediate full-board sweep (#203).

View file

@ -122,7 +122,8 @@ the machinery at all:
[Labels automation](#labels-automation), plus `.github/labels.conf` [Labels automation](#labels-automation), plus `.github/labels.conf`
(panel + the repo's `scope:*` rows) and `.github/labeler.yml` (the (panel + the repo's `scope:*` rows) and `.github/labeler.yml` (the
path→scope globs). Run `workflow_dispatch` once — **this bootstraps path→scope globs). Run `workflow_dispatch` once — **this bootstraps
the taxonomy, `release` label included**. the taxonomy, `release` label included** — and use it again whenever an
operator needs a full-board sweep immediately.
7. **The artifact hook** (optional): `.github/actions/release-artifact/` 7. **The artifact hook** (optional): `.github/actions/release-artifact/`
per [The artifact hook](#the-artifact-hook). No hook → the source per [The artifact hook](#the-artifact-hook). No hook → the source
tarball is the package. tarball is the package.
@ -296,15 +297,18 @@ The complete caller is:
```yaml ```yaml
name: labels name: labels
on: on:
# Hourly, not */15 (#199): the cron is the sweep's only wake for the # The consumer owns this cadence (#203). Hourly is the recommended default
# transitions no subscribed event carries — a review verdict landing (no # when no other engine drives board state: the cron is then the sweep's only
# pull_request_review trigger), blocker:ci-red set/cleared, a blocker:conflict # wake for four transition classes — a review verdict landing (no
# when another PR merges under this one, and the time-based stale / 48h # pull_request_review trigger), blocker:ci-red set/cleared, blocker:conflict
# when another PR merges under this one, and time-based stale / 48h
# claim-reclaim. Events below carry the rest in seconds. Hourly trades ≤1h of # claim-reclaim. Events below carry the rest in seconds. Hourly trades ≤1h of
# latency on those four for dropping */15's four sweeps an hour at GitHub's # latency on those four for one full-board sweep at GitHub's 1-minute floor.
# 1-minute floor. Keep the cron — it is the discovery path, not a safety net. # If another engine writes some of those transitions, only the classes with
# no other writer bound the cadence; relax it only as that list shrinks.
schedule: [{cron: "0 * * * *"}] schedule: [{cron: "0 * * * *"}]
workflow_dispatch: # bootstraps missing labels on a fresh repo # A manual full-board sweep, including taxonomy bootstrap on a fresh repo.
workflow_dispatch:
pull_request_target: pull_request_target:
# Fork PRs; these carry the head/draft/review facts state:* derives from. # Fork PRs; these carry the head/draft/review facts state:* derives from.
# labeled/unlabeled are the handoff wake (state:needs-human confirmed here); # labeled/unlabeled are the handoff wake (state:needs-human confirmed here);
@ -398,11 +402,20 @@ Core state, blocker, work-queue, and release labels come from ceremony. Scope
rows remain consumer-owned because paths and surfaces differ by repository. rows remain consumer-owned because paths and surfaces differ by repository.
After adding the caller and configuration, run `workflow_dispatch` once to After adding the caller and configuration, run `workflow_dispatch` once to
bootstrap labels on a fresh repository. Scheduled and PR-triggered runs only bootstrap labels on a fresh repository. It is also the operator's general
reconcile; they do not repeatedly upsert the taxonomy. When a ceremony pin manual full-board sweep — the answer when the board looks wrong now rather
bump adds a core label, bump the pin first and then re-dispatch than after the next scheduled cadence:
`workflow_dispatch`; the scheduled sweep warns when the pinned taxonomy
declares a core label the repository lacks. ```sh
gh workflow run labels.yml -R <owner>/<repo>
```
Ceremony dogfoods the caller under the filename `self-labels.yml`, so the
equivalent command in this repository substitutes that filename. Scheduled
and PR-triggered runs only reconcile; they do not repeatedly upsert the
taxonomy. When a ceremony pin bump adds a core label, bump the pin first and
then re-dispatch `workflow_dispatch`; the scheduled sweep warns when the
pinned taxonomy declares a core label the repository lacks.
## Doctrine mirror ## Doctrine mirror