pkgcache: reject 0-byte artifacts on store and lookup, self-heal torn writes (#10)

A torn producer write (e.g. disk-full mid-copy) could leave a 0-byte P.wwi or
P.o in out/.pkgcache under a self-consistent key; cache_lookup checked only
existence, so every later build HIT and served the empty artifact forever
(silent serve-wrong). Reject size==0 on both sides, symmetric across stages:
store refuses to commit a 0-byte temp before the key write, lookup treats a
0-byte cached artifact as a MISS so existing poison self-heals on re-derive.
A valid .wwi/.o is never 0 bytes, so the guard cannot misfire.

Regression: test/wcc/989_pkgcache_poison_run.c, table-driven over
{poison P.wwi | P.o | both}, non-vacuity proven by guard-neuter.
This commit is contained in:
2026-06-22 20:52:11 +09:00
parent c0383274d1
commit a1484aef28
4 changed files with 291 additions and 0 deletions

View File

@@ -535,6 +535,7 @@ TESTS = $(BIN)/test_smoke $(BIN)/test_lex $(BIN)/test_parse $(BIN)/test_check \
$(BIN)/test_separchive_run \
$(BIN)/test_pkgcache_run \
$(BIN)/test_pkgcache_concurrent_run \
$(BIN)/test_pkgcache_poison_run \
$(BIN)/test_c6soak_run \
$(BIN)/test_septest_run \
$(BIN)/test_coloimport_sep \
@@ -2951,6 +2952,16 @@ $(BIN)/test_pkgcache_concurrent_run: test/wcc/989_pkgcache_concurrent_run.c $(BI
$(BIN)/w6l $(BIN)/w6l_ww $(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# 989_pkgcache_poison_run — #10 (BUG-B): a 0-byte cached P.wwi/P.o under a valid
# P.key (torn producer write) must self-heal — rejected on both lookup (MISS,
# re-derive) and store (never commit a 0-byte). Table-driven over which artifact
# is poisoned {wwi/o/both}, both driver stages. COLD/dev-only (off every byte-id/
# bootstrap gate). Needs both driver + compiler + asm + linker stages + libwwrt.a.
$(BIN)/test_pkgcache_poison_run: test/wcc/989_pkgcache_poison_run.c $(BIN)/ww $(BIN)/ww_ww \
$(BIN)/w6c $(BIN)/w6c_ww $(BIN)/w6a $(BIN)/w6a_ww \
$(BIN)/w6l $(BIN)/w6l_ww $(LIB)/libwwrt.a | $(BIN)
$(CC) $(CFLAGS) -o $@ $<
# 989_c6soak_run — M3-tail commit-6 dual-path soak gate, phase-1 leg (#46
# c6). Builds real lib chains (encoding.utf8 dotted + strings/bytes same-leaf
# `contains`) BOTH combined and --sep, asserts combined==sep run-equivalence