carlos / platform Public

sim: expected-outcomes.two-box.txt overrides the one-box expectations at HOSTLIFE_BOXES=2 (timer-canonical and source-readiness missed at two boxes, exec-writer caught); mutate.sh merges it, one-box reads the base file unchanged

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Paul Campbell pushed by claude agent, operated by paul@keymail.dev 5766a0e1e7b8c76895766e6e00bbfdd3ab81774c parent df1a5f2
2 files changed, +21 −3
  • internal/sim/hostlife/expected-outcomes.two-box.txt +8 −0
  • internal/sim/hostlife/mutate.sh +13 −3
diff --git a/internal/sim/hostlife/expected-outcomes.two-box.txt b/internal/sim/hostlife/expected-outcomes.two-box.txt
new file mode 100644
index 000000000..929c5d91f
--- /dev/null
+++ b/internal/sim/hostlife/expected-outcomes.two-box.txt
@@ -0,0 +1,8 @@
+# Two-box overrides for expected-outcomes.txt (the one-box expectations).
+# Read by mutate.sh only at HOSTLIFE_BOXES=2. A rule listed here replaces
+# that rule's line from the base file; `rule - reason` drops the base
+# line, so the rule must be caught at two boxes. Same format otherwise:
+# rule outcome reason.
+timer-canonical missed at two boxes the sweep reaches it 0 of 3000; at one box it is caught (2 / 3000 on this revision), so the one-box sweep owns it
+source-readiness missed at two boxes the sweep reaches it 0 of 3000; at one box it is caught (12 / 3000 on this revision), so the one-box sweep owns it
+exec-writer - caught at two boxes by the random sweep (1 / 3000, seed 2319: INV-11 generation.json published before its snapshot landed); the base line's one-box miss does not hold here
diff --git a/internal/sim/hostlife/mutate.sh b/internal/sim/hostlife/mutate.sh
index 883996ece..27579b126 100755
--- a/internal/sim/hostlife/mutate.sh
+++ b/internal/sim/hostlife/mutate.sh
@@ -42,6 +42,10 @@
# miss is EXPECTED-MISS and a catch is CAUGHT; at N or more a miss is
# MISSED. The sweep exits nonzero on any ERROR, on any unexpected MISSED,
# and on any rule listed as `missed` that is CAUGHT (STALE).
+# At HOSTLIFE_BOXES=2 expected-outcomes.two-box.txt overrides it, rule by
+# rule: a line there replaces the rule's line from the base file, and
+# `rule - reason` drops the base line (the rule must then be caught).
+# Unset or 1, the base file is read as it is.
#
# Scratch (the binary, every run's log, the verdicts) lives under
# ${HOSTLIFE_SCRATCH:-$TMPDIR/hostlife-sim}; remove it once, after the
@@ -66,6 +70,12 @@ if [ -n "${HOSTLIFE_LIST:-}" ]; then
exit 0
fi
mkdir -p "$SCRATCH/logs" "$SCRATCH/verdicts" || { echo "cannot create $SCRATCH" >&2; exit 2; }
+EXPECT="$PKG/expected-outcomes.txt"
+if [ "$SHAPE" = 2 ] && [ -f "$PKG/expected-outcomes.two-box.txt" ]; then
+ EXPECT="$SCRATCH/expected-outcomes.merged"
+ awk 'FNR==NR { if ($0 !~ /^#/ && NF) ov[$1]=$0; next } !($1 in ov)' "$PKG/expected-outcomes.two-box.txt" "$PKG/expected-outcomes.txt" >"$EXPECT"
+ awk '$0 !~ /^#/ && NF && $2 != "-"' "$PKG/expected-outcomes.two-box.txt" >>"$EXPECT"
+fi
if [ ! -x "$BIN" ]; then
echo "no test binary at $BIN; build it with: go test -c -o $BIN ./internal/sim/hostlife/" >&2
exit 2
@@ -93,8 +103,8 @@ one() {
# the random sweep
HOSTLIFE_MUTATE=$r HOSTLIFE_SEEDS=$SEEDS "$BIN" -test.run '^TestHostLifecycle$' -test.count=1 -test.v -test.timeout 180m >"$log" 2>&1
rc=$?
- expect=$(awk -v r="$r" '$1==r {print $2}' "$PKG/expected-outcomes.txt" 2>/dev/null)
- depth=$(awk -v r="$r" '$1==r {print $3}' "$PKG/expected-outcomes.txt" 2>/dev/null)
+ expect=$(awk -v r="$r" '$1==r {print $2}' "$EXPECT" 2>/dev/null)
+ depth=$(awk -v r="$r" '$1==r {print $3}' "$EXPECT" 2>/dev/null)
nviol=$(grep -o "[0-9]* of $SEEDS seeds violated an invariant" "$log" | head -1 | awk '{print $1}')
seed=$(grep -o "first seed [0-9]*" "$log" | head -1 | awk '{print $3}')
clean=$(grep -c "^ sim_test.go:[0-9]*: $SEEDS seeds, 0 failed.*mutated=\"$r\"" "$log")
@@ -153,7 +163,7 @@ one() {
fi
}
export -f one
-export SEEDS PKG SCRATCH BIN WRULES SHAPE
+export SEEDS PKG SCRATCH BIN WRULES SHAPE EXPECT
printf '%s\n' $RULES | xargs -P "${HOSTLIFE_PAR:-8}" -I{} bash -c 'one "$@"' _ {}
xrc=$?
if [ $xrc -ne 0 ]; then