Merge pull request #128 from codex-bot-andresmgsl/build/118-release-0-2-0

release: 0.2.0
This commit is contained in:
Daniel Marin 2026-07-24 13:36:07 +01:00 committed by GitHub
commit 94e019b3fc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
34 changed files with 98 additions and 44 deletions

View file

@ -24,7 +24,7 @@ on:
env:
# A called workflow arrives without its repository. Keep this literal pin
# aligned with the ceremony release consumed by callers (issue #9 D3).
CEREMONY_SELF_REF: "0.1.0"
CEREMONY_SELF_REF: "0.2.0"
jobs:
scope:

View file

@ -129,7 +129,7 @@ env:
# `ref:` accepts ${{ env }}; `uses:` strings do not — which is why the
# shared logic arrives as script files via checkout, not as inner `uses:`
# references.
CEREMONY_SELF_REF: "0.1.0"
CEREMONY_SELF_REF: "0.2.0"
VERSION_SOURCE: ${{ inputs.version-source }}
jobs:

View file

@ -7,6 +7,37 @@ fragments — one `changelog.d/<issue>.md` per PR, never an edit to this
file — and the release PR assembles them into the next section here
(`bin/changelog-assemble`, #112).
## 0.2.0 — 2026-07-24
- `test/changelog-assembled.test.sh` — keep the trio interaction aligned with fragment mode: a dropped entry makes armed red too, while a hand-edited section leaves assembled as the sole red (#126).
- `actions/changelog-assembled` — a release PR's stamped section must be byte-for-byte what the fragments it consumed assemble to, replayed from the merge base; inapplicable trees pass with a NOTICE (#116).
- `changelog-armed` — treat `changelog.d/` as the arming, validate every development fragment, and require bare releases to consume the directory into their exact publishable section (#115).
- `lib/changelog.sh` + `bin/changelog-assemble` — read the `changelog.d/` fragments, assemble one release section (canonical group order, one shape per repo), and consume exactly what was published (#114).
- BUILDER.md — the directed hold is the parked claim's fifth shape, its attention demand is acknowledged in the declaration comment, and its board bookkeeping covers in-flight work; TRIAGE.md no longer excludes it (#113).
- Ceremony adopts `changelog.d/` — a PR writes one fragment per issue instead of editing `CHANGELOG.md`, the release PR assembles the section, and `## Unreleased` is gone (#112).
- BUILDER.md — the handed-off PR is the parked claim's fourth shape, its handoff is its declaration, and shape 2 covers the round awaiting its first verdicts (#109).
- `labels-reconcile` — warn once per sweep when a repository lacks labels declared by the pinned core taxonomy (#105).
- `LABELS.md` — drop the vendored scope-table enumeration; the per-repo set lives in `.github/labels.conf` and the repo's own CONTRIBUTING (#104).
- `labels-reconcile` — a degraded mergeability/checks read now logs gh's actual stderr (collapsed, bounded) beside the byte-identical counted line, and the blind-sweep warning leads with the observed reason instead of asserting the permissions cause (#101).
- Changelog publication — count entries instead of bytes, refuse dangling grouped headings, and seed grouped re-arms with Added/Changed/Fixed (#98).
- `labels-reconcile` — grant callers private-repo check reads and warn when an entire PR sweep is blind (#95).
- `labels-reconcile` — the bootstrap now retires the six GitHub defaults `LABELS.md` publishes as deleted, tolerating both an already-absent label and a refused delete (#93).
- `issueflow-reconcile` — a triage-authored issue arrival stands down with exit 0 instead of killing the run before the sweep (#91).
- FLEET.md — the assignee's `attention` wake: one role-independent trigger ahead of every per-role list, one acked session per demand; a spec on paper until `duty.sh` polls it (#86).
- `attention` doctrine — define its assignee-owned pickup, ack, queue and clock semantics across labels, triage, and builder roles (#85).
- `attention` — add the issue-only, hand-set assignee-demand flag to the core label taxonomy (#84).
- One issue at a time counts build work in flight: the parked claim's three shapes, its declared-never-inferred comment, and triage's duty to name a directed hold as a park (#77).
- FLEET.md — the operator notifier's `needs-ruling` queue (one tracked message per item, edited in place across the rungs) and triage's past-24h wake condition; a spec on paper until an operator updates the box (#74).
- The sweep observes the escalation contract: a malformed escalation is named field-by-field, and the ladder's 12h/24h rungs each draw one comment to the flag-setter — comment-only, per-episode, both surfaces (#73).
- Ruling doctrine — define every human-owned trigger, the fixed escalation shape, and the 024h builder-to-triage ladder (#72).
- `issueflow-reconcile` — nudge once when an `offsite` flag outlives every visible cross-referenced PR (#69).
- `offsite` — protect claimed issues whose PR lives in another repository from the claim-reclaim clock (#68).
- `issueflow-reconcile` — keep cross-repo references out of local dependency decisions and require triage to resolve cross-repo blockers by hand (#61).
- `actions/runner-isolated` — a `pull_request`-triggered job may never run on a self-hosted runner (#58).
- Cross-repo doctrine: the panel is the PR's repo's roster, a review request is authorization but not panel membership, and `Part of <repo>#N` replaces the `Closes #N` that cannot cross repos (#57).
- The sweep's `needs-ruling` invariants, one implementation for both surfaces: the issue-side staleness exemption, the bare-flag check (comment-only, the label is never removed), and the 7-day nudge to the decider (#52).
- `needs-ruling` — the cross-cutting flag for a pending human decision, excluded from `state:needs-human` and from the staleness sweep (#51).
## 0.1.0 — 2026-07-22
- `lib/version.sh` — one version abstraction, `file` and `package-json` backends (#3).

View file

@ -1 +1 @@
0.1.1-dev
0.2.0

View file

@ -1 +0,0 @@
- `labels-reconcile` — a degraded mergeability/checks read now logs gh's actual stderr (collapsed, bounded) beside the byte-identical counted line, and the blind-sweep warning leads with the observed reason instead of asserting the permissions cause (#101).

View file

@ -1 +0,0 @@
- `LABELS.md` — drop the vendored scope-table enumeration; the per-repo set lives in `.github/labels.conf` and the repo's own CONTRIBUTING (#104).

View file

@ -1 +0,0 @@
- `labels-reconcile` — warn once per sweep when a repository lacks labels declared by the pinned core taxonomy (#105).

View file

@ -1 +0,0 @@
- BUILDER.md — the handed-off PR is the parked claim's fourth shape, its handoff is its declaration, and shape 2 covers the round awaiting its first verdicts (#109).

View file

@ -1 +0,0 @@
- Ceremony adopts `changelog.d/` — a PR writes one fragment per issue instead of editing `CHANGELOG.md`, the release PR assembles the section, and `## Unreleased` is gone (#112).

View file

@ -1 +0,0 @@
- BUILDER.md — the directed hold is the parked claim's fifth shape, its attention demand is acknowledged in the declaration comment, and its board bookkeeping covers in-flight work; TRIAGE.md no longer excludes it (#113).

View file

@ -1 +0,0 @@
- `lib/changelog.sh` + `bin/changelog-assemble` — read the `changelog.d/` fragments, assemble one release section (canonical group order, one shape per repo), and consume exactly what was published (#114).

View file

@ -1 +0,0 @@
- `changelog-armed` — treat `changelog.d/` as the arming, validate every development fragment, and require bare releases to consume the directory into their exact publishable section (#115).

View file

@ -1 +0,0 @@
- `actions/changelog-assembled` — a release PR's stamped section must be byte-for-byte what the fragments it consumed assemble to, replayed from the merge base; inapplicable trees pass with a NOTICE (#116).

View file

@ -1 +0,0 @@
- `test/changelog-assembled.test.sh` — keep the trio interaction aligned with fragment mode: a dropped entry makes armed red too, while a hand-edited section leaves assembled as the sole red (#126).

View file

@ -1 +0,0 @@
- `needs-ruling` — the cross-cutting flag for a pending human decision, excluded from `state:needs-human` and from the staleness sweep (#51).

View file

@ -1 +0,0 @@
- The sweep's `needs-ruling` invariants, one implementation for both surfaces: the issue-side staleness exemption, the bare-flag check (comment-only, the label is never removed), and the 7-day nudge to the decider (#52).

View file

@ -1 +0,0 @@
- Cross-repo doctrine: the panel is the PR's repo's roster, a review request is authorization but not panel membership, and `Part of <repo>#N` replaces the `Closes #N` that cannot cross repos (#57).

View file

@ -1 +0,0 @@
- `actions/runner-isolated` — a `pull_request`-triggered job may never run on a self-hosted runner (#58).

View file

@ -1 +0,0 @@
- `issueflow-reconcile` — keep cross-repo references out of local dependency decisions and require triage to resolve cross-repo blockers by hand (#61).

View file

@ -1 +0,0 @@
- `offsite` — protect claimed issues whose PR lives in another repository from the claim-reclaim clock (#68).

View file

@ -1 +0,0 @@
- `issueflow-reconcile` — nudge once when an `offsite` flag outlives every visible cross-referenced PR (#69).

View file

@ -1 +0,0 @@
- Ruling doctrine — define every human-owned trigger, the fixed escalation shape, and the 024h builder-to-triage ladder (#72).

View file

@ -1 +0,0 @@
- The sweep observes the escalation contract: a malformed escalation is named field-by-field, and the ladder's 12h/24h rungs each draw one comment to the flag-setter — comment-only, per-episode, both surfaces (#73).

View file

@ -1 +0,0 @@
- FLEET.md — the operator notifier's `needs-ruling` queue (one tracked message per item, edited in place across the rungs) and triage's past-24h wake condition; a spec on paper until an operator updates the box (#74).

View file

@ -1 +0,0 @@
- One issue at a time counts build work in flight: the parked claim's three shapes, its declared-never-inferred comment, and triage's duty to name a directed hold as a park (#77).

View file

@ -1 +0,0 @@
- `attention` — add the issue-only, hand-set assignee-demand flag to the core label taxonomy (#84).

View file

@ -1 +0,0 @@
- `attention` doctrine — define its assignee-owned pickup, ack, queue and clock semantics across labels, triage, and builder roles (#85).

View file

@ -1 +0,0 @@
- FLEET.md — the assignee's `attention` wake: one role-independent trigger ahead of every per-role list, one acked session per demand; a spec on paper until `duty.sh` polls it (#86).

View file

@ -1 +0,0 @@
- `issueflow-reconcile` — a triage-authored issue arrival stands down with exit 0 instead of killing the run before the sweep (#91).

View file

@ -1 +0,0 @@
- `labels-reconcile` — the bootstrap now retires the six GitHub defaults `LABELS.md` publishes as deleted, tolerating both an already-absent label and a refused delete (#93).

View file

@ -1 +0,0 @@
- `labels-reconcile` — grant callers private-repo check reads and warn when an entire PR sweep is blind (#95).

View file

@ -1 +0,0 @@
- Changelog publication — count entries instead of bytes, refuse dangling grouped headings, and seed grouped re-arms with Added/Changed/Fixed (#98).

54
drills/0.2.0.md Normal file
View file

@ -0,0 +1,54 @@
# 0.2.0 — drill record
Run 2026-07-24 by `codex-bot-andresmgsl` against the release candidate at
PR #128 head `b632c19e97678653547252d3e402ca93907b2d50`.
Where: disposable private repo
`codex-bot-andresmgsl/ceremony-drill-0.2.0`, carrying the
`docs/CONSUMERS.md` release caller and a fragment-mode fixture armed at
`0.2.0-dev`. The fixture had `changelog.d/README.md`, one release fragment,
and a non-blank drill record. The repository is archived, pending the
operator's delete.
## Candidate-ref deviation
The pure consumer path still cannot resolve `CEREMONY_SELF_REF: "0.2.0"`
before the candidate creates that tag. No `0.2.0` branch was created in
`heavy-duty/ceremony`. The scratch caller instead used the already-existing
`claude-bot-andresmgsl/ceremony@drill/0.2.0` scaffold, whose parent candidate
tree is byte-identical to PR #128's tree and whose only additional change
rewrites both `CEREMONY_SELF_REF` carriers to candidate SHA
`682b9cb8929aa8c50a3101b64ca57fee7b09fef1`. All runtime machinery was
therefore fetched from the 0.2.0 candidate tree.
## Probes
| # | probe | run | result |
|---|---|---|---|
| 1 | merge-door ceremony | 30090148675 (attempt 1) | ✅ one `0.2.0` release; tag equals merge commit; main re-armed to `0.2.1-dev` with only `changelog.d/README.md` |
| 2 | mislabeled ordinary PR | 30090024126 | ✅ green NOTICE no-op; no tag or release |
| 3 | bare-version PR without `release` | 30090111403 | ✅ refused at decide; no tag or release |
| 4 | re-run completed ceremony | 30090148675 (attempt 2) | ✅ refused because tag/release already existed; release count stayed one |
| 5 | manual matching tag | 30090226056 | ✅ `0.3.0` published with its changelog section; main untouched |
| 6 | mismatched tag | 30090251726 | ✅ refused before publication; no `9.9.9` release |
The merge-door `0.2.0` tag and PR #4 merge commit were both
`f74a52447ae9abcbc61cf75d38ebf8f0ca28a427`. Its release body was exactly:
```text
- Fragment mode is exercised by the 0.2.0 drill.
```
## Failures and setup corrections
The scratch repository's root commit triggered run 30089943081 before a
parent commit existed, so fact gathering could not read a base version
(discussion #132). An empty armed-state baseline commit then ran green as
30089962334.
The first preparation of the unlabeled refusal probe assembled the fragment
but accidentally left `VERSION` at `0.2.0-dev`; run 30090059412 correctly
treated that merge as a green non-ceremony no-op. The merge was reverted,
the fixture was restored to armed fragment shape, and probe 3 was repeated
with the intended bare `0.2.0` transition. The corrected probe refused as
required and created nothing.

View file

@ -12,20 +12,17 @@ drill is where they run live *before* a version rests on them.
1. Create a scratch **private** repo. It is disposable by design — it gets
deleted at the end.
2. Install the docs/CONSUMERS.md caller stubs, pinned to the release
candidate ref. A branch ref works: refs are static identifiers — the
family's own drill doctrine.
2. Install the docs/CONSUMERS.md caller stubs, pinned to a fork ref carrying
the release candidate tree. The candidate's `CEREMONY_SELF_REF` is by
construction the tag this release has not created yet, so the consumer
path cannot resolve directly from the candidate. Rewrite that pin to a
canonical candidate SHA in every carrier on the fork ref, and record the
fork ref and rewritten pin in the drill record.
**Except for the first release** (learned drilling 0.1.0, #11): the
stubs' consumer path fetches ceremony at `CEREMONY_SELF_REF` — the very
ref the first drill exists to rehearse creating — so the pure pinned
path cannot run before some `X.Y.Z` ref exists, and a branch named like
the tag must NOT be created on the canonical repo to paper over it (it
would shadow the tag for every consumer until someone remembers to
delete it). The first drill instead pins the callers to a fork ref
carrying the candidate tree with `CEREMONY_SELF_REF` rewritten to the
candidate SHA in every pin carrier, and records that one-line deviation
in its record. From the second release on, this paragraph is moot.
Never create a branch named like the tag on `heavy-duty/ceremony` to
paper over this deadlock: it would shadow the tag for every consumer
until someone remembers to delete it. The 0.1.0 drill (#11) is the
worked example of this standing fork-ref shape.
3. Give it a fixture `VERSION` / `CHANGELOG.md` / `changelog.d/` /
`drills/` in the armed state (`X.Y.Z-dev`, the fragments directory with
its `README.md` marker plus at least one fragment for the ceremony to