name: wai-quantum service # The WAI quantum stack as a public job service (wai/wai-quantum-service): its # tests, clippy with warnings as errors, and its smoke checks over HTTP against # an instance started here, on Linux and on the macOS runner (the host the # service is deployed to). Its tests also hold the command line's snapshot of # its MCP tools (wai/wai-quantum-cli/docs/service-mcp.json) to the live list, # and one (tests/restart.rs) kills the service mid-job and starts it again on # its store. Each instance here keeps its job store in the runner's own # scratch directory. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true on: push: branches: [main] paths: - 'wai/wai-quantum/**' - 'wai/wai-quantum-service/**' # The command line's agent docs list this service's tools from a snapshot # there, which this service's tests hold to its live list. - 'wai/wai-quantum-cli/docs/**' - 'rust-toolchain.toml' - '.github/workflows/wai-quantum-service.yml' pull_request: paths: - 'wai/wai-quantum/**' - 'wai/wai-quantum-service/**' # The command line's agent docs list this service's tools from a snapshot # there, which this service's tests hold to its live list. - 'wai/wai-quantum-cli/docs/**' - 'rust-toolchain.toml' - '.github/workflows/wai-quantum-service.yml' jobs: relevant: name: does this change touch it runs-on: gate outputs: run: ${{ steps.gate.outputs.run }} steps: - uses: actions/checkout@v5 with: fetch-depth: 0 - id: gate run: | set -euo pipefail r=$(python3 scripts/pr-touches-paths.py .github/workflows/wai-quantum-service.yml \ "${{ github.event.pull_request.base.sha }}" \ "${{ github.event.pull_request.head.sha }}") echo "this change touches wai-quantum-service: $r" echo "run=$r" >> "$GITHUB_OUTPUT" service-linux: name: service · linux needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: linux timeout-minutes: 60 steps: - uses: actions/checkout@v5 - name: Install Rust 1.99.1 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.99.1 rustup toolchain install 1.99.1 --profile minimal --component clippy rustup default 1.99.1 echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Tests and clippy shell: bash working-directory: wai/wai-quantum-service run: | set -euo pipefail cargo test --locked --release 2>&1 | tee "$RUNNER_TEMP/test.log" grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/test.log" || { echo "::error::no test ran"; exit 1; } cargo clippy --locked --release --all-targets -- -D warnings # The engine's parts of the service, each required by name: sets and # sweeps and their Merkle paths, a result's provenance, the package # counter's reader and probe (on fake trees; a container hides the real # one), and a real-valued input bound by the reader. - name: The engine's sets, provenance and package energy shell: bash working-directory: wai/wai-quantum run: | set -euo pipefail cargo test --locked --release --features full --lib -- engine::sets:: engine::energy:: merkle:: engine::run::tests::a_result_s_provenance qasm::tests::a_bound_parameter 2>&1 | tee "$RUNNER_TEMP/engine.log" grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/engine.log" || { echo "::error::the engine's tests did not pass"; exit 1; } for t in engine::sets::tests::one_receipt_binds_every_item_and_any_change_breaks_it \ engine::sets::tests::a_sweep_is_its_grid_each_point_the_program_written_out \ engine::sets::tests::a_failed_item_is_bound_by_its_error \ merkle::tests::every_leaf_s_path_leads_to_the_root_and_nothing_else_does \ engine::run::tests::a_result_s_provenance_names_the_passes_its_certificate_ran \ engine::energy::tests::the_probe_finds_a_live_counter_s_cadence_and_refuses_a_stalled_one \ engine::energy::tests::only_top_level_package_zones_are_read_and_a_frozen_one_is_not_live \ engine::energy::tests::a_package_figure_names_its_scope_and_declares_its_edges \ qasm::tests::a_bound_parameter_reads_as_the_program_written_with_its_value; do grep -q "^test $t \.\.\. ok$" "$RUNNER_TEMP/engine.log" || { echo "::error::$t did not run"; exit 1; } done - name: The smoke checks over HTTP shell: bash working-directory: wai/wai-quantum-service run: | set -euo pipefail key="$RUNNER_TEMP/service.key"; rm -f "$key" "$RUNNER_TEMP/service.keys.json" store="$RUNNER_TEMP/store"; rm -rf "$store" cargo build --locked --release WAI_QSVC_KEY="$key" WAI_QSVC_STORE="$store" WAI_QSVC_ADDR=127.0.0.1:18241 WAI_QSVC_BUDGET_GB=8 WAI_QSVC_JOB_GB=4 WAI_QSVC_WORKERS=2 WAI_QSVC_CLIENT_BURST=60 \ ./target/release/wai-quantum-service serve 2> "$RUNNER_TEMP/service.log" & pid=$! trap 'kill $pid 2>/dev/null || true; cat "$RUNNER_TEMP/service.log"' EXIT for _ in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:18241/v1/health && break; sleep 0.2; done bash smoke.sh http://127.0.0.1:18241 service-macos: name: service · macos needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: macos timeout-minutes: 60 steps: - uses: actions/checkout@v5 # launchd's PATH omits cargo on the macOS host runner. - name: Put cargo on PATH shell: bash run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH" - name: Tests shell: bash working-directory: wai/wai-quantum-service run: | set -euo pipefail nice -n 10 cargo test --locked --release 2>&1 | tee "$RUNNER_TEMP/test.log" grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$RUNNER_TEMP/test.log" || { echo "::error::no test ran"; exit 1; } # The single-precision state vector on this host's GPU, against the # double-precision one; the GPU is declared, so its absence fails. - name: The GPU state vector shell: bash working-directory: wai/wai-quantum env: WAI_QUANTUM_SV_METAL_EXPECT: "1" run: | set -euo pipefail nice -n 10 cargo test --locked --release --features quantum_sv_metal --lib quantum_sv_metal 2>&1 | tee "$RUNNER_TEMP/gpu.log" grep -qE '^test result: ok\. 4 passed; 0 failed' "$RUNNER_TEMP/gpu.log" || { echo "::error::not every GPU test ran and passed"; exit 1; } # The cut-rank table on this host's GPU, against the double-precision # walk; the GPU is declared, so its absence fails, and each GPU test is # checked by name. - name: The GPU cut-rank table shell: bash working-directory: wai/wai-quantum env: WAI_QUANTUM_CUTRANK_METAL_EXPECT: "1" run: | set -euo pipefail nice -n 10 cargo test --locked --release --features quantum_cutrank_metal --lib quantum_cutrank 2>&1 | tee "$RUNNER_TEMP/cutrank-gpu.log" for t in the_gpu_table_agrees gpu_samples_follow_the_probabilities; do grep -q "^test quantum_cutrank::tests::$t ... ok$" "$RUNNER_TEMP/cutrank-gpu.log" \ || { echo "::error::quantum_cutrank::tests::$t did not run and pass"; exit 1; } done - name: The smoke checks over HTTP shell: bash working-directory: wai/wai-quantum-service run: | set -euo pipefail key="$RUNNER_TEMP/service.key"; rm -f "$key" "$RUNNER_TEMP/service.keys.json" store="$RUNNER_TEMP/store"; rm -rf "$store" cargo build --locked --release WAI_QSVC_KEY="$key" WAI_QSVC_STORE="$store" WAI_QSVC_ADDR=127.0.0.1:18241 WAI_QSVC_BUDGET_GB=8 WAI_QSVC_JOB_GB=4 WAI_QSVC_WORKERS=2 WAI_QSVC_CLIENT_BURST=60 \ ./target/release/wai-quantum-service serve 2> "$RUNNER_TEMP/service.log" & pid=$! trap 'kill $pid 2>/dev/null || true; cat "$RUNNER_TEMP/service.log"' EXIT for _ in $(seq 1 50); do curl -s -o /dev/null http://127.0.0.1:18241/v1/health && break; sleep 0.2; done bash smoke.sh http://127.0.0.1:18241 # The processor packages' counters on a Linux host that has them readable # (the hardware runner, outside any container): the engine's live test # required to take its live branch, and the service's smoke checks with a # metered figure required on every job. energy-linux: name: service energy · linux packages needs: relevant if: needs.relevant.outputs.run == 'true' runs-on: linux-hw timeout-minutes: 90 env: CARGO_PROFILE_RELEASE_DEBUG: '0' CARGO_BUILD_JOBS: '8' steps: - name: Fetch the source shell: bash run: | set -euo pipefail ref="${{ github.event_name == 'pull_request' && format('refs/pull/{0}/head', github.event.pull_request.number) || github.ref }}" want="${{ github.event.pull_request.head.sha || github.sha }}" rm -rf src && mkdir src && cd src git init -q git fetch -q --depth 1 http://100.64.224.0:3400/Transaction-Science/open-standards.git "$ref" git checkout -q FETCH_HEAD got="$(git rev-parse HEAD)" echo "fetched $ref at $got" if [ "$got" != "$want" ]; then echo "::error::$ref is at $got, not $want: it moved after this run started, and a newer run tests it" exit 1 fi - name: The package counter, live shell: bash working-directory: src/wai/wai-quantum env: WAI_QUANTUM_PACKAGE_ENERGY_EXPECT: "1" run: | set -euo pipefail log=$(mktemp) CARGO_TARGET_DIR="$HOME/hw-target/wai-quantum" nice -n 10 cargo test --locked --release --features quantum_engine,quantum_receipt --lib engine::energy:: -- --nocapture --test-threads=1 2>&1 | tee "$log" # With --nocapture the test's line follows its name on the same line. grep -q 'package counter: {"joules_micro":' "$log" || { echo "::error::the package counter's live path never ran"; exit 1; } - name: The service's smoke checks, every job metered shell: bash working-directory: src/wai/wai-quantum-service run: | set -euo pipefail export CARGO_TARGET_DIR="$HOME/hw-target/wai-quantum-service" nice -n 10 cargo build --locked --release t=$(mktemp -d) WAI_QSVC_KEY="$t/service.key" WAI_QSVC_STORE="$t/store" WAI_QSVC_ADDR=127.0.0.1:18244 WAI_QSVC_BUDGET_GB=4 WAI_QSVC_JOB_GB=2 WAI_QSVC_WORKERS=1 WAI_QSVC_CLIENT_BURST=60 \ "$CARGO_TARGET_DIR/release/wai-quantum-service" serve 2> "$t/service.log" & pid=$! trap 'kill $pid 2>/dev/null || true; cat "$t/service.log"; rm -rf "$t"' EXIT for _ in $(seq 1 100); do curl -s -o /dev/null http://127.0.0.1:18244/v1/health && break; sleep 0.2; done curl -sS http://127.0.0.1:18244/v1 | python3 -I -c 'import json,sys; e=json.load(sys.stdin)["energy"]; assert e["meter"]=="packages", e; print("meter:", e)' SMOKE_EXPECT_ENERGY=1 bash smoke.sh http://127.0.0.1:18244