open-standards/.github/workflows/wai-http.yml
2026-10-08 02:00:51 -04:00

180 lines
8.1 KiB
YAML

name: WAI HTTP delivery
# extensions/http-delivery.md: two jobs beside the corpus checks in wai-conformance.yml.
#
# falsify — the HTTP corpus tool and its independent verifier must catch defects. Each
# patch in wai/http-conformance/falsify/ breaks one function of wai-rs (the content
# hash's domain, the root flag, the left-subtree rule, the chunk counter, the component
# digest check, the Content-Range and content-coding checks, ASCII-only numbers, the
# union, layers' place in it and their dispatch, the wai prefix's case, duplicate
# capabilities, a record beside a fallback, the trailing-byte rule, the missing-digest
# plan, the class merge, the base-only threshold, refused refinement responses, stale
# bytes after a mismatch, an unanswered base, the selection digest test, the component
# conformance that withholds an envelope's refinements; and on the
# playlist side adjacency, rendering, bandwidths, durations, the classical master, the
# playlist receipt and its chain, listed cids, and the adaptation policies); it
# is applied to a fresh worktree, the build must succeed, and `wai_http_vectors verify`
# must fail naming the cases on the patch's first line. Then each `http_verify.py
# --mutate` must fail, and the differential: wai-rs writes random envelopes' covered
# prefixes and head proofs, the Python verifier accepts every one, and refuses exactly
# the ten it changes one chaining-value byte in.
#
# cache-conformance — the cache rules (§9). wai/cache-conformance/run.sh stages the
# corpus's objects behind the reference origin (`wai http origin`) and runs driver.py
# against the origin, which must pass every MUST test, and against four negative-control
# proxies, which must each fail the tests their defect reaches. Labelled caches run only
# where the environment provides them (/opt/wai-cache); this repository holds none, and
# the job summary says when none ran. The reports are uploaded as an artifact.
#
# No workflow_dispatch: it does not start runs on this forge. A weekly schedule keeps the
# jobs exercised between changes.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
paths:
- 'wai/wai-rs/src/http_binding/**'
- 'wai/wai-rs/src/container.rs'
- 'wai/wai-rs/src/jwp_hash.rs'
- 'wai/wai-rs/src/bin/wai.rs'
- 'wai/wai-rs/src/bin/wai_http_vectors.rs'
- 'wai/wai-rs/src/bin/wai_cli/http.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_vectors.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_vectors_playlists.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_playlists.rs'
# The playlists render through hls_render and are sealed by wai_video_manifest.
- 'wai/wai-rs/src/hls_render.rs'
- 'wai/wai-rs/src/wai_video_manifest.rs'
# Playlist receipts verify Ed25519 through the shared strict rule, in Rust and Python.
- 'wai/wai-rs/src/sig.rs'
- 'wai/claim-conformance/_ed25519.py'
- 'wai/wai-rs/Cargo.toml'
- 'wai/http-conformance/**'
- 'wai/cache-conformance/**'
- 'wai/claim-conformance/_blake3.py'
# http_verify.py reads staged_verify.py (and through it int_payload_verify.py), and
# the corpus carries the staged ladder's base and layers.
- 'wai/staged-conformance/staged_verify.py'
# staged_verify.py's component rules (SPEC §7.1) read the capability registry.
- 'wai/registry/capabilities.json'
- 'wai/staged-conformance/cases/audio_flac_rate_ladder/**'
- 'wai/int-payload-conformance/int_payload_verify.py'
- 'wai/registry/**'
- '.github/workflows/wai-http.yml'
pull_request:
paths:
- 'wai/wai-rs/src/http_binding/**'
- 'wai/wai-rs/src/container.rs'
- 'wai/wai-rs/src/jwp_hash.rs'
- 'wai/wai-rs/src/bin/wai.rs'
- 'wai/wai-rs/src/bin/wai_http_vectors.rs'
- 'wai/wai-rs/src/bin/wai_cli/http.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_vectors.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_vectors_playlists.rs'
- 'wai/wai-rs/src/bin/wai_cli/http_playlists.rs'
# The playlists render through hls_render and are sealed by wai_video_manifest.
- 'wai/wai-rs/src/hls_render.rs'
- 'wai/wai-rs/src/wai_video_manifest.rs'
# Playlist receipts verify Ed25519 through the shared strict rule, in Rust and Python.
- 'wai/wai-rs/src/sig.rs'
- 'wai/claim-conformance/_ed25519.py'
- 'wai/wai-rs/Cargo.toml'
- 'wai/http-conformance/**'
- 'wai/cache-conformance/**'
- 'wai/claim-conformance/_blake3.py'
# http_verify.py reads staged_verify.py (and through it int_payload_verify.py), and
# the corpus carries the staged ladder's base and layers.
- 'wai/staged-conformance/staged_verify.py'
# staged_verify.py's component rules (SPEC §7.1) read the capability registry.
- 'wai/registry/capabilities.json'
- 'wai/staged-conformance/cases/audio_flac_rate_ladder/**'
- 'wai/int-payload-conformance/int_payload_verify.py'
- 'wai/registry/**'
- '.github/workflows/wai-http.yml'
schedule:
- cron: '17 4 * * 1'
jobs:
falsify:
name: HTTP corpus · falsification and differential
runs-on: linux
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
command -v rustup >/dev/null 2>&1 || \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
rustup toolchain install 1.98.0 --profile minimal
rustup default 1.98.0
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- uses: actions/setup-python@v5
with:
python-version: '3.11'
# One target directory for every patched build, so only the wai crate rebuilds.
- name: Every patch is caught; every mutation is caught; the differential holds
shell: bash
env:
CARGO_TARGET_DIR: ${{ runner.temp }}/falsify-target
run: |
git config --global --add safe.directory "$GITHUB_WORKSPACE"
bash wai/http-conformance/falsify/run.sh "$RUNNER_TEMP/falsify"
cache-conformance:
name: cache rules · controls and labelled caches
runs-on: linux
steps:
- uses: actions/checkout@v5
- name: Install Rust 1.98.0
shell: bash
run: |
export PATH="$HOME/.cargo/bin:$PATH"
command -v rustup >/dev/null 2>&1 || \
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain 1.98.0
rustup toolchain install 1.98.0 --profile minimal
rustup default 1.98.0
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
- uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Build the reference origin
working-directory: wai/wai-rs
shell: bash
run: cargo build --release --no-default-features --features http --bin wai
# The verdict: run.sh exits non-zero when the origin fails a MUST test, a control is
# not caught, or a labelled cache fails one.
- name: The origin passes, the controls are caught, labelled caches report
shell: bash
run: WAI="$GITHUB_WORKSPACE/wai/wai-rs/target/release/wai" bash wai/cache-conformance/run.sh "$RUNNER_TEMP/cache"
# The evidence in the log, whatever becomes of the upload: each report's path and
# SHA-256, and the summary.
- name: The reports, in the log
if: always()
shell: bash
run: |
cd "$RUNNER_TEMP/cache/reports" 2>/dev/null || { echo "no reports were written"; exit 0; }
for f in *; do printf '%s %s\n' "$(sha256sum "$f" | cut -d' ' -f1)" "$RUNNER_TEMP/cache/reports/$f"; done
cat summary.md 2>/dev/null || true
# An upload this forge cannot take must not decide the job: the verdict is the step
# above it.
- name: Upload the reports
if: always()
continue-on-error: true
uses: actions/upload-artifact@v3
with:
name: cache-conformance-reports
path: ${{ runner.temp }}/cache/reports