fix(retire): finish hello-lib, and stop rebuild resurrecting pipelines #595
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/retire-hello-lib-residue"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Two retirements were left half done, and both failed the same structural way: under
prune: false, removing a declaration stops Flux managing an object — it does not delete it.hello-lib
ad45bd04deletedgitmirrors/hello-lib.yamland stopped there. Both CRs carryRetain, so nothing was ever going to clean them up. Four days later the residue is:None of it is declared anywhere in this repository. The deleted file's own header said what to do instead: "Retiring a repo is still a deliberate act: set deletionPolicy: Delete first, per README.md."
The fence, and why it differs from the pipelines tombstone
The pipelines Job refuses if
deletionPolicysaysDelete, because archiving kept the code. Here the intent is destruction, so the safety property cannot be "never destroy" — it has to be "destroy only what is proven empty."The Job reads the repository from Forgejo and refuses unless it is
empty, zero-size, and still repository id 391. Pinning the id matters: a name can be recycled, and a futuresean/hello-libholding real code must not be deleted by a stale Job. That proof is exactly the checkad45bd04never had.It needs no credential — the repository is public, so the fence is an anonymous read against the in-cluster Forgejo service.
Order is enforced: mirror released first (it is the one still trying to write to Codeberg), emptiness proven, only then the policy flip, then the effect verified as a 404.
pipelines — a live bug
d6639f8aarchived it in six files: the two gitmirror CRs and nothing else. It is still inrepository-bootstrap.json, somake rebuildstill re-creates and re-importssean/pipelinesfrom Codeberg — precisely what that commit said archiving would stop. It is also still in the management grants, so the bootstrap re-grantsbinjovi-operator-botadmin on an archived repo every cold rebuild.Both entries go. Seed 42 → 41,
completionswith it, grants 43 → 42.repository-retirement/is durableUnlike
pipelines-retirement/, which is documented as delete-the-whole-thing-when-drained. Retirement recurs, and every one leaves orphans that only a Job like this can release. Individual tombstones are still one-shot — "AFTER IT RUNS this file is onegit rm" — but the directory outlives them.Verification
tests/hello-lib-retired.shpins the emptiness fence, the id pin, the pinned RBAC and its exact verbs, the release order, and that the policy flip comes after the proof. Five controls confirmed red against the real manifest:The guard also caught a bug in itself during development: a loose
deletionPolicy":"Delete"pattern matched the mirror's refuse-check rather than the patch body, so the ordering assertion fired on correct code. Tightened to the patch body.Passing:
every-guard-has-a-caller,hello-lib-retired,pipelines-archived,binjovi-repository-bootstrap,binjovi-collaborator-bootstrap,binjovi-service-handoff,gitmirror-fleet,retirement-jobs-are-replaceable,binjovi.Pre-flight recorded for the destructive step:
sean/hello-libconfirmedempty: true, size 0,git ls-remotereturns nothing, id 391 matching the CR'sstatus.repositoryID. 45 repositories before the change; expect exactly 44 after and no other change.Not in this PR
pipelinesstill appears in five RBAC rules and five binjovi binding modules, and four guards actively require it —binjovi-service-handoff.sh:10,14,binjovi-active-webhook-handoff.sh:12,forgejo_service_catalog_test.exs:6-9. Unwinding guards written to prevent that edit is its own deliberate change, not something to slip into a cleanup.https://claude.ai/code/session_01TdW5FSvRJW8CtGnpd29Xp8
3ea1019d2d2c7f70c224