Merge pull request 'drills/0.4.1.md — the post-merge rehearsal passed; record both runs (#191)' (#194) from build/191-drill-record into main
All checks were successful
CI / test (push) Successful in 1m30s
CI / release-exercise (push) Has been skipped
CI / self-guards (push) Successful in 5s
CI / action-exercise (push) Successful in 5s
CI / docs-sync-exercise (push) Successful in 5s
release / release (push) Successful in 6s
All checks were successful
CI / test (push) Successful in 1m30s
CI / release-exercise (push) Has been skipped
CI / self-guards (push) Successful in 5s
CI / action-exercise (push) Successful in 5s
CI / docs-sync-exercise (push) Successful in 5s
release / release (push) Successful in 6s
Reviewed-on: #194 Reviewed-by: grok-reviewer-andresmgsl <andres+3@heavyduty.builders> Reviewed-by: codex-reviewer-andresmgsl <andres+2@heavyduty.builders> Reviewed-by: kimi-reviewer-andresmgsl <andres+4@heavyduty.builders>
This commit is contained in:
commit
1ddefe79d9
1 changed files with 106 additions and 0 deletions
106
drills/0.4.1.md
Normal file
106
drills/0.4.1.md
Normal file
|
|
@ -0,0 +1,106 @@
|
||||||
|
# 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 | run | result |
|
||||||
|
|---|---|---|---|
|
||||||
|
| 1 | merge-door ceremony | 637 | ✅ exactly one release `0.4.1`; body is the version's own changelog section; tag and release on merge commit `4a83fa1b`; **main re-armed to `0.4.2-dev`**; both assets uploaded |
|
||||||
|
| 2 | mislabeled ordinary PR | 652 | ✅ green no-op in **7s** on merge commit `e71df4e3` — release count stayed **2**, no tag created |
|
||||||
|
| 3 | bare version, no `release` label | 638 | ✅ refused at `b091aff2` — release count stayed **1** |
|
||||||
|
| 4 | re-run of the completed ceremony | 654 | ✅ refused in **8s** on merge commit `82e7d11b` — release count stayed **2**, and tag `0.4.1` **stayed on `4a83fa1b`**, the original merge commit |
|
||||||
|
| 5 | tag door, matching tag | 639 | ✅ `0.5.0` published with its own section and both assets; **main VERSION untouched** |
|
||||||
|
| 6 | mismatched tag | 640 | ✅ `9.9.9` refused — release count stayed **2**; the tag exists, the release does not |
|
||||||
|
|
||||||
|
Probes 2 and 4 were run last, at 15:23–15:28Z, on the same consumer: it was
|
||||||
|
un-archived for them and archived again at the end. Nothing else about the
|
||||||
|
run changed — same candidate ref, same caller pin.
|
||||||
|
|
||||||
|
**Probe 4 diverges in mechanism, not in what it proves.** The 0.3.0 and 0.4.0
|
||||||
|
siblings re-ran the completed ceremony's workflow run (GitHub's "attempt 2").
|
||||||
|
Forgejo 8.0.3 exposes no run-rerun API — there are no `actions/runs/{id}`
|
||||||
|
routes in its swagger at all — so the ceremony was re-run by reproducing its
|
||||||
|
input instead: main re-armed to `0.4.1-dev` (setup run 653), then a second
|
||||||
|
`release`-labeled PR stamping bare `0.4.1` merged on top. That is the same
|
||||||
|
state the door refuses on, reached by a push rather than a re-trigger, and it
|
||||||
|
is stricter than the sibling shape in one way — it re-enters through
|
||||||
|
`facts` → `decide` rather than replaying a decided run.
|
||||||
|
|
||||||
|
Which refusal fired is measurable even without run logs. Replaying the
|
||||||
|
door's own inputs against the live consumer at `82e7d11b`:
|
||||||
|
|
||||||
|
```
|
||||||
|
facts: ver='0.4.1' base_ver='0.4.1-dev' released='' labeled='yes'
|
||||||
|
decide: ceremony=yes
|
||||||
|
```
|
||||||
|
|
||||||
|
So `decide` said **go** — a labeled bare transition is row 6 — and the stop
|
||||||
|
came from the merge door's own pre-publish assert, `release.yml:216-219`,
|
||||||
|
whose comment names this exact probe ("what makes a re-run of a completed
|
||||||
|
ceremony refuse instead of clobber"): the tag existed, so it refused before
|
||||||
|
`forge_tag_create` ever ran. The second net behind it is #191's own verb,
|
||||||
|
and it reads this consumer correctly:
|
||||||
|
|
||||||
|
```
|
||||||
|
forge_release_exists 0.4.1 -> yes 0.5.0 -> yes 9.9.9 -> no
|
||||||
|
```
|
||||||
|
|
||||||
|
`9.9.9` is the probe-6 receipt in the same breath: the tag exists, the
|
||||||
|
release does not.
|
||||||
|
|
||||||
|
Evidence for every probe here is the run conclusion plus the repository
|
||||||
|
state before and after — this instance serves no run logs (the API 404s on
|
||||||
|
every log route), so no probe's result is quoted from a log line.
|
||||||
|
|
||||||
|
End state, as observed when this was written: releases `0.4.1` and `0.5.0`
|
||||||
|
and nothing else; tags `0.4.1` on `4a83fa1b`, `0.5.0` and `9.9.9` on
|
||||||
|
`b091aff2`; the consumer's `main` left at bare `0.4.1` where probe 4 stopped
|
||||||
|
it, private and archived.
|
||||||
|
|
||||||
|
**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.
|
||||||
Loading…
Reference in a new issue