W14: pin S4 soft-error-page cache exclusion (test-only) — section A complete

Pre-fix, a routing-failure page was stored in the HTTP response cache as
200 and served byte-identically to every later visitor until restart
(cold 2s -> warm 0.0005s). dc7aa709 made http_render_page return
(html, is_error) and gated cache insertion on `not is_err`.

Extend scripts/test-protocol-gate.sh with an HTTP-mode case: fresh
sx_server.exe --http on a random port (timeout-bounded, own child killed),
GET the same nonexistent path twice, assert both requests re-render (two
[sx-http] render lines) and the "[cache] ... error page, not cached" gate
line appears. Standalone-worktree caveat (all docs pages render as soft
error pages, so no positive cache control) documented in the script.

5/5 protocol-gate green; 267/0 sx gate pins. All seven section-A test-debt
pins now landed (K18, K20, K09/K11/K39, K49, crit-2, C1/C1b, S4).

Test-only: no semantics edits, no push.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-04 00:53:57 +00:00
parent ff6c379942
commit d9e452d9bc
2 changed files with 69 additions and 1 deletions

View File

@@ -54,7 +54,9 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to
sentinel across two tests; a plain assert would inherit the vacuity)
- [x] C1/C1b [W3] — command-channel crash guards pinned
(`scripts/test-protocol-gate.sh`, seed for section E's fuzz suite)
- [ ] S4 [conformance] — housekeeping repro, pin
- [x] S4 [hosts] — soft error pages not cached (HTTP-mode pin in
`scripts/test-protocol-gate.sh`; NB S4 lives in hosts.md, not
conformance — "housekeeping" was a mislabel from F-15's tag)
### B. Runner/production env unification
- [ ] Audit runner-only bindings (`values`/`call-with-values` F7/K42, JS
@@ -81,6 +83,16 @@ Pin each confirmed-and-fixed finding with a minimal repro. Add suites to
## Progress log (newest first)
- 2026-07-04 — **S4 error-page-cache pin (item A.7) — section A COMPLETE**.
Extended `scripts/test-protocol-gate.sh` with an HTTP-mode case: fresh
`sx_server.exe --http <random-port>` (timeout-bounded, own PID killed at
end), GET the same nonexistent path twice, assert BOTH requests re-render
(2 `[sx-http]` lines — pre-fix the 2nd was cache-served at 0.0005s) and
the `[cache] … error page, not cached` is_err gate line appears. Findings
from prototyping: standalone worktree renders ALL docs pages as soft error
pages (no content), so a positive "real page IS cached" control is not
assertable here — documented in the script; startup takes ~12-15s (poll
loop, 40s budget). 5/5 protocol-gate green + 267/0 sx pins. Test-only.
- 2026-07-04 — **C1/C1b command-channel pins (item A.6)**. These are
protocol-level, not .sx-suite pins: authored
`scripts/test-protocol-gate.sh` — each case spawns its OWN timeout-bounded

View File

@@ -84,6 +84,62 @@ else
fail=$((fail+1))
fi
# ---------------------------------------------------------------------------
# S4 (review, hosts.md): soft error pages must NOT be stored in the HTTP
# response cache. Pre-fix, a routing-failure page was cached as HTTP 200 and
# served byte-identically from cache to every later visitor (cold 2s → warm
# 0.0005s, ONE render line). Post-fix (dc7aa709), http_render_page returns
# (html, is_error) and cache insertion is gated on `not is_err` (the skip is
# logged as "[cache] <path> → error page, not cached").
#
# Pin: GET the same nonexistent path twice against a fresh --http server and
# assert BOTH requests re-render (two [sx-http] render lines) plus the
# is_err gate line appearing in the log. NB: in a standalone worktree all
# docs pages render as soft error pages (no content), so a positive
# "real page IS cached" control is not assertable here.
# ---------------------------------------------------------------------------
s4_case() {
local port=$((18000 + RANDOM % 2000))
local log; log=$(mktemp)
timeout 90 "$SERVER" --http "$port" >"$log" 2>&1 &
local srv=$!
local up=0
for _ in $(seq 1 40); do
if curl -s -o /dev/null "http://localhost:$port/" 2>/dev/null; then up=1; break; fi
sleep 1
done
if [[ $up -ne 1 ]]; then
echo "FAIL: S4 — http server did not come up on :$port"
kill "$srv" 2>/dev/null; rm -f "$log"
fail=$((fail+1)); return
fi
local miss="/sx/gate-pin-missing-$$-$RANDOM"
curl -s -o /dev/null "http://localhost:$port$miss"
curl -s -o /dev/null "http://localhost:$port$miss"
sleep 1
local renders
renders=$(grep -c "sx-http\] $miss " "$log")
local ok=1
if [[ "$renders" -ne 2 ]]; then
echo "FAIL: S4 — expected 2 renders of $miss (not cache-served), got $renders"
ok=0
fi
if ! grep -q 'error page, not cached' "$log"; then
echo "FAIL: S4 — is_err cache gate line absent from server log"
ok=0
fi
if [[ $ok -eq 1 ]]; then
echo "PASS: S4 soft error page not cached (both GETs re-rendered)"
pass=$((pass+1))
else
echo " --- log tail ---"; tail -12 "$log" | sed 's/^/ /'; echo " ---------------"
fail=$((fail+1))
fi
kill "$srv" 2>/dev/null
rm -f "$log"
}
s4_case
echo
echo "protocol-gate: $pass passed, $fail failed"
[[ $fail -eq 0 ]]