drill(0.4.1): record the rehearsal — both doors are inoperable here
All checks were successful
CI / test (pull_request) Successful in 1m26s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 5s
CI / action-exercise (pull_request) Successful in 5s
CI / docs-sync-exercise (pull_request) Successful in 5s
labels / labels (pull_request) Successful in 1m45s
All checks were successful
CI / test (pull_request) Successful in 1m26s
CI / release-exercise (pull_request) Successful in 11s
CI / self-guards (pull_request) Successful in 5s
CI / action-exercise (pull_request) Successful in 5s
CI / docs-sync-exercise (pull_request) Successful in 5s
labels / labels (pull_request) Successful in 1m45s
The drill ran and FAILED, and the record says so. Merge door: lib/facts.sh reads the release label with `gh api`, the runner image has no gh, the fact comes back "no", and decide fail-closes on a wrong fact — reproduced twice. Tag door: clears every gate the merge door fails, then dies at `gh release create`. Release count in the scratch repo at the end: 0. Every refusal created nothing, which is the property the drill exists to check. drill-recorded wants a record, not a passing result — this is the honest one, and it says 0.4.1 cannot publish from this instance until facts.sh and the publish call sites are ported off gh. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9a229ee643
commit
abb1c818a3
1 changed files with 79 additions and 0 deletions
79
drills/0.4.1.md
Normal file
79
drills/0.4.1.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# 0.4.1 — drill record
|
||||
|
||||
Run 2026-08-04 by `cluade-reviewer-andresmgsl` against release PR !190 head
|
||||
`9a229ee643291c27dbd404fa97e4dcc7e6ed3b17`.
|
||||
|
||||
**This drill FAILED. Both doors of the release workflow are inoperable on
|
||||
`forgejo.heavyduty.builders`.** The record is written down as the guard
|
||||
requires, and the failure is the finding: 0.4.1 cannot publish from this
|
||||
instance until `lib/facts.sh` and the publish steps are ported off `gh`.
|
||||
|
||||
Where: disposable private repo `heavy-duty/ceremony-drill-0.4.1`, armed at
|
||||
`0.4.1-dev` with the `docs/CONSUMERS.md` release caller, a fragment-mode
|
||||
fixture (`changelog.d/README.md` + one fragment), and a non-blank drill
|
||||
record. Archived at the end; the operator's delete is pending, and per
|
||||
`drills/README.md` cleanup gates nothing.
|
||||
|
||||
## Deviations
|
||||
|
||||
* **Candidate ref.** The pure consumer path cannot resolve
|
||||
`CEREMONY_SELF_REF: "0.4.1"` before the candidate creates that tag, and
|
||||
`release.yml`'s self-checkout is hardcoded to `heavy-duty/ceremony`. No
|
||||
`0.4.1` branch was created there. The caller used
|
||||
`cluade-reviewer-andresmgsl/ceremony@drill-0.4.1` (`f148255`), whose parent
|
||||
is `9a229ee` and whose only extra commit rewrites both `CEREMONY_SELF_REF`
|
||||
carriers to that same canonical candidate SHA.
|
||||
* **Log access.** The drill repo was flipped public for ~8 minutes to read
|
||||
job logs — Forgejo's web log route (`/{owner}/{repo}/actions/runs/{run}/
|
||||
jobs/{job}/logs`) 404s for a token-authenticated private repo, and the
|
||||
`/api/v1` log routes 404 outright. Restored to private, then archived.
|
||||
Recorded because it is a real deviation from "scratch **private** repo".
|
||||
|
||||
## Probes
|
||||
|
||||
| # | probe | run | result |
|
||||
|---|---|---|---|
|
||||
| 1 | merge-door ceremony | 12 (and 7, at `0.4.1`) | ❌ **FAILED** — `decide` refused; no tag, no release, main left bare |
|
||||
| 2 | `-dev` push is a green NOTICE no-op | 9, and the fixture push | ✅ green no-op, nothing created |
|
||||
| 3 | bare version without the `release` label refuses | — | ⚠️ not run as an independent probe; probe 1 refused through exactly this path, because the label fact read `no` |
|
||||
| 4 | re-run of a completed ceremony refuses | — | ⚠️ **not reachable** — no ceremony ever completed to re-run |
|
||||
| 5 | tag-door release from a matching tag | 14 | ❌ **FAILED** — `gh: command not found` at *publish the release*; no release |
|
||||
| 6 | mismatched tag refuses | 16 | ✅ `tag '9.9.9' does not match the tree's version '0.4.2' — creating nothing` |
|
||||
|
||||
Release count in the scratch repo at the end: **0**. Every refusal path
|
||||
created nothing, which is the one property the drill demands of a refusal.
|
||||
|
||||
## Finding 1 — the merge door cannot read its own label (`lib/facts.sh`)
|
||||
|
||||
Probe 1, reproduced twice (`0.4.1`, then `0.4.2` after re-arming):
|
||||
|
||||
```
|
||||
facts: ver=0.4.2 base_ver=0.4.2-dev released= labeled=no
|
||||
decide: the version transitioned ('0.4.2-dev' -> '0.4.2') but no merged,
|
||||
release-labeled PR is behind this commit — a release is a labeled
|
||||
ceremony PR, not a bare push — creating nothing.
|
||||
```
|
||||
|
||||
The PR *was* labeled `release` and *was* merged. `lib/facts.sh` derives that
|
||||
fact with `gh api "repos/$GITHUB_REPOSITORY/commits/$MERGE_SHA/pulls"`, and
|
||||
the Forgejo runner image ships no `gh`. Its own comment says *"A failed API
|
||||
call reads as 'no label', which row 5 refuses: fail-closed."* — so the guard
|
||||
behaved exactly as designed on a fact that was wrong.
|
||||
|
||||
`#188` ported the reconcilers and `labels-scope` onto `lib/forge.sh`;
|
||||
`lib/facts.sh` was outside that scope and is still gh-only.
|
||||
|
||||
## Finding 2 — the tag door cannot publish (`gh release create`)
|
||||
|
||||
Probe 5: the tag matched, the version assert passed, and the job then died
|
||||
at *publish the release* with `gh: command not found` (exitcode 127). The tag
|
||||
door has no decide and no label check, so it clears every gate the merge door
|
||||
fails — and then falls at the same missing binary.
|
||||
|
||||
## Consequence
|
||||
|
||||
Merging !190 will run this identical path on `heavy-duty/ceremony` and refuse,
|
||||
creating nothing. **There is no door through which 0.4.1 can publish on this
|
||||
instance today.** The fix is the same shape as #188's, one layer out:
|
||||
`lib/facts.sh` and `release.yml`'s `gh release view` / `gh release create`
|
||||
call sites onto `forge_*`. That is new work, not a re-review of !190.
|
||||
Loading…
Reference in a new issue