open-standards/.github/workflows/wai-catalogue.yml
Transaction Science 84b630956a The fleet's operations in the catalogue, and one confirmation flag, --yes
enrolment.create, enrolment.list, report.create and report.export join the catalogue as the
other operations are: placed on the client against a fleet service, with their effect, toolset,
input and output schemas, receipt and the features they need (fleet for the two that sign or
verify). wai enrolment|report run through the door, and the fleet's command module keeps the
agent rules of dx/envelope.rs instead of its own copy of them: the envelope with --json, every
file through out.rs and every request to the service named in a dry run's plan and not sent
(out::would_send), and --yes before the service is changed or a file replaced, exit 4 off a
terminal with the proposal and the confirming command.

A catalogue entry now says when it waits for confirmation (Op::confirms: never, a file the
command line did not name, any file, the target or a file, always), and the rules refuse a
change to a target that does not wait and a read that does. The export carries it and the
agent flags (AGENT_FLAGS), from which wai --help is written: --yes is the one confirmation
flag, and --confirm, which wai conform, wai setup-agent and the fleet took, is its deprecated
spelling, still accepted, so named in help, in every confirming operation's help and in the
export. wai conform confirms through the same module. wai verify's entry names the
conformance results and fleet bundles it reads.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-28 05:32:21 -04:00

136 lines
6 KiB
YAML

name: WAI operation catalogue
# WAI's toolchain has one catalogue of operations, `noun.verb` (wai/wai-rs/src/catalogue.rs),
# and every door names them by it. This workflow fails on drift:
#
# - the export, wai/catalogue/ops.json, is the table (`wai ops export --check`);
# - the table keeps its naming rules (the library's catalogue tests);
# - the command line reaches operations through the catalogue alone, and every operation
# keeps the agent rules: its help, the exit codes, the JSON envelope, --dry-run on every
# operation that is not read-only, --yes (tests/cli_ops.rs, and the binary's own tests);
# - the other doors name operations as the catalogue does: MCP tool names, the services'
# OpenAPI operationIds, the C header, and the Swift and Kotlin sinks
# (scripts/check-wai-ops-doors.py, with its selftest).
#
# Push filters match the push's delta, so every path a door or a test reads is listed.
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
on:
push:
branches: [main]
paths:
- 'wai/wai-rs/**'
- 'wai/catalogue/**'
- 'wai/examples/**'
- 'wai/http-conformance/**'
- 'wai/score-conformance/**'
- 'wai/live-conformance/fleet/**'
- 'wai/REGISTRY.md'
- 'wai/LICENSE'
- 'wai/wai-quantum/**'
- 'wai/wai-ops/**'
- 'wai/wai-app/**'
- 'wai/wai-sink-swift/**'
- 'wai/wai-sink-android/**'
- 'joule-code/joule-code-rs/crates/*/openapi.json'
- 'scripts/check-wai-ops-doors.py'
- 'scripts/check-wai-ops-doors-selftest.sh'
- 'rust-toolchain.toml'
- '.github/workflows/wai-catalogue.yml'
pull_request:
paths:
- 'wai/wai-rs/**'
- 'wai/catalogue/**'
- 'wai/examples/**'
- 'wai/http-conformance/**'
- 'wai/score-conformance/**'
- 'wai/live-conformance/fleet/**'
- 'wai/REGISTRY.md'
- 'wai/LICENSE'
- 'wai/wai-quantum/**'
- 'wai/wai-ops/**'
- 'wai/wai-app/**'
- 'wai/wai-sink-swift/**'
- 'wai/wai-sink-android/**'
- 'joule-code/joule-code-rs/crates/*/openapi.json'
- 'scripts/check-wai-ops-doors.py'
- 'scripts/check-wai-ops-doors-selftest.sh'
- 'rust-toolchain.toml'
- '.github/workflows/wai-catalogue.yml'
jobs:
# The path filters gate the trigger; this job gates the work from the pull request's own
# diff (scripts/pr-touches-paths.py, reading the list above), as wai-pack.yml explains.
relevant:
name: does this change touch it
runs-on: linux-arm64
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-catalogue.yml \
"${{ github.event.pull_request.base.sha }}" \
"${{ github.event.pull_request.head.sha }}")
echo "this change touches the operation catalogue: $r"
echo "run=$r" >> "$GITHUB_OUTPUT"
catalogue:
name: the catalogue and every door · linux
needs: relevant
if: needs.relevant.outputs.run == 'true'
runs-on: linux
timeout-minutes: 60
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
SUDO=""; [ "$(id -u)" -ne 0 ] && SUDO="sudo"
command -v python3 >/dev/null || { $SUDO apt-get update -qq; $SUDO apt-get install -y -qq python3; }
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
# The export other tools and this workflow's door check read is the table, byte for
# byte; the message says how to regenerate it.
- name: The catalogue's export is up to date
working-directory: wai/wai-rs
run: cargo run -q --locked --no-default-features --bin wai -- ops export --check ../catalogue/ops.json
- name: Every door names its operations as the catalogue does
shell: bash
run: |
set -euo pipefail
bash scripts/check-wai-ops-doors-selftest.sh
python3 -I scripts/check-wai-ops-doors.py
# The library's catalogue tests: the naming rules, each broken in a copy of the table
# and refused. The binary's own tests: every implementation names an operation of the
# catalogue and every operation with a command line has one; help is the catalogue's.
# tests/cli_ops.rs: wai ops, help, the exit codes, the envelope, --dry-run and --yes (and
# --confirm, its deprecated spelling),
# first in the archive's build (quickstart), then with every command-line feature that
# needs no system library, so --dry-run is held on generate, score and stage too, and with
# Create's (app), so it is held on wai app export.
- name: The catalogue's rules, and the command line through it
shell: bash
working-directory: wai/wai-rs
run: |
set -euo pipefail
ran() { grep -qE '^test result: ok\. [1-9][0-9]* passed; 0 failed' "$1" || { echo "::error::no test ran in $1"; exit 1; }; }
cargo test --locked --no-default-features --lib catalogue 2>&1 | tee "$RUNNER_TEMP/lib.log"
ran "$RUNNER_TEMP/lib.log"
cargo test --locked --no-default-features --features quickstart --bin wai --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli.log"
ran "$RUNNER_TEMP/cli.log"
cargo test --locked --no-default-features --features quickstart,generate,score,staged,video_int,audio_int,splat_int --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-full.log"
ran "$RUNNER_TEMP/cli-full.log"
cargo test --locked --no-default-features --features quickstart,app --test cli_ops 2>&1 | tee "$RUNNER_TEMP/cli-app.log"
ran "$RUNNER_TEMP/cli-app.log"