open-standards/wai/http-conformance/falsify/run.sh
Transaction Science 1cffbc6ffd wai: HTTP reports a refinement by its refines.base alone; a conforming envelope's refinement tested
- §7 step 4 as the text stands: a refinement of the pick is one whose refines.base, read
  on its own, is the pick's id (container::refinements_naming, refinements_naming in
  http_verify.py), so one whose refines is otherwise malformed is reported dropped
  (components_nonconforming). Of a conforming envelope the set is the same as before.
- Objects OCF (ONC's conforming twin: refinements [2], dropped []), ONM (refines
  {base: b} alone: reported) and ONX (refines {base: x}: not reported), on the whole and
  the range paths; fetch_OR_malformed_refines now reports its refinement; the generator
  checks each outcome.
- falsify: conforming-withheld and refines-read-whole, each with an http_verify.py
  --mutate, wired into falsify/run.sh; nonconforming-offered's must-fail list extended.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-08 03:11:46 -04:00

74 lines
4.1 KiB
Shell
Executable file

#!/usr/bin/env bash
# Falsify the HTTP corpus tool: each patch here breaks one function of wai-rs. For each,
# in a fresh worktree of HEAD: apply it, require the build to succeed, and require
# `wai_http_vectors verify` to exit non-zero and to name every case the patch's first
# line lists. Then the Python side: each `http_verify.py --mutate` must fail, and the
# differential must verify every proof and refuse exactly the flipped ones.
#
# bash wai/http-conformance/falsify/run.sh [work-dir [patch-name…]]
#
# With patch names, only those patches run (and nothing else).
# Run from the repository root. CARGO_TARGET_DIR, if set, is shared by the builds, which
# need the features http and video_manifest (the playlist receipts).
set -uo pipefail
ROOT="$(git rev-parse --show-toplevel)"
WORK="${1:-${RUNNER_TEMP:-/tmp}/wai-http-falsify}"
shift || true
ONLY="$*"
mkdir -p "$WORK"
fail=0
for patch in "$ROOT"/wai/http-conformance/falsify/*.patch; do
name="$(basename "$patch" .patch)"
if [ -n "$ONLY" ] && ! printf ' %s ' $ONLY | grep -q " $name "; then continue; fi
wt="$WORK/f-$name"
rm -rf "$wt"
git -C "$ROOT" worktree add --detach --quiet "$wt" HEAD
must="$(head -1 "$patch" | sed 's/^# must fail: //')"
if ! git -C "$wt" apply "$patch"; then
echo "::error::$name: the patch does not apply"; fail=1
elif ! (cd "$wt/wai/wai-rs" && cargo build --release --no-default-features --features http,video_manifest --bin wai_http_vectors) > "$WORK/$name.build.log" 2>&1; then
echo "::error::$name: the patched tree does not build"; tail -20 "$WORK/$name.build.log"; fail=1
else
bin="${CARGO_TARGET_DIR:-$wt/wai/wai-rs/target}/release/wai_http_vectors"
"$bin" verify "$wt/wai/http-conformance" > "$WORK/$name.verify.log" 2>&1
rc=$?
missing=""
for c in $must; do grep -q "^FAIL $c:" "$WORK/$name.verify.log" || missing="$missing $c"; done
if [ $rc -eq 0 ] || [ -n "$missing" ]; then
echo "::error::$name: verify exited $rc; cases not failed:$missing"; fail=1
else
echo "ok $name: verify exited $rc and failed$(printf ' %s' $must) ($(grep -c '^FAIL' "$WORK/$name.verify.log") failures)"
fi
fi
git -C "$ROOT" worktree remove --force "$wt"
done
[ -n "$ONLY" ] && exit $fail
cd "$ROOT/wai/http-conformance"
for m in left-half no-root counter-zero floor-as-codecs blake3-iv base-at-done tick-noop refinement-unclipped \
pdt-ignored dseq-ignored parts-after-extinf average-floor render-digest-off name-unchecked chain-unchecked \
ilog2-no-interp bola-waits unlabelled-as-zero round-half-down small-order-key small-order-r \
rebind-uri rebind-sequence key-unchecked walk-unbounded reload-walked \
xml-char-unchecked xml-attribute-twice dash-start-ignored dash-timescale-ignored \
unlabelled-escapes abr-unbounded gap-carries receipt-duplicates receipt-surrogates session-data-anywhere \
dash-r-expanded xml-attributes-scanned dash-timelines-unbounded budget-raises \
uri-unresolved gap-withdraws reanchor-backwards walk-exceeded-wedges walk-name-unchecked walk-verify-unchecked bindings-unbounded \
file-numbers-unbounded nonconforming-offered conforming-withheld refines-read-whole; do
if python3 http_verify.py . --mutate "$m" > "$WORK/py-$m.log" 2>&1; then
echo "::error::http_verify.py --mutate $m passed"; fail=1
else
echo "ok http_verify.py --mutate $m: $(grep -c '^FAIL' "$WORK/py-$m.log") failures"
fi
done
# The differential runs the unpatched tool: build it again (the patched builds shared
# its output path).
(cd "$ROOT/wai/wai-rs" && cargo build --release --no-default-features --features http,video_manifest --bin wai_http_vectors) > "$WORK/unpatched.build.log" 2>&1 || fail=1
bin="${CARGO_TARGET_DIR:-$ROOT/wai/wai-rs/target}/release/wai_http_vectors"
if [ -x "$bin" ]; then
"$bin" diff . --seed 7 --count 500 --out "$WORK/diff.jsonl" > /dev/null || fail=1
python3 http_verify.py diff "$WORK/diff.jsonl" || fail=1
python3 http_verify.py diff "$WORK/diff.jsonl" --flip 10 --seed 3 || fail=1
else
echo "::error::no release wai_http_vectors at $bin for the differential"; fail=1
fi
exit $fail