Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions .github/justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# CI job bodies: each workflow job runs exactly one `gha::` recipe, so
# `just ci` is exactly CI and the workflow files carry no logic beyond
# environment setup.

set working-directory := '..'

# Wrap one recipe in a GitHub Actions log group (plain passthrough
# locally).
[private]
_step recipe:
#!/usr/bin/env bash
set -euo pipefail
if [ "${GITHUB_ACTIONS:-}" = "true" ]; then
echo "::group::just {{recipe}}"
status=0
just {{recipe}} || status=$?
echo "::endgroup::"
if [ $status -ne 0 ]; then
echo "::error title=just {{recipe}} failed::exit status $status"
exit $status
fi
else
just {{recipe}}
fi

# The static checks — fmt, clippy, workspace tests, wasm build — plus the
# release-wasm AES-table audit, which needs the release build and so
# shares this job's cache.
rust-checks:
@just gha::_step fmt-check
@just gha::_step clippy
@just gha::_step test
@just gha::_step build-wasm
@just gha::_step audit

# The QUIC loopback rig under Wasmtime and both tls-virt deliveries
# against openssl over real TCP.
smoke:
@just gha::_step smoke-quic
@just gha::_step smoke-tls-virt

# The cross-implementation conformance suite: the shared guest suite
# composed with each delivery, the aggregated matrix diffed against the
# committed one.
conformance-checks:
@just gha::_step conformance-ct::all
@just gha::_step conformance-ct::matrix-check

# Cross-implementation interop over real transports: the composed
# component against OpenSSL and Go peers over TCP, and the noq leg
# against quic-go over UDP.
interop:
@just gha::_step interop-tls
@just gha::_step interop-quic

# The timing lab workflow's entry point (timing-lab.yml, schedule-only,
# not a `ci` job): one retry at 4x samples before reporting failure — a
# flake washes out at 4x while a real leak's t grows, so the retry
# separates them; shared runners make the retry mandatory rather than
# optional. Records the environment the verdicts are valid for (verdicts
# hold per runtime version and per microarchitecture; a wasmtime upgrade
# or a runner change invalidates previous quiet readings). Under GitHub
# Actions the report also lands in the job summary.
timing-lab-scheduled:
#!/usr/bin/env bash
set -uo pipefail
samples="${TIMING_LAB_SAMPLES:-2000}"
cpu=$(sed -n 's/^model name[^:]*: //p' /proc/cpuinfo | head -n1)
[ -n "$cpu" ] || cpu="$(sed -n 's/^CPU implementer[^:]*: /implementer /p' /proc/cpuinfo | head -n1)"
environment="$(wasmtime --version), $(uname -m), ${cpu:-unknown CPU}"
echo "timing lab environment: ${environment}"
run() { TIMING_LAB_SAMPLES="$1" just timing-lab 2>&1; }

report=$(run "$samples"); status=$?
printf '%s\n' "$report"
if [ $status -ne 0 ]; then
samples=$(( samples * 4 ))
echo
echo "timing lab: verdicts diverged; retrying at ${samples} samples/class before reporting failure."
report=$(run "$samples"); status=$?
printf '%s\n' "$report"
fi

if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{
echo "### timing lab — ${samples} samples/class"
echo
echo "Environment: ${environment}"
echo
# The lab prints its report as a markdown table; lift it verbatim.
printf '%s\n' "$report" | sed -n '/^| surface/,/^$/p'
if [ $status -eq 0 ]; then
echo "All surfaces matched expectations."
else
echo "**Surfaces diverged from expectation, and again on a retry at ${samples} samples/class.**"
echo "A quiet positive control means the harness cannot detect leaks at this"
echo "measurement distance; a LEAK on a real surface warrants investigation."
fi
} >> "$GITHUB_STEP_SUMMARY"
fi
exit $status
51 changes: 23 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
name: CI

# The pull-request gate: the same recipes a developer runs, split into the
# static checks, the smoke/virtualizer rigs, the conformance matrix, and
# the cross-implementation interop legs. The job bodies live in the
# justfiles; the workflow only provisions the environment. The timing lab
# is deliberately not here — it is statistical and schedule-only
# (timing-lab.yml); `just bench` is non-gating by design.
# The pull-request gate: each job runs exactly one `gha::` job recipe, so
# `just ci` is exactly CI; the workflow only provisions the environment.
# The timing lab is deliberately not here — it is statistical and
# schedule-only (timing-lab.yml); `just bench` is non-gating by design.
on:
push:
branches: [main]
Expand All @@ -16,10 +14,9 @@ permissions:
contents: read

jobs:
# `just check` (fmt, clippy all-features, workspace tests, wasm build)
# plus `just audit` (no table-based AES reachable in the release wasm
# artifact — the audit needs the release build, so it shares this job's
# cache).
# `just gha::rust-checks`: fmt, clippy, tests, wasm build, plus the
# AES-table audit, which needs the release build and so shares this
# job's cache.
rust-checks:
runs-on: ubuntu-latest
# Headroom for a cold cargo cache: clippy all-features compiles the
Expand All @@ -44,12 +41,11 @@ jobs:
tool: just
env:
GITHUB_TOKEN: ${{ github.token }}
- run: just check
- run: just audit
- run: just gha::rust-checks

# The QUIC loopback rig under Wasmtime (`just smoke-quic`) and both
# tls-virt deliveries against openssl over real TCP
# (`just smoke-tls-virt`). openssl and python3 are on the runner image.
# `just gha::smoke`: the QUIC loopback rig under Wasmtime and both
# tls-virt deliveries against openssl over real TCP. openssl and
# python3 are on the runner image.
smoke:
runs-on: ubuntu-latest
# Headroom for a cold cargo cache (the tls-virt-wasmtime leg builds the
Expand All @@ -75,14 +71,13 @@ jobs:
tool: just,wasmtime,wasm-tools,wac-cli
env:
GITHUB_TOKEN: ${{ github.token }}
- run: just smoke-quic
- run: just smoke-tls-virt
- run: just gha::smoke

# The cross-implementation conformance suite (`just conformance`): the
# shared guest suite composed with each delivery, run under the pinned
# component-test runner and validated against the committed inventory,
# manifest, and matrix. The aggregate action republishes the matrix to
# the job summary; the just gate has already gated.
# `just gha::conformance-checks`: the shared guest suite composed with
# each delivery, run under the pinned component-test runner and
# validated against the committed inventory, manifest, and matrix. The
# aggregate action republishes the matrix to the job summary; the just
# gate has already gated.
conformance:
runs-on: ubuntu-latest
# Headroom for a cold cargo cache plus the ct-tools install.
Expand Down Expand Up @@ -124,7 +119,7 @@ jobs:
tool: just,wasm-tools,wac-cli
env:
GITHUB_TOKEN: ${{ github.token }}
- run: just conformance
- run: just gha::conformance-checks
- name: Publish the conformance matrix
if: always() && hashFiles('conformance/driver-ct/results/*.jsonl') != ''
uses: polymorph-components/polymorph-test/actions/aggregate@2436bb9fd233ec514f10de613556a7a61bbb8476
Expand Down Expand Up @@ -154,10 +149,10 @@ jobs:
conformance/driver-ct/results/matrix.md
retention-days: 30

# Cross-implementation interop over real transports (`just interop`):
# the composed component against OpenSSL and Go crypto/tls peers over
# TCP, and the noq leg against quic-go over UDP, both directions,
# under a fresh Ed25519 private PKI per run.
# `just gha::interop`: cross-implementation interop over real
# transports — the composed component against OpenSSL and Go crypto/tls
# peers over TCP, and the noq leg against quic-go over UDP, both
# directions, under a fresh Ed25519 private PKI per run.
interop:
runs-on: ubuntu-latest
# Cap so a hung handshake or stuck peer fails fast.
Expand Down Expand Up @@ -186,4 +181,4 @@ jobs:
tool: just,wasmtime,wasm-tools,wac-cli
env:
GITHUB_TOKEN: ${{ github.token }}
- run: just interop
- run: just gha::interop
2 changes: 1 addition & 1 deletion .github/workflows/timing-lab.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,6 @@ jobs:
tool: just,wasmtime

- name: Run the timing lab
run: just timing-lab-scheduled
run: just gha::timing-lab-scheduled
env:
TIMING_LAB_SAMPLES: ${{ inputs.samples || '2000' }}
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ design record.
| Recipe | Verifies |
| --- | --- |
| `just check` | fmt, clippy (all features), workspace tests (RFC 9001 vectors, profile/provider pinning, class-D key rejection), wasm build |
| `just ci` | every gating CI job's body, exactly as CI runs it — each CI job runs one gha:: job recipe (.github/justfile). The timing lab is schedule-only and excluded |
| `just conformance` | the cross-implementation conformance suite (see `conformance/README.md`): the shared guest suite composed with each delivery — the `tls` world's in-guest Ed25519 posture and the `tls-delegated` world with the fixture signer — run under the pinned component-test runner, transpiled under Node 24 JSPI (the jco-node targets), runtime-linked under deltic on stock Deno (the deltic-deno targets — no transpile, no engine flag; release-pinned in `conformance/driver-ct/deltic/`), and in headless Chromium (the jco-browser targets; CI or CONFORMANCE_BROWSER=1), with import-satisfaction and signer-reachability gates, validated against the committed case inventory (`tests.lock`) and target manifest, and diffed against the committed matrix. `just conformance-ct::run-webcrypto` (on demand: clones the sibling repo) adds the delegated posture over a real `polymorph:webcrypto` provider |
| `just smoke-quic` | QUIC over `wasi:sockets` UDP under Wasmtime |
| `just smoke-tls-virt` | both tls-virt deliveries against `openssl s_server` over real TCP (needs openssl + python3): the composed guest virtualizer (handle-address and import-satisfaction gates), and the wasmtime host provider on both sockets generations — wasip3 and `std::net`/0.2 guests — with handle-address and profile-cipher-suite gates plus plain-TCP passthrough-delegation legs |
Expand Down
64 changes: 16 additions & 48 deletions justfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
# Run all checks.
check: fmt-check clippy test build-wasm
# The orchestration surface: repo-wide recipes plus the GitHub Actions
# gha module, colocated with the workflows it drives.

mod conformance-ct "conformance/driver-ct/justfile"
# GitHub Actions plumbing: CI job entry points and workflow-only recipes.
mod gha ".github"

# List the available recipes.
default:
@just --list

# The exact set of checks CI runs: each CI job runs exactly one gha:: job
# recipe. The timing lab is schedule-only (timing-lab.yml) and not part
# of ci.
ci: (gha::rust-checks) (gha::smoke) (gha::conformance-checks) (gha::interop)

# The fast pre-commit checks.
check: fmt-check clippy test build-wasm

fmt:
cargo fmt --all
Expand Down Expand Up @@ -83,49 +97,3 @@ timing-lab:
[ -n "${TIMING_LAB_SEED:-}" ] && args+=(--env TIMING_LAB_SEED)
[ -n "${TIMING_LAB_ISOLATE:-}" ] && args+=(--env TIMING_LAB_ISOLATE)
wasmtime run "${args[@]}" target/wasm32-wasip2/release/timing-lab.wasm

# The timing lab's scheduled wrapper: one retry at 4x samples before
# reporting failure — a flake washes out at 4x while a real leak's t grows,
# so the retry separates them; shared runners make the retry mandatory
# rather than optional. Records the environment the verdicts are valid for
# (verdicts hold per runtime version and per microarchitecture; a wasmtime
# upgrade or a runner change invalidates previous quiet readings). Under
# GitHub Actions the report also lands in the job summary.
timing-lab-scheduled:
#!/usr/bin/env bash
set -uo pipefail
samples="${TIMING_LAB_SAMPLES:-2000}"
cpu=$(sed -n 's/^model name[^:]*: //p' /proc/cpuinfo | head -n1)
[ -n "$cpu" ] || cpu="$(sed -n 's/^CPU implementer[^:]*: /implementer /p' /proc/cpuinfo | head -n1)"
environment="$(wasmtime --version), $(uname -m), ${cpu:-unknown CPU}"
echo "timing lab environment: ${environment}"
run() { TIMING_LAB_SAMPLES="$1" just timing-lab 2>&1; }

report=$(run "$samples"); status=$?
printf '%s\n' "$report"
if [ $status -ne 0 ]; then
samples=$(( samples * 4 ))
echo
echo "timing lab: verdicts diverged; retrying at ${samples} samples/class before reporting failure."
report=$(run "$samples"); status=$?
printf '%s\n' "$report"
fi

if [ -n "${GITHUB_STEP_SUMMARY:-}" ]; then
{
echo "### timing lab — ${samples} samples/class"
echo
echo "Environment: ${environment}"
echo
# The lab prints its report as a markdown table; lift it verbatim.
printf '%s\n' "$report" | sed -n '/^| surface/,/^$/p'
if [ $status -eq 0 ]; then
echo "All surfaces matched expectations."
else
echo "**Surfaces diverged from expectation, and again on a retry at ${samples} samples/class.**"
echo "A quiet positive control means the harness cannot detect leaks at this"
echo "measurement distance; a LEAK on a real surface warrants investigation."
fi
} >> "$GITHUB_STEP_SUMMARY"
fi
exit $status
Loading