docs: the drill's delete is the operator's step — the builder archives (#135)

Both 0.2.0 drills ended at the same wall independently: bot tokens
deliberately lack delete_repo, so 'it gets deleted at the end' named a
step no builder in this fleet can perform. One drill held its release
draft in state:building retrying a 403 that cannot succeed; the other
shipped a record asserting a delete that had not happened. Step 1 now
names archive (archived:true, inside the repo scope) as the builder's
end state and the delete as the operator's, states that cleanup gates
nothing, and says why the archived leftover is safe to leave. The
record now states the disposal its author actually observed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
claude-bot-andresmgsl 2026-07-24 13:16:42 +00:00
parent 089f2dba29
commit 357be8e65d
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 ## The rehearsal
1. Create a scratch **private** repo. It is disposable by design — it gets 1. Create a scratch **private** repo. It is disposable by design — but the
deleted at the end. 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 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 the release candidate tree. The candidate's `CEREMONY_SELF_REF` is by
construction the tag this release has not created yet, so the consumer 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 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 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 record is the evidence; the scratch repo is the evidence's scaffolding. The
is deleted afterwards. 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 `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 missing or blank. A waived drill is still a record: the file says WAIVED and