Merge pull request #147 from claude-bot-andresmgsl/build/135-drill-cleanup

docs: the drill's delete is the operator's step — the builder archives
This commit is contained in:
Daniel Marin 2026-07-24 14:46:28 +01:00 committed by GitHub
commit e8675548ce
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 35 additions and 4 deletions

12
changelog.d/135.md Normal file
View file

@ -0,0 +1,12 @@
### Fixed
- `drills/README.md` no longer tells the builder to delete the scratch repo —
a step no fleet identity can perform, because `delete_repo` is deliberately
absent from bot tokens. The builder's end state is **archive**
(`archived: true`, inside the `repo` scope); the delete is the operator's,
and cleanup gates nothing — not ready-for-review, not the panel, not the
merge. The drill record now names the scratch repo by `owner/name` and
states the disposal its author actually observed, never one that has not
happened: both 0.2.0 drills hit the missing-scope wall independently, one
stalling a release draft on an impossible 403, the other shipping a record
asserting a delete that never ran (#135).

View file

@ -10,8 +10,21 @@ drill is where they run live *before* a version rests on them.
## The rehearsal
1. Create a scratch **private** repo. It is disposable by design — it gets
deleted at the end.
1. Create a scratch **private** repo. It is disposable by design — but the
disposal is split, because the builder cannot perform the delete: at the
end the builder **archives** it (`PATCH /repos/{owner}/{repo}` with
`archived: true`, inside the `repo` scope every fleet identity holds),
and **deleting it is the operator's step**`delete_repo` is
deliberately absent from bot tokens, fleet doctrine and not a
misconfiguration, so no builder that will ever run a drill can do it.
Do not retry the delete and do not wait on it: both 0.2.0 drills ended
at that wall independently (#135) — one builder held its release draft
in `state:building` re-trying a 403 that cannot succeed, the other wrote
a record asserting a delete that had not happened. **Cleanup gates
nothing** — not ready-for-review, not the review panel, not the merge.
The archived leftover is safe to leave: private, no consumers, and
outside `heavy-duty/ceremony`'s ref namespace — the namespace the
"never a branch named like the tag" rule below protects.
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
@ -44,8 +57,14 @@ drill is where they run live *before* a version rests on them.
One file per version, `drills/X.Y.Z.md` — the shape the siblings use: what
was run, where, the result of each probe, failures written down plainly. The
record is the evidence; the scratch repo is the evidence's scaffolding and
is deleted afterwards.
record is the evidence; the scratch repo is the evidence's scaffolding. The
record names the scratch repo by full `owner/name` and states its disposal
state **as its author observed it when the record was written** — archived
and pending the operator's delete, or deleted only if the author genuinely
performed the delete. Never a disposal the author did not observe: the
record is the only thing that survives the drill, and 0.2.0's record shipped
its first draft asserting a cleanup that had not happened (#135) — false
evidence in the one file whose job is to be evidence.
`actions/drill-recorded` refuses any bare-version tree whose record is
missing or blank. A waived drill is still a record: the file says WAIVED and