commit 04e04f48214b61a9eb5ea006c9e23407d8f56c69
parent 80c2474810edca4672c4a2a7cbc57bd865fd558d
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 28 Sep 2026 13:49:40 -0400
docker: build-site.sh's asset sync only ever removes an .svg (review N3)
sync_public_assets removed any listed name the repo no longer had; a damaged
or hand-edited /site/.tracked-public-assets naming a file compose writes
(corpus.json) would have deleted it before compose ran. The removal loop now
skips every name that is not an .svg. The sync test lists corpus.json and
checks it survives; without the guard it fails (ENOENT). The W3c record says so.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
3 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/common/publish/buildImage.test.ts b/common/publish/buildImage.test.ts
@@ -71,9 +71,12 @@ test("build-site.sh's asset sync ships a changed svg, drops a removed one, and t
assert.equal(existsSync(path.join(dest, "stale.json")), false);
assert.equal(readFileSync(list, "utf8"), "globe.svg\nkofi-symbol.svg\n");
- // The repo changes one asset and drops another.
+ // The repo changes one asset and drops another. And a list naming a file
+ // compose writes (a hand-edited or damaged list) must not cost the site it:
+ // only an .svg is ever removed.
writeFileSync(path.join(src, "globe.svg"), "<svg>v2</svg>");
rmSync(path.join(src, "kofi-symbol.svg"));
+ writeFileSync(list, "globe.svg\nkofi-symbol.svg\ncorpus.json\n");
sync();
assert.equal(read("globe.svg"), "<svg>v2</svg>", "a changed asset is shipped");
assert.equal(existsSync(path.join(dest, "kofi-symbol.svg")), false, "a removed asset stops shipping");
diff --git a/docker/build-site.sh b/docker/build-site.sh
@@ -59,6 +59,7 @@ sync_public_assets() { # <image public dir> <site public dir> <list file>
if [ -f "$list" ]; then
while IFS= read -r name; do
case "$name" in "" | */* | . | ..) continue ;; esac
+ case "$name" in *.svg) ;; *) continue ;; esac # only an asset is ever removed
if [ ! -e "$src/$name" ] && [ -f "$dest/$name" ]; then rm -f "$dest/$name"; fi
done < "$list"
fi
diff --git a/plans/release-13.md b/plans/release-13.md
@@ -467,6 +467,10 @@ the primary was running a live six-site build and deploy.
never ships. Only a listed name, and only as a regular file, is ever removed. So nothing compose
wrote, and no svg the image did not put there, is touched.
- The sync runs before compose, so compose would win over any shared name anyway.
+- **N3 (the re-read):** the removal loop now skips any listed name that is not an `.svg`, so a
+ hand-edited or damaged list naming `corpus.json` cannot delete what compose wrote. The sync test
+ lists `corpus.json`, and without the guard it fails with ENOENT on `site-public/corpus.json`
+ (`w3d-bite.log`).
- **Review question 1:** no case exists where a file already in `/site/public` must win over the
image's svg. compose writes no top-level `.svg`: its files are `_headers`, `site.json`,
`corpus.json`, `llms.txt`, `robots.txt`, `sitemap.xml`, `sw.js`, the JSON data files and the