ceremony/drills/0.4.1.md
cluade-reviewer-andresmgsl 4057c59354
All checks were successful
CI / test (pull_request) Successful in 1m29s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 6s
CI / action-exercise (pull_request) Successful in 5s
CI / docs-sync-exercise (pull_request) Successful in 5s
labels / labels (pull_request) Successful in 1m33s
drill(0.4.1): the post-merge rehearsal passed — record both runs
#191's last acceptance criterion was a live drill against the MERGED tree,
not the candidate. Run against `fda5657`:

  probe 1  merge door   one release 0.4.1, changelog body, main re-armed
                        to 0.4.2-dev, both assets uploaded
  probe 3  no label     refused, nothing created
  probe 5  tag door     0.5.0 published, main VERSION untouched
  probe 6  bad tag      refused, nothing created

The fixture carried an artifact hook this time, dropping `drill asset.tgz`
and `a&b.tgz`. Both survived under those exact names — the encoding fix
proven end to end, in the place it would have failed: after the tag exists,
mid-publish.

The record keeps run 1 (the failure at 9a229ee) beside run 2, because the
failure is why #191 exists and a record that quietly replaced it would be
the kind of tidy history this repo refuses.

Refs #191

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 15:06:53 +00:00

3.1 KiB

0.4.1 — drill record

Two runs. The first, 2026-08-04 against release PR !190 head 9a229ee, failed: both doors were inoperable and the release could not publish at all. The second, after #191 landed as fda5657, passed. Both are recorded, because the first is why the second exists.

Run 2 — against merged main fda5657 (the one that counts)

Where: disposable private repo heavy-duty/ceremony-drill-0.4.1-final, armed at 0.4.1-dev, carrying the docs/CONSUMERS.md release caller, a fragment-mode fixture, and — unlike run 1 — an artifact hook dropping two deliberately awkward filenames, drill asset.tgz and a&b.tgz. Archived at the end; the operator's delete is pending, and cleanup gates nothing.

Candidate ref: cluade-reviewer-andresmgsl/ceremony@drill-main, parent fda5657, whose only extra commit rewrites both CEREMONY_SELF_REF carriers to that SHA — release.yml's self-checkout is hardcoded to heavy-duty/ceremony, so only a SHA that resolves there can stand in for a tag that does not exist yet. No 0.4.1 branch was created on heavy-duty/ceremony.

# probe result
1 merge-door ceremony exactly one release 0.4.1; body is the version's own changelog section; main re-armed to 0.4.2-dev; both assets uploaded
3 bare version, no release label refused — release count stayed 1
5 tag door, matching tag 0.5.0 published with its own section and both assets; main VERSION untouched
6 mismatched tag 9.9.9 refused — release count stayed 2

Not run: probe 2 beyond the implicit -dev no-op at fixture push, and probe 4 — a re-run of a completed ceremony, which needs a re-trigger this round did not exercise. Recorded as not-run rather than implied.

The asset names survived intact: a&b.tgz and drill asset.tgz both appear under those exact names on both releases. Before #191's fix the space made curl reject the URL outright and the & split the query — the failure landing after the tag exists, mid-publish, which is the worst place this door has.

Run 1 — against 9a229ee, before the fix (FAILED)

Recorded in full because the failure is the reason #191 exists.

# probe result
1 merge-door ceremony decide refused: labeled=no for a PR that was labeled and was merged
5 tag door gh: command not found at publish the release
6 mismatched tag refused, creating nothing

Root cause, both doors: lib/facts.sh and release.yml spoke gh, which the runner image does not ship. facts.sh read any failure as a definite no, so a missing binary silently demoted a release ceremony to "a bare push". Release count across the whole of run 1: 0.

What changed between them

#191, merged as fda5657: both doors onto lib/forge.sh; a read that did not complete refuses instead of fabricating a no; forgejo_api_base refuses an empty REPO so repos//… cannot be addressed; release asset names percent-encoded.

Every refusal path, in both runs, created nothing. That property never broke — what broke was the doors' ability to say yes.