diff --git a/skills/sourcehut-ci-cache/SKILL.md b/skills/sourcehut-ci-cache/SKILL.md index 170166f59afa46f376426649f5d172f75cc3099a..c1e6dd863b07b9bd3084c9868a880344cf81d19b 100644 --- a/skills/sourcehut-ci-cache/SKILL.md +++ b/skills/sourcehut-ci-cache/SKILL.md @@ -200,24 +200,29 @@ makes this class of failure visible at the task that causes it. ## The half-restored module cache -The most important paragraph here, and the one that looks like removable -boilerplate. +The block that looks like removable boilerplate, and is not. -Go writes its module cache read-only — module directories are `0555`. The -tarball preserves those modes, so an extraction can create a module directory -and then be **denied its own next file inside it**. The result is a cache HIT, -one swallowed `permission denied`, and a handful of packages failing to compile -against a dependency missing a single file — while unrelated packages pass, so -the log reads like a code bug. cover.sr.ht build **#284** is that failure. +A module cache that comes back incomplete — an interrupted upload, a truncated +object, a key written while a build was still running — produces a cache HIT and +then a handful of packages failing to compile against a dependency missing a +single file, while unrelated packages pass, so the log reads like a code bug. +cover.sr.ht build **#284** was that failure. -Two halves to the fix, and both are needed: +Go writes its module cache read-only (`0555` directories, `0444` files) and the +tarball keeps those modes. `art` copes with that on extraction — it creates +directories writable and applies the recorded modes at the very end +(`cachedir.go:extractTree`) — so a read-only tree no longer locks the restore +out of itself. What stays load-bearing: +- **the repair block** in `cache_restore`: `chmod -R u+w` (without it `rm -rf` + cannot remove a `0555` tree), then `go mod verify` as the gate, then + `rm -rf ~/go/pkg/mod` on failure. `go mod verify` recomputes each extracted + module's hash and is the only instrument that sees a file missing from a + directory Go otherwise trusts on sight — `go mod download` alone takes the + directory's existence as proof. - **`-modcacherw`** on the `go build` that populates the cache (in the APKBUILD's - `build()` for the apk-packaging projects), so the stored tree is writable. -- **the repair block** in `cache_restore`: `chmod -R u+w`, then `go mod verify` - as the gate, then `rm -rf ~/go/pkg/mod` on failure. `go mod verify` recomputes - each extracted module's hash and is the only instrument that sees a file - missing from a directory Go otherwise trusts on sight. + `build()` for the apk-packaging projects), so the stored tree is writable and + any extractor, not only `art`'s, can unpack it. Never soften the verify to `|| true`. A bad restore costs one cold download, which is the optimisation failing, not the build failing. The first build after