wai: one operation catalogue (noun.verb) for every door, wai ops, the agent rules on every command, and the wai-* service binaries #506

Merged
dcharlot merged 26 commits from wai/ops-catalogue into main 2026-10-28 11:17:27 -04:00
Owner

WAI toolchain v1: one catalogue of noun.verb operations, the same name through every door, the agent rules on every command, and CI that fails on drift.

On today's main

#505, #508 and #507 have landed, and so have the fleet (#518) and wai-quantum 0.7.0 (#521). origin/main (25d38c48) is merged into this branch, with no rebase and no force push, so main is an ancestor of the head and this diff against main is this PR's own. Where the branch carried an earlier copy of #507, main's final version is the one kept, routed through the catalogue; there is one envelope and agent-rules module (wai_cli/dx/envelope.rs).

How each conflict was resolved

File Resolution
wai-rs/src/bin/wai_cli/dx/mod.rs The catalogue's VERBS (implementations by operation id) kept; main's Verb/Run::Checks/Run::Status table and dispatch, which the door replaces, not taken. The fleet's module is declared, and its four operations are implementations by id (next commit).
wai-rs/src/bin/wai_cli/dx/verify.rs Main's text (fleet bundles *.wai-fleet.json read and recomputed), with this branch's OpError and its usage from the catalogue.
wai-rs/src/bin/wai_cli/dx/envelope.rs This branch's (main's is the earlier #507 copy, unchanged): one module.
wai-rs/src/bin/wai_cli/dx/breaking/rust_api.rs, dx/conform/adapter.rs Main's: the base holds every standard its crate reaches by path; the adapter as #507 landed.
wai-rs/src/bin/wai_cli/dx/conform/mod.rs, tests/cli_conform.rs This branch's (main's are the earlier copy): the record's write through out.rs, reports under data.
wai-rs/tests/cli_breaking.rs Both: main's new test of a path dependency in another workspace, which reads findings through data.
wai-rs/Cargo.toml quickstart with main's fleet; both test targets, cli_ops and cli_fleet.
wai-rs/src/lib.rs strict_json gated on fleet too, as main has it; catalogue in place of ops.
.github/workflows/wai-conformance.yml Main's three hunks (the fleet feature and test in the verifier and per-feature steps); this branch's step text for wai mcp kept.
wai/CHANGELOG.md This entry above #507's and the fleet's, each whole.

Workflow steps against both merge parents: 0 problems (wfsteps.py 0abd2ae46 3363058002 270be911a 25d38c480); every workflow parses.

What is in it

The catalogue (wai/wai-rs/src/catalogue.rs, wai::catalogue). One Rust table holds every operation the toolchain offers that works today: id, summary, CLI spelling and aliases, usage, placement, input and output JSON Schemas (each input carries the flag or position that gives it; a service operation's schemas point into its OpenAPI document), stream, effect, route, toolset, stability, since/deprecated, receipt, the build features it needs, whether wai mcp serves it, and when it waits for confirmation (Op::confirms: never, a file the command line did not name, any file that exists, the target it names or a file, always; by its effect unless its entry says). wai ops export writes it as wai/catalogue/ops.json (format wai.ops/1), with each operation's name in every door and the agent flags (agent_flags).

Naming rules, enforced (library tests that also break each rule in a copy of the table and require it refused): lowercase noun.verb; a singular noun; a verb from N3's closed list; no near-synonym (get, describe, info are show; init, new, keygen are create); one CLI form per operation and none a prefix of another; a routed operation placed on a service and every service operation routed; every operation reachable by some door; a change to a target, or a destructive one, waits for --yes, and a read never does.

The fleet's operations (#518) are in the catalogue as the others are: enrolment.create, enrolment.list, report.create, report.export, placed on the client against a fleet service, with their effect, toolset, schemas, receipt and the feature they need (fleet for the two that sign or verify; the other two need none). wai enrolment|report run through the door, and the fleet's command module now keeps the agent rules of dx/envelope.rs instead of a copy of its own: the envelope with --json; every file through out.rs, and in a dry run every request the service would be sent named in the plan (out::would_send) and none sent; --yes before the service is changed or a file replaced. wai verify's entry names the conformance results and fleet bundles it reads.

wai ops: list, search "<task>" (offline, ranked over ids, command lines, aliases and summaries with stems and a few synonyms, at most five), show <id> (also wai ops schema), export [--out F | --check F].

The CLI through the catalogue (wai_cli/door.rs). A command line resolves through the catalogue alone: its spelling today (wai inspect, wai hello, wai mcp) or its id's words (wai envelope inspect). The implementation is found by id (door::IMPLS, and dx::VERBS for the developer path). wai --help, wai <cmd> --help and every usage error are written from the catalogue. Every command keeps its spelling.

The agent rules on every command, in one module: #507's wai_cli/dx/envelope.rs, extended, with wai_cli/out.rs for writes.

  • Exit codes 0 to 7: 0 done, 1 a check failed, 2 usage, 3 authentication or permission, 4 confirmation required, 5 not found, 6 target unavailable (retryable), 7 internal.
  • --json: one envelope on stdout, {"wai": "envelope/1", "op", "ok", "data" | "error": {code, message, hint, retryable}, "exit"}; exit 1 carries error and the report in data; exit 4 adds proposed and confirm; a dry run adds dry_run and plan. Logs stay on stderr. A command that prints text runs again as a child of wai for its envelope, so its text is unchanged.
  • --dry-run on every operation whose effect is not reads: every file a command writes goes through out.rs, which records instead of writing; wai dev, wai http origin and wai mcp say what they would start and start nothing.
  • One confirmation flag, --yes. An operation waits as its entry says (replacing a file the command line did not name; for wai conform, wai setup-agent and wai report export, any file that exists; for wai enrolment create, the fleet service or a file; for wai report create, always): at a terminal a prompt, otherwise exit 4 with the proposal and the exact confirming command, which names --yes. --no-input never asks. --confirm, which wai conform, wai setup-agent and the fleet took, is its deprecated spelling: it still works and does the same, and wai --help (written from catalogue::AGENT_FLAGS), every confirming operation's help and its usage line, and the export say it is deprecated. wai conform now confirms through the same module.

Reconciled with #507 in that one module: exit 3 (authentication or permission) is added; the envelope keeps #507's wai member; a command's report moves under data, as every other command's does; and JSON is printed only with --json (#507 also chose it whenever stdout is not a terminal; that would change every piped command's output, so it is not done). wai breaking --json and wai conform --json are unchanged otherwise, and --text still forces text.

Doors held to the catalogue (.github/workflows/wai-catalogue.yml):

  • the export is the table (wai ops export --check);
  • the CLI: every implementation names a catalogue operation and every operation with a command line has exactly one (the binary's tests); tests/cli_ops.rs holds help, the exit codes, the envelope, --dry-run and --yes across the operations, in the archive's build, with every command-line feature that needs no system library, and with Create's;
  • MCP: wai mcp's tool table both ways (every tool is an operation the catalogue says wai mcp serves, in that toolset, named noun_verb; every such operation is a tool; a tool of MCP alone takes the catalogue's input) in mcp/tools.rs's tests;
  • the room service's OpenAPI: every operationId is the catalogue's id at the catalogue's route, and every routed operation is described (joule-moq-room/tests/openapi_contract.rs);
  • scripts/check-wai-ops-doors.py (standard library only, with a selftest): MCP tool names, the services' operationIds, the C header, and the Swift and Kotlin sinks. In the C header and the sinks a name is an operation's when its noun is a catalogue noun and its verb an N3 verb; it must then be in the catalogue, and a near-synonym is refused. Other names are library API and reported as such.

Service binaries renamed (crates keep their names): joule-moq-relay builds wai-relay, joule-moq-room wai-room, joule-moq-ingest wai-ingest. wai dev and wai mcp's dev tools, the quickstart archive, the release and examples workflows, the browser and interop test scripts, the package manifests, the example host script, and the crates' READMEs and example configurations name them so. Wire and record identifiers (joule-moq-relay/session-summary/2, joule-moq-ingest/session/1), the JOULE_MOQ_*_LOG variables and the conformance corpora keep the crates' names. The messaging service is the room service (wai-room with [messaging]), so there is no separate binary. Production keeps running the old names until switched (a private deploy note covers it).

Templates are Apache-2.0: every example carries LICENSE (= wai/LICENSE) and a README line; wai create, from a template or from --from app.oui, writes it from one copy in the binary.

Telemetry: none. The wai binary's only network code is what a person names (wai http receipts, wai http bench, an HTTP wai conform adapter) and loopback (wai dev, wai mcp's bridge). Help, the README and the catalogue's README say: "wai sends nothing off your machine unless you name a remote service."

The catalogue

Operation CLI MCP Placement Effect Toolset Stability Needs
toolchain.test wai hello local writes-project core stable quickstart
project.create wai create local writes-project core stable
dev.start wai dev dev_start local runs dev stable
receipt.verify wai verify receipt_verify local reads core stable quickstart
envelope.inspect wai inspect envelope_inspect local reads core stable
envelope.wrap wai wrap envelope_wrap local writes-project core stable
envelope.unwrap wai unwrap local writes-project core stable
media.encode wai encode local writes-project core stable any of floor, codecs, platform_encode
media.decode wai decode local writes-project core stable any of floor, codecs
media.generate wai generate local writes-project core stable generate
score.build wai score build local writes-project core stable score
score.decode wai score render local writes-project core stable score
encoder.list wai encoders local reads core preview platform_encode
encoder.verify wai encode-record verify local reads core preview platform_encode
registry.list wai capabilities registry_list local reads core stable
registry.export wai registry export local writes-project maintainer stable
prior.list wai prior-set local reads core stable
stage.encode wai stage refine local writes-project core preview staged, video_int, audio_int, splat_int
stage.decode wai stage apply local reads core preview staged, video_int, audio_int, splat_int
stage.build wai stage base local writes-project core preview staged, video_int, audio_int, splat_int
stage.inspect wai stage inspect local reads core preview staged, video_int, audio_int, splat_int
stage.wrap wai stage pack local writes-project core preview staged, video_int, audio_int, splat_int
stage.unwrap wai stage explode local writes-project core preview staged, video_int, audio_int, splat_int
http.export wai http publish local writes-project core preview http
http.inspect wai http codecs local reads core preview http
http.start wai http origin local runs core preview http
hls.build wai http hls local writes-project core preview http
dash.build wai http mpd local writes-project core preview http
playlist.lock wai http seal-playlist local writes-project core preview http, video_manifest
playlist.verify wai http check-playlist local reads core preview http, video_manifest
corpus.generate wai http vectors local writes-project maintainer preview http
http.load wai http bench client writes-project core preview http
receipt.fetch wai http receipts client reads core preview http, receipt_claims
compat.check wai breaking local reads core stable
conformance.run wai conform conformance_run local writes-project core stable quickstart
conformance.list wai conformance list conformance_list local reads core stable quickstart
enrolment.create wai enrolment create client writes-target core preview fleet
enrolment.list wai enrolment list client reads core preview
report.create wai report create client writes-target core preview
report.export wai report export client writes-project core preview fleet
mcp.start wai mcp local runs core preview mcp
agent.setup wai setup-agent local writes-project core preview
app.guide wai app guide app_guide local reads app preview app
app.check wai app check app_check local reads app preview app
app.export wai app export app_export local writes-project app preview app
app.stream app_stream local runs app preview app
registry.show registry_show local reads core stable
docs.search docs_search local reads core stable
dev.stop dev_stop local runs dev stable
room.join room_join client writes-target dev stable
room.leave room_leave client writes-target dev stable
session.show session_show client reads dev stable
ops.list wai ops list local reads core stable
ops.search wai ops search local reads core stable
ops.show wai ops show (also wai ops schema) local reads core stable
ops.export wai ops export local writes-project core stable

The room service's operations, each placed on wai-room at its route (service), preview, toolset core or dev; room.grant is also an MCP tool (room_grant):

service.show, service.check, room.show, room.grant, admission.show, mls.tail, mls.import, mls.update, performance.list, performance.show, schedule.create, handover.create, window.create, fidelity.create, time.show, source.fetch, watch.setup, watch.tail, watch.show, watch.join, watch.update, control.grant, remote.show, remote.verify, conversation.show, conversation.setup, conversation.join, conversation.tail, conversation.import, conversation.update, message.create, acknowledgement.create, conversation.leave, member.delete, call.setup, call.create, call.invite, inbox.show, answer.create, call.show.

Names settled

  • N3 is enforced, so names approved earlier with a verb off the list take a listed verb, and the CLI keeps its spelling: wai hello is toolchain.test; wai mcp is mcp.start; the room session MCP tool is session_show; wai ops schema is ops.show (alias kept); wai score render is score.decode.
  • The specialist tools take the verb that says what they do, their spelling kept: wai stage refine|apply|base|pack|explode are stage.encode|decode|build|wrap|unwrap; wai http publish|codecs|origin|bench|receipts|vectors are http.export|inspect|start|load, receipt.fetch, corpus.generate; wai http hls|mpd are hls.build, dash.build; wai http seal-playlist|check-playlist are playlist.lock|verify; wai encode-record verify is encoder.verify; wai encoders encoder.list; wai prior-set prior.list.
  • The MCP tool package_build, which carries a file in an envelope as wai wrap does, is envelope_wrap; package.build stays free for real packaging when it has a door.
  • The room service's challenges are one form, watch.setup, conversation.setup, call.setup (they were watchchallenge.create, conversationchallenge.create, callchallenge.create). Posting a KeyPackage stays mls.import / conversation.import: import is on the list, and the service takes in a member's key material.
  • wai app export is app.export, the same writer as wai create <dir> --from app.oui.

Changed behaviour (each in the CHANGELOG)

  • The --json output of wai create --list, wai dev --check, wai generate, wai score build|render, wai stage apply, wai breaking, wai conform and wai setup-agent is now the envelope's data. In-repo readers are updated (the CLI tests, wai/quickstart/build.sh).
  • wai breaking and wai conform print text when piped, unless --json.
  • wai wrap/wai encode without -o over an existing out.wai, and wai hello over an earlier run, exit 4 off a terminal until --yes.
  • An unknown command exits 5 (it was 2), with the closest operations in the hint; an operation this build does not hold exits 5 naming the feature; a missing input file exits 5; wai dev whose stack does not come up exits 6.
  • The service binaries are wai-relay, wai-room, wai-ingest. Nothing main gained since names an old binary: the release workflow's Windows list and the examples workflow build wai-relay, wai-room and wai-remote-host; #518's text names joule-moq-relay only in the wire identifier joule-moq-relay/session-summary/2, which keeps it.
  • The fleet's operations print their JSON envelope only with --json (they printed it whenever standard output was not a terminal), as every command does; a dry run's members are the envelope's dry_run and plan (they were data.dry_run and data.proposed); a confirming command names --yes.
  • --confirm is deprecated; --yes is the flag.
  • Breaking, acknowledged in the CHANGELOG by the ids wai breaking gives them: wai::ops gives way to wai::catalogue (five Rust items), and the room service's three challenges take the operationIds N3 gives them (three OpenAPI items). wai breaking --against main reports these eight, all acknowledged, and nothing else.

Checks

Every Rust build and test ran on the Framework box (Linux x86_64) through rb; none on a workstation. Light scripts ran locally.

Check Host Result
cargo test --locked --no-default-features --lib catalogue Framework box 6 passed
cargo test --locked --no-default-features --features quickstart --bin wai --test cli_ops --test cli_dx --test cli_fleet --test floor Framework box 42, 2, 3, 9, 3 passed
cargo test --locked --no-default-features --features quickstart,score,key_discovery --bin wai --test cli_breaking --test cli_conform (wai-breaking.yml's runner) Framework box 42, 10, 6 passed
cargo test --locked --no-default-features --features mcp --bin wai --test cli_mcp --test cli_setup_agent Framework box 38, 10, 6 passed
cargo test --locked --no-default-features --features app --bin wai --test cli_app Framework box 38, 5 passed
cargo test --locked --no-default-features --features quickstart,generate,score,staged,video_int,audio_int,splat_int --test cli_ops; the same with quickstart,app Framework box 9 passed each (dry run held on the fleet's operations, generate, score, stage and app export)
cargo test --no-default-features --features fleet,conform_result --test fleet --test conform_result Framework box 4, 6 passed
wai-conformance's independent-verifier build: $WAI_FEATURES (with fleet and conform_result) --bins, and --lib catalogue under it Framework box builds; 6 passed
cargo check --no-default-features --tests with no feature, fleet, conform_result, key_discovery, mcp, app, quickstart Framework box clean
cargo clippy on --bin wai and the three CLI tests, with quickstart, the full command-line features and fleet Framework box no note in any file this PR touches
wai ops export --check ../catalogue/ops.json; the export from a bare build and from quickstart,app Framework box up to date; byte-identical
wai breaking --against main --text --all Framework box 8 breaking changes, all acknowledged; exit 0
wai conform over the claim, JWP, signer and conform-result verifiers and the reference packager, then wai verify (wai-breaking.yml's steps) Framework box each conformant; 5 results verified
joule-moq-room: openapi_contract, mcp_dev_room; wai-fleet build Framework box 1, 4 passed; builds
cargo metadata --locked --offline in wai-rs, joule-code-rs, joule-moq-room, joule-moq-remote, wai-fleet, wai-pack, wai-app Framework box every lock valid
check-wai-ops-doors.py and its selftest local 0 findings; every case held
check-tests-in-ci.py, check-workflow-concurrency.sh, check-spec-refs.py, check-wai-section-refs.py, check-no-vanity-metrics.sh, test-public-text-checks.sh, check-comparative-prose.sh, check-orphan-sources.py, every workflow's YAML local all pass
public-name check on every changed file, the commit messages and this body local clean

Falsifications

Committed first; each mutation an exact one-match edit, restored with git checkout -- and a fresh mtime. Every one was caught. The first three are this round's, on the merged head; the rest were made on the earlier head and their guards are unchanged.

Broken rule Guard Result
a fleet operation missing from the catalogue (enrolment.create removed) door::tests::every_implementation_names_an_operation_of_the_catalogue; wai ops export --check; cli_fleet fails ("the CLI runs enrolment.create, which the catalogue does not hold"); exit 1; 2 tests fail
--confirm no longer the same as --yes (the door reads --yes alone) cli_ops::confirm_is_the_deprecated_spelling_of_yes; cli_fleet::enrolment_create_signs_writes_and_waits_for_confirmation both fail
wai report create changing the service without --yes cli_fleet::report_create_and_export_and_verify fails (exit 0, not 4)
Broken rule (earlier head) Guard Result
a CLI verb not in the catalogue (Impl { id: "envelope.frob" }) door::tests::every_implementation_names_an_operation_of_the_catalogue fails
a catalogue operation with no CLI implementation (prior.list removed) door::tests::every_operation_with_a_command_line_has_exactly_one_implementation fails
a write past out.rs (wrap writing directly) cli_ops::every_operation_that_is_not_read_only_writes_nothing_with_dry_run fails
an operation turned writer with no dry-run sample the same test fails
a missing file exiting 2, not 5 cli_ops::the_exit_codes_say_what_happened fails
a confirmation exiting 1, not 4 cli_ops::replacing_a_file_the_command_line_did_not_name_waits_for_yes fails
a near-synonym id (registry.get) catalogue::tests::every_entry_keeps_the_rules fails
an id off N3's list (room.session) the same test fails
the export behind the table wai ops export --check exit 1
the MCP tool envelope_wrap named package_build in the real tool table mcp/tools.rs tests; check-wai-ops-doors.py three tests fail; 1 finding
an operation the catalogue says wai mcp serves, with no tool mcp/tools.rs tests fails
the room service's operationId watch.setup named watchchallenge.create openapi_contract; check-wai-ops-doors.py fails; 1 finding
a catalogue route the room service does not describe (/inboxes) openapi_contract fails
a C function misnamed (wai_envelope_decode) check-wai-ops-doors.py 1 finding, pointing at media.decode
a Swift name misnamed (WaiReceipt.check) check-wai-ops-doors.py 1 finding
a Kotlin name with a near-synonym (WaiEnvelope.describe) check-wai-ops-doors.py 1 finding

Not done

  • The Rust (wai::noun::verb) and JavaScript doors are not checked: neither is organised by operation yet. The C header and the sinks carry no catalogue operation today; the check reports their names as library API.
  • An MCP compat_check tool (wai breaking as a tool through breaking::run).
  • wai serve <role>, an ops_run tool, wai --version --json, a generated CLI reference and llms.txt.
  • JSON whenever stdout is not a terminal (rule A1), as above.
  • The operations named but not built (a doctor, deriving an edge configuration, meter calibration, an audit report) are not in the catalogue: it lists what works.
  • For an operation with both a CLI and an MCP door (conformance.run, envelope.wrap), the MCP tool's input schema is the tool's own; the catalogue's is the CLI's.
  • WAI Studio (#522) is not on main, so its pending copy of the catalogue (wai/wai-studio/ops.pending.json) is not retired here, and room.test is not added; that is for whichever of the two lands second.
  • The fleet service's own HTTP API (wai-fleet serve) has no OpenAPI document, so its routes are not catalogue operations of their own; the four operations are the client's.
  • wai-quantum's command line and MCP servers are a separate binary with their own tool lists; the door check reads wai mcp's alone.

🤖 Generated with Claude Code

WAI toolchain v1: one catalogue of `noun.verb` operations, the same name through every door, the agent rules on every command, and CI that fails on drift. ## On today's main #505, #508 and #507 have landed, and so have the fleet (#518) and wai-quantum 0.7.0 (#521). `origin/main` (`25d38c48`) is merged into this branch, with no rebase and no force push, so main is an ancestor of the head and this diff against main is this PR's own. Where the branch carried an earlier copy of #507, main's final version is the one kept, routed through the catalogue; there is one envelope and agent-rules module (`wai_cli/dx/envelope.rs`). ### How each conflict was resolved | File | Resolution | |---|---| | `wai-rs/src/bin/wai_cli/dx/mod.rs` | The catalogue's `VERBS` (implementations by operation id) kept; main's `Verb`/`Run::Checks`/`Run::Status` table and `dispatch`, which the door replaces, not taken. The fleet's module is declared, and its four operations are implementations by id (next commit). | | `wai-rs/src/bin/wai_cli/dx/verify.rs` | Main's text (fleet bundles `*.wai-fleet.json` read and recomputed), with this branch's `OpError` and its usage from the catalogue. | | `wai-rs/src/bin/wai_cli/dx/envelope.rs` | This branch's (main's is the earlier #507 copy, unchanged): one module. | | `wai-rs/src/bin/wai_cli/dx/breaking/rust_api.rs`, `dx/conform/adapter.rs` | Main's: the base holds every standard its crate reaches by path; the adapter as #507 landed. | | `wai-rs/src/bin/wai_cli/dx/conform/mod.rs`, `tests/cli_conform.rs` | This branch's (main's are the earlier copy): the record's write through `out.rs`, reports under `data`. | | `wai-rs/tests/cli_breaking.rs` | Both: main's new test of a path dependency in another workspace, which reads findings through `data`. | | `wai-rs/Cargo.toml` | `quickstart` with main's `fleet`; both test targets, `cli_ops` and `cli_fleet`. | | `wai-rs/src/lib.rs` | `strict_json` gated on `fleet` too, as main has it; `catalogue` in place of `ops`. | | `.github/workflows/wai-conformance.yml` | Main's three hunks (the `fleet` feature and test in the verifier and per-feature steps); this branch's step text for `wai mcp` kept. | | `wai/CHANGELOG.md` | This entry above #507's and the fleet's, each whole. | Workflow steps against both merge parents: 0 problems (`wfsteps.py 0abd2ae46 3363058002 270be911a 25d38c480`); every workflow parses. ## What is in it **The catalogue** (`wai/wai-rs/src/catalogue.rs`, `wai::catalogue`). One Rust table holds every operation the toolchain offers that works today: id, summary, CLI spelling and aliases, usage, placement, input and output JSON Schemas (each input carries the flag or position that gives it; a service operation's schemas point into its OpenAPI document), stream, effect, route, toolset, stability, since/deprecated, receipt, the build features it needs, whether `wai mcp` serves it, and when it waits for confirmation (`Op::confirms`: never, a file the command line did not name, any file that exists, the target it names or a file, always; by its effect unless its entry says). `wai ops export` writes it as `wai/catalogue/ops.json` (format `wai.ops/1`), with each operation's name in every door and the agent flags (`agent_flags`). **Naming rules, enforced** (library tests that also break each rule in a copy of the table and require it refused): lowercase `noun.verb`; a singular noun; a verb from N3's closed list; no near-synonym (`get`, `describe`, `info` are `show`; `init`, `new`, `keygen` are `create`); one CLI form per operation and none a prefix of another; a routed operation placed on a service and every service operation routed; every operation reachable by some door; a change to a target, or a destructive one, waits for `--yes`, and a read never does. **The fleet's operations** (#518) are in the catalogue as the others are: `enrolment.create`, `enrolment.list`, `report.create`, `report.export`, placed on the client against a fleet service, with their effect, toolset, schemas, receipt and the feature they need (`fleet` for the two that sign or verify; the other two need none). `wai enrolment|report` run through the door, and the fleet's command module now keeps the agent rules of `dx/envelope.rs` instead of a copy of its own: the envelope with `--json`; every file through `out.rs`, and in a dry run every request the service would be sent named in the plan (`out::would_send`) and none sent; `--yes` before the service is changed or a file replaced. `wai verify`'s entry names the conformance results and fleet bundles it reads. **`wai ops`**: `list`, `search "<task>"` (offline, ranked over ids, command lines, aliases and summaries with stems and a few synonyms, at most five), `show <id>` (also `wai ops schema`), `export [--out F | --check F]`. **The CLI through the catalogue** (`wai_cli/door.rs`). A command line resolves through the catalogue alone: its spelling today (`wai inspect`, `wai hello`, `wai mcp`) or its id's words (`wai envelope inspect`). The implementation is found by id (`door::IMPLS`, and `dx::VERBS` for the developer path). `wai --help`, `wai <cmd> --help` and every usage error are written from the catalogue. Every command keeps its spelling. **The agent rules on every command**, in one module: #507's `wai_cli/dx/envelope.rs`, extended, with `wai_cli/out.rs` for writes. - Exit codes 0 to 7: 0 done, 1 a check failed, 2 usage, 3 authentication or permission, 4 confirmation required, 5 not found, 6 target unavailable (retryable), 7 internal. - `--json`: one envelope on stdout, `{"wai": "envelope/1", "op", "ok", "data" | "error": {code, message, hint, retryable}, "exit"}`; exit 1 carries `error` and the report in `data`; exit 4 adds `proposed` and `confirm`; a dry run adds `dry_run` and `plan`. Logs stay on stderr. A command that prints text runs again as a child of `wai` for its envelope, so its text is unchanged. - `--dry-run` on every operation whose effect is not `reads`: every file a command writes goes through `out.rs`, which records instead of writing; `wai dev`, `wai http origin` and `wai mcp` say what they would start and start nothing. - **One confirmation flag, `--yes`.** An operation waits as its entry says (replacing a file the command line did not name; for `wai conform`, `wai setup-agent` and `wai report export`, any file that exists; for `wai enrolment create`, the fleet service or a file; for `wai report create`, always): at a terminal a prompt, otherwise exit 4 with the proposal and the exact confirming command, which names `--yes`. `--no-input` never asks. `--confirm`, which `wai conform`, `wai setup-agent` and the fleet took, is its deprecated spelling: it still works and does the same, and `wai --help` (written from `catalogue::AGENT_FLAGS`), every confirming operation's help and its usage line, and the export say it is deprecated. `wai conform` now confirms through the same module. **Reconciled with #507 in that one module**: exit 3 (authentication or permission) is added; the envelope keeps #507's `wai` member; a command's report moves under `data`, as every other command's does; and JSON is printed only with `--json` (#507 also chose it whenever stdout is not a terminal; that would change every piped command's output, so it is not done). `wai breaking --json` and `wai conform --json` are unchanged otherwise, and `--text` still forces text. **Doors held to the catalogue** (`.github/workflows/wai-catalogue.yml`): - the export is the table (`wai ops export --check`); - the CLI: every implementation names a catalogue operation and every operation with a command line has exactly one (the binary's tests); `tests/cli_ops.rs` holds help, the exit codes, the envelope, `--dry-run` and `--yes` across the operations, in the archive's build, with every command-line feature that needs no system library, and with Create's; - MCP: `wai mcp`'s tool table both ways (every tool is an operation the catalogue says `wai mcp` serves, in that toolset, named `noun_verb`; every such operation is a tool; a tool of MCP alone takes the catalogue's input) in `mcp/tools.rs`'s tests; - the room service's OpenAPI: every `operationId` is the catalogue's id at the catalogue's route, and every routed operation is described (`joule-moq-room/tests/openapi_contract.rs`); - `scripts/check-wai-ops-doors.py` (standard library only, with a selftest): MCP tool names, the services' `operationId`s, the C header, and the Swift and Kotlin sinks. In the C header and the sinks a name is an operation's when its noun is a catalogue noun and its verb an N3 verb; it must then be in the catalogue, and a near-synonym is refused. Other names are library API and reported as such. **Service binaries renamed** (crates keep their names): `joule-moq-relay` builds `wai-relay`, `joule-moq-room` `wai-room`, `joule-moq-ingest` `wai-ingest`. `wai dev` and `wai mcp`'s dev tools, the quickstart archive, the release and examples workflows, the browser and interop test scripts, the package manifests, the example host script, and the crates' READMEs and example configurations name them so. Wire and record identifiers (`joule-moq-relay/session-summary/2`, `joule-moq-ingest/session/1`), the `JOULE_MOQ_*_LOG` variables and the conformance corpora keep the crates' names. The messaging service is the room service (`wai-room` with `[messaging]`), so there is no separate binary. Production keeps running the old names until switched (a private deploy note covers it). **Templates are Apache-2.0**: every example carries `LICENSE` (= `wai/LICENSE`) and a README line; `wai create`, from a template or from `--from app.oui`, writes it from one copy in the binary. **Telemetry**: none. The `wai` binary's only network code is what a person names (`wai http receipts`, `wai http bench`, an HTTP `wai conform` adapter) and loopback (`wai dev`, `wai mcp`'s bridge). Help, the README and the catalogue's README say: "`wai` sends nothing off your machine unless you name a remote service." ## The catalogue | Operation | CLI | MCP | Placement | Effect | Toolset | Stability | Needs | |---|---|---|---|---|---|---|---| | `toolchain.test` | `wai hello` | | local | writes-project | core | stable | quickstart | | `project.create` | `wai create` | | local | writes-project | core | stable | | | `dev.start` | `wai dev` | `dev_start` | local | runs | dev | stable | | | `receipt.verify` | `wai verify` | `receipt_verify` | local | reads | core | stable | quickstart | | `envelope.inspect` | `wai inspect` | `envelope_inspect` | local | reads | core | stable | | | `envelope.wrap` | `wai wrap` | `envelope_wrap` | local | writes-project | core | stable | | | `envelope.unwrap` | `wai unwrap` | | local | writes-project | core | stable | | | `media.encode` | `wai encode` | | local | writes-project | core | stable | any of floor, codecs, platform_encode | | `media.decode` | `wai decode` | | local | writes-project | core | stable | any of floor, codecs | | `media.generate` | `wai generate` | | local | writes-project | core | stable | generate | | `score.build` | `wai score build` | | local | writes-project | core | stable | score | | `score.decode` | `wai score render` | | local | writes-project | core | stable | score | | `encoder.list` | `wai encoders` | | local | reads | core | preview | platform_encode | | `encoder.verify` | `wai encode-record verify` | | local | reads | core | preview | platform_encode | | `registry.list` | `wai capabilities` | `registry_list` | local | reads | core | stable | | | `registry.export` | `wai registry export` | | local | writes-project | maintainer | stable | | | `prior.list` | `wai prior-set` | | local | reads | core | stable | | | `stage.encode` | `wai stage refine` | | local | writes-project | core | preview | staged, video_int, audio_int, splat_int | | `stage.decode` | `wai stage apply` | | local | reads | core | preview | staged, video_int, audio_int, splat_int | | `stage.build` | `wai stage base` | | local | writes-project | core | preview | staged, video_int, audio_int, splat_int | | `stage.inspect` | `wai stage inspect` | | local | reads | core | preview | staged, video_int, audio_int, splat_int | | `stage.wrap` | `wai stage pack` | | local | writes-project | core | preview | staged, video_int, audio_int, splat_int | | `stage.unwrap` | `wai stage explode` | | local | writes-project | core | preview | staged, video_int, audio_int, splat_int | | `http.export` | `wai http publish` | | local | writes-project | core | preview | http | | `http.inspect` | `wai http codecs` | | local | reads | core | preview | http | | `http.start` | `wai http origin` | | local | runs | core | preview | http | | `hls.build` | `wai http hls` | | local | writes-project | core | preview | http | | `dash.build` | `wai http mpd` | | local | writes-project | core | preview | http | | `playlist.lock` | `wai http seal-playlist` | | local | writes-project | core | preview | http, video_manifest | | `playlist.verify` | `wai http check-playlist` | | local | reads | core | preview | http, video_manifest | | `corpus.generate` | `wai http vectors` | | local | writes-project | maintainer | preview | http | | `http.load` | `wai http bench` | | client | writes-project | core | preview | http | | `receipt.fetch` | `wai http receipts` | | client | reads | core | preview | http, receipt_claims | | `compat.check` | `wai breaking` | | local | reads | core | stable | | | `conformance.run` | `wai conform` | `conformance_run` | local | writes-project | core | stable | quickstart | | `conformance.list` | `wai conformance list` | `conformance_list` | local | reads | core | stable | quickstart | | `enrolment.create` | `wai enrolment create` | | client | writes-target | core | preview | fleet | | `enrolment.list` | `wai enrolment list` | | client | reads | core | preview | | | `report.create` | `wai report create` | | client | writes-target | core | preview | | | `report.export` | `wai report export` | | client | writes-project | core | preview | fleet | | `mcp.start` | `wai mcp` | | local | runs | core | preview | mcp | | `agent.setup` | `wai setup-agent` | | local | writes-project | core | preview | | | `app.guide` | `wai app guide` | `app_guide` | local | reads | app | preview | app | | `app.check` | `wai app check` | `app_check` | local | reads | app | preview | app | | `app.export` | `wai app export` | `app_export` | local | writes-project | app | preview | app | | `app.stream` | | `app_stream` | local | runs | app | preview | app | | `registry.show` | | `registry_show` | local | reads | core | stable | | | `docs.search` | | `docs_search` | local | reads | core | stable | | | `dev.stop` | | `dev_stop` | local | runs | dev | stable | | | `room.join` | | `room_join` | client | writes-target | dev | stable | | | `room.leave` | | `room_leave` | client | writes-target | dev | stable | | | `session.show` | | `session_show` | client | reads | dev | stable | | | `ops.list` | `wai ops list` | | local | reads | core | stable | | | `ops.search` | `wai ops search` | | local | reads | core | stable | | | `ops.show` | `wai ops show` (also `wai ops schema`) | | local | reads | core | stable | | | `ops.export` | `wai ops export` | | local | writes-project | core | stable | | The room service's operations, each placed on `wai-room` at its route (`service`), `preview`, toolset `core` or `dev`; `room.grant` is also an MCP tool (`room_grant`): `service.show`, `service.check`, `room.show`, `room.grant`, `admission.show`, `mls.tail`, `mls.import`, `mls.update`, `performance.list`, `performance.show`, `schedule.create`, `handover.create`, `window.create`, `fidelity.create`, `time.show`, `source.fetch`, `watch.setup`, `watch.tail`, `watch.show`, `watch.join`, `watch.update`, `control.grant`, `remote.show`, `remote.verify`, `conversation.show`, `conversation.setup`, `conversation.join`, `conversation.tail`, `conversation.import`, `conversation.update`, `message.create`, `acknowledgement.create`, `conversation.leave`, `member.delete`, `call.setup`, `call.create`, `call.invite`, `inbox.show`, `answer.create`, `call.show`. ## Names settled - **N3 is enforced**, so names approved earlier with a verb off the list take a listed verb, and the CLI keeps its spelling: `wai hello` is `toolchain.test`; `wai mcp` is `mcp.start`; the room session MCP tool is `session_show`; `wai ops schema` is `ops.show` (alias kept); `wai score render` is `score.decode`. - **The specialist tools** take the verb that says what they do, their spelling kept: `wai stage refine|apply|base|pack|explode` are `stage.encode|decode|build|wrap|unwrap`; `wai http publish|codecs|origin|bench|receipts|vectors` are `http.export|inspect|start|load`, `receipt.fetch`, `corpus.generate`; `wai http hls|mpd` are `hls.build`, `dash.build`; `wai http seal-playlist|check-playlist` are `playlist.lock|verify`; `wai encode-record verify` is `encoder.verify`; `wai encoders` `encoder.list`; `wai prior-set` `prior.list`. - **The MCP tool `package_build`**, which carries a file in an envelope as `wai wrap` does, is `envelope_wrap`; `package.build` stays free for real packaging when it has a door. - **The room service's challenges** are one form, `watch.setup`, `conversation.setup`, `call.setup` (they were `watchchallenge.create`, `conversationchallenge.create`, `callchallenge.create`). Posting a KeyPackage stays `mls.import` / `conversation.import`: import is on the list, and the service takes in a member's key material. - **`wai app export`** is `app.export`, the same writer as `wai create <dir> --from app.oui`. ## Changed behaviour (each in the CHANGELOG) - The `--json` output of `wai create --list`, `wai dev --check`, `wai generate`, `wai score build|render`, `wai stage apply`, `wai breaking`, `wai conform` and `wai setup-agent` is now the envelope's `data`. In-repo readers are updated (the CLI tests, `wai/quickstart/build.sh`). - `wai breaking` and `wai conform` print text when piped, unless `--json`. - `wai wrap`/`wai encode` without `-o` over an existing `out.wai`, and `wai hello` over an earlier run, exit 4 off a terminal until `--yes`. - An unknown command exits 5 (it was 2), with the closest operations in the hint; an operation this build does not hold exits 5 naming the feature; a missing input file exits 5; `wai dev` whose stack does not come up exits 6. - The service binaries are `wai-relay`, `wai-room`, `wai-ingest`. Nothing main gained since names an old binary: the release workflow's Windows list and the examples workflow build `wai-relay`, `wai-room` and `wai-remote-host`; #518's text names `joule-moq-relay` only in the wire identifier `joule-moq-relay/session-summary/2`, which keeps it. - The fleet's operations print their JSON envelope only with `--json` (they printed it whenever standard output was not a terminal), as every command does; a dry run's members are the envelope's `dry_run` and `plan` (they were `data.dry_run` and `data.proposed`); a confirming command names `--yes`. - `--confirm` is deprecated; `--yes` is the flag. - **Breaking**, acknowledged in the CHANGELOG by the ids `wai breaking` gives them: `wai::ops` gives way to `wai::catalogue` (five Rust items), and the room service's three challenges take the `operationId`s N3 gives them (three OpenAPI items). `wai breaking --against main` reports these eight, all acknowledged, and nothing else. ## Checks Every Rust build and test ran on the Framework box (Linux x86_64) through `rb`; none on a workstation. Light scripts ran locally. | Check | Host | Result | |---|---|---| | `cargo test --locked --no-default-features --lib catalogue` | Framework box | 6 passed | | `cargo test --locked --no-default-features --features quickstart --bin wai --test cli_ops --test cli_dx --test cli_fleet --test floor` | Framework box | 42, 2, 3, 9, 3 passed | | `cargo test --locked --no-default-features --features quickstart,score,key_discovery --bin wai --test cli_breaking --test cli_conform` (wai-breaking.yml's runner) | Framework box | 42, 10, 6 passed | | `cargo test --locked --no-default-features --features mcp --bin wai --test cli_mcp --test cli_setup_agent` | Framework box | 38, 10, 6 passed | | `cargo test --locked --no-default-features --features app --bin wai --test cli_app` | Framework box | 38, 5 passed | | `cargo test --locked --no-default-features --features quickstart,generate,score,staged,video_int,audio_int,splat_int --test cli_ops`; the same with `quickstart,app` | Framework box | 9 passed each (dry run held on the fleet's operations, generate, score, stage and app export) | | `cargo test --no-default-features --features fleet,conform_result --test fleet --test conform_result` | Framework box | 4, 6 passed | | wai-conformance's independent-verifier build: `$WAI_FEATURES` (with `fleet` and `conform_result`) `--bins`, and `--lib catalogue` under it | Framework box | builds; 6 passed | | `cargo check --no-default-features --tests` with no feature, `fleet`, `conform_result`, `key_discovery`, `mcp`, `app`, `quickstart` | Framework box | clean | | `cargo clippy` on `--bin wai` and the three CLI tests, with `quickstart`, the full command-line features and `fleet` | Framework box | no note in any file this PR touches | | `wai ops export --check ../catalogue/ops.json`; the export from a bare build and from `quickstart,app` | Framework box | up to date; byte-identical | | `wai breaking --against main --text --all` | Framework box | 8 breaking changes, all acknowledged; exit 0 | | `wai conform` over the claim, JWP, signer and conform-result verifiers and the reference packager, then `wai verify` (wai-breaking.yml's steps) | Framework box | each conformant; 5 results verified | | `joule-moq-room`: `openapi_contract`, `mcp_dev_room`; `wai-fleet` build | Framework box | 1, 4 passed; builds | | `cargo metadata --locked --offline` in wai-rs, joule-code-rs, joule-moq-room, joule-moq-remote, wai-fleet, wai-pack, wai-app | Framework box | every lock valid | | `check-wai-ops-doors.py` and its selftest | local | 0 findings; every case held | | `check-tests-in-ci.py`, `check-workflow-concurrency.sh`, `check-spec-refs.py`, `check-wai-section-refs.py`, `check-no-vanity-metrics.sh`, `test-public-text-checks.sh`, `check-comparative-prose.sh`, `check-orphan-sources.py`, every workflow's YAML | local | all pass | | public-name check on every changed file, the commit messages and this body | local | clean | ## Falsifications Committed first; each mutation an exact one-match edit, restored with `git checkout --` and a fresh mtime. Every one was caught. The first three are this round's, on the merged head; the rest were made on the earlier head and their guards are unchanged. | Broken rule | Guard | Result | |---|---|---| | a fleet operation missing from the catalogue (`enrolment.create` removed) | `door::tests::every_implementation_names_an_operation_of_the_catalogue`; `wai ops export --check`; `cli_fleet` | fails ("the CLI runs enrolment.create, which the catalogue does not hold"); exit 1; 2 tests fail | | `--confirm` no longer the same as `--yes` (the door reads `--yes` alone) | `cli_ops::confirm_is_the_deprecated_spelling_of_yes`; `cli_fleet::enrolment_create_signs_writes_and_waits_for_confirmation` | both fail | | `wai report create` changing the service without `--yes` | `cli_fleet::report_create_and_export_and_verify` | fails (exit 0, not 4) | | Broken rule (earlier head) | Guard | Result | |---|---|---| | a CLI verb not in the catalogue (`Impl { id: "envelope.frob" }`) | `door::tests::every_implementation_names_an_operation_of_the_catalogue` | fails | | a catalogue operation with no CLI implementation (`prior.list` removed) | `door::tests::every_operation_with_a_command_line_has_exactly_one_implementation` | fails | | a write past `out.rs` (`wrap` writing directly) | `cli_ops::every_operation_that_is_not_read_only_writes_nothing_with_dry_run` | fails | | an operation turned writer with no dry-run sample | the same test | fails | | a missing file exiting 2, not 5 | `cli_ops::the_exit_codes_say_what_happened` | fails | | a confirmation exiting 1, not 4 | `cli_ops::replacing_a_file_the_command_line_did_not_name_waits_for_yes` | fails | | a near-synonym id (`registry.get`) | `catalogue::tests::every_entry_keeps_the_rules` | fails | | an id off N3's list (`room.session`) | the same test | fails | | the export behind the table | `wai ops export --check` | exit 1 | | the MCP tool `envelope_wrap` named `package_build` in the real tool table | `mcp/tools.rs` tests; `check-wai-ops-doors.py` | three tests fail; 1 finding | | an operation the catalogue says `wai mcp` serves, with no tool | `mcp/tools.rs` tests | fails | | the room service's `operationId` `watch.setup` named `watchchallenge.create` | `openapi_contract`; `check-wai-ops-doors.py` | fails; 1 finding | | a catalogue route the room service does not describe (`/inboxes`) | `openapi_contract` | fails | | a C function misnamed (`wai_envelope_decode`) | `check-wai-ops-doors.py` | 1 finding, pointing at `media.decode` | | a Swift name misnamed (`WaiReceipt.check`) | `check-wai-ops-doors.py` | 1 finding | | a Kotlin name with a near-synonym (`WaiEnvelope.describe`) | `check-wai-ops-doors.py` | 1 finding | ## Not done - The Rust (`wai::noun::verb`) and JavaScript doors are not checked: neither is organised by operation yet. The C header and the sinks carry no catalogue operation today; the check reports their names as library API. - An MCP `compat_check` tool (`wai breaking` as a tool through `breaking::run`). - `wai serve <role>`, an `ops_run` tool, `wai --version --json`, a generated CLI reference and `llms.txt`. - JSON whenever stdout is not a terminal (rule A1), as above. - The operations named but not built (a doctor, deriving an edge configuration, meter calibration, an audit report) are not in the catalogue: it lists what works. - For an operation with both a CLI and an MCP door (`conformance.run`, `envelope.wrap`), the MCP tool's input schema is the tool's own; the catalogue's is the CLI's. - WAI Studio (#522) is not on main, so its pending copy of the catalogue (`wai/wai-studio/ops.pending.json`) is not retired here, and `room.test` is not added; that is for whichever of the two lands second. - The fleet service's own HTTP API (`wai-fleet serve`) has no OpenAPI document, so its routes are not catalogue operations of their own; the four operations are the client's. - `wai-quantum`'s command line and MCP servers are a separate binary with their own tool lists; the door check reads `wai mcp`'s alone. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
One Rust table in the wai crate holds every operation the toolchain offers: its id
(noun.verb), summary, CLI spelling and aliases, placement, input and output JSON Schemas,
stream, effect, route, toolset, stability, since/deprecated, whether it writes a receipt,
and the build features it needs. It lists only operations that work today. Its tests hold
the naming rules (noun.verb, no near-synonym verb, singular nouns, one command line per
operation, a route exactly when it runs on a service) and break each rule to show it is
refused. wai/catalogue/ops.json is its export (wai.ops/1).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Every command line resolves through the catalogue (wai_cli/door.rs): its CLI spelling, an
alias, or its mechanical form wai <noun> <verb>; an implementation is found by operation
id, and help is written from the catalogue's entries. dx::VERBS is the developer path's view
of it. Every command keeps the agent rules (wai_cli/agent.rs): exit codes 0 to 7, --json
(a versioned envelope, envelope/1, carrying a command's own JSON or its text in data),
--dry-run on every operation that is not read-only (every write goes through
wai_cli/out.rs), and --yes where a change waits for confirmation (exit 4 off a terminal).
wai ops list, search, schema and export. The tests and the quickstart's packaging check read
the JSON forms from the envelope's data.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Each example holds the license's text as LICENSE (wai/LICENSE, byte for byte) and says so in
its README; wai create writes it with the rest of the template, from one copy in the binary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
WAI toolchain decision 11: joule-moq-relay builds wai-relay, joule-moq-room wai-room, and
joule-moq-ingest wai-ingest. wai dev finds them by those names (WAI_RELAY_BIN, WAI_ROOM_BIN),
and the quickstart archive, the release workflow, the examples' workflow, the browser
tests, the interop scripts, the example host script, the Scoop manifest and the crates'
READMEs and example configurations name them so. Wire and record identifiers that carry a
crate's name (joule-moq-relay/session-summary/2, joule-moq-ingest/session/1, the relay's
MOQT implementation string) and the log variables (JOULE_MOQ_*_LOG) are unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
MCP tool names (noun_verb), the services' OpenAPI operationIds (the id, placed on a service,
at its route), the C header's functions (wai_noun_verb where the noun is the catalogue's and
the verb an operation verb) and the Swift and Kotlin sinks' public methods (Wai<Noun>.<verb>)
are read and held to wai/catalogue/ops.json; a door with no operation yet says so. The
selftest misnames each door's operation and requires the check to fail and say which.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai ops list, search, schema and export (the export is the committed file, a drifted copy
exits 1); every operation's help from its entry and its mechanical form; the exit codes 1 to
6 each from a real case; the envelope on success, failure and confirmation; --yes; and
--dry-run on every operation of the build whose effect is not reads, each shown to write
nothing with it and to write without it, with generate, score and stage covered in a build
that has them. A new operation that writes cannot join the catalogue without a sample here.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
CI: the WAI operation catalogue workflow; the catalogue's README, the changelog
Some checks failed
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
wai-key-proxy / does this change touch it (pull_request) Has been cancelled
wai-key-proxy / proxy · linux (pull_request) Has been cancelled
wai-ledger service / does this change touch it (pull_request) Has been cancelled
wai-ledger service / service · linux (pull_request) Has been cancelled
wai-ledger service / service · macos (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-quantum studio and desktop / does this change touch it (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-sink-android native sink library / does this change touch it (pull_request) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Has been cancelled
wai-sink-swift native sink package / does this change touch it (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
9d18a895f1
.github/workflows/wai-catalogue.yml fails on drift: the export against the table, every door's
names against the catalogue (with the check's selftest), the catalogue's rules, and the
command line's tests in the archive's build and with every command-line feature that needs no
system library.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai ops: the command line carries only the operations it implements; the door check reads a tool table by operation
Some checks failed
standards workspaces build + test / macOS energy backends (pull_request) Successful in 9m22s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 9m23s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 26s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m1s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 18m50s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
wai-ledger service / service · macos (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Has been cancelled
ef6dda46ee
An operation served only over HTTP or MCP has no command line: it does not resolve, help does
not list it as a command, and the dry-run test asks no sample of it. check-wai-ops-doors.py
reads an MCP tool named by its operation (op: "noun.verb") as well as one named outright.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`wai breaking --against <git-ref>` (operation compat.check) reports what the working
tree breaks against the merge base of a ref, in three cumulative categories: wire (the
registry export, the media and delivery corpora), record (the signing domains, magics
and versions in the WAI crates' sources, the record corpora, the published JSON
Schemas) and API (the Rust public API of wai and wai-quantum from rustdoc's JSON, the
C header, the room service's OpenAPI document). Each finding names its item, category,
what changed and why it breaks; additions are compatible. A break passes only when a
line the change adds to wai/CHANGELOG.md, in an entry that says Breaking, names its id.

`wai conform <kind> --suite <suite> --impl <command or URL>` (operation
conformance.run) runs a corpus against another implementation through a command-line
or an HTTP adapter: verifiers (claim, jwp, signer), a decoder (score), a packager
(policy) and an origin (http). The result is a signed conform-result/1 record that
`wai verify` checks. Both follow the agent rules: the envelope/1 JSON output, the exit
statuses, --dry-run.

.github/workflows/wai-breaking.yml runs the gate on every pull request that touches
WAI, the tests of both commands, and the corpora's independent Python verifiers and
the reference packager through wai conform.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
tests/cli_conform.rs: the origin picks its own port and says which
Some checks failed
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Has been cancelled
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Has been cancelled
wai-ledger service / service · macos (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI examples / WAI examples · portable · linux (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
63481e6917
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Merge TC-B's wai/breaking-conform (#507) into the catalogue: one agent-rules module
Some checks failed
WAI examples / WAI examples · portable · linux (pull_request) Has been cancelled
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Has been cancelled
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Has been cancelled
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Has been cancelled
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Has been cancelled
wai-key-proxy / proxy · linux (pull_request) Has been cancelled
wai-ledger service / service · linux (pull_request) Has been cancelled
wai-ledger service / service · macos (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
c63427fcf5
The coordinator's direction: the catalogue's agent rules build on #507's
wai_cli/dx/envelope.rs, the one place the exit codes and the JSON envelope live.
agent.rs is folded into it (OpError holds the confirmation proposal and a reported
exit); the envelope is {"wai": "envelope/1", "op", "ok", "data" | "error",
"exit"} for every command, wai breaking and wai conform among them, their bodies now
data; JSON with --json (or a parent's), text otherwise. The exit-code table is the
study's in both; 3 (permission) joins the module's constants. compat.check,
conformance.run and conformance.list join the catalogue and dx::VERBS; every id now
ends in an N3 verb (toolchain.test for wai hello, stage.encode for wai stage refine,
playlist.lock for wai http seal-playlist, ops.show for wai ops show, ...), the command
lines unchanged. conform names its record in a dry run's plan.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`wai mcp` (the feature `mcp`) is a Model Context Protocol server (2025-06-18) on
standard input and output. Its tools, in one table (src/bin/wai_cli/mcp/tools.rs):
inspect an envelope or a package; list and describe registered capabilities; verify a
delivery receipt, a claim with the context the tool takes, a live-room session and a
stream audit bundle, each answering with the verifier's verdict and reason code;
package a media file under `wai wrap`'s rules, inside the project directory only; list
and run a conformance corpus's independent verifier; search the specification; and,
marked development only, drive a development room on loopback (`joule-moq-room dev`):
start it, mint grants for test principals (any service whose address is not a loopback
address is refused before a connection is made), join and publish as them, read the
session, stop it. Each tool carries safety hints; `--read-only` offers only those that
read or run a verifier.

`wai setup-agent` writes AGENTS.md and CLAUDE.md (which imports it) and registers the
server in the project's MCP configuration files by their documented formats. A file
that exists is changed only after its diff is shown and confirmed (asked on a terminal,
or --confirm; otherwise exit 4 with every diff and the confirming command), --dry-run
writes nothing, nothing outside the project directory is written, and its output is
JSON off a terminal.

Both are reached through one table of verbs in wai.rs, so a name is one line. `wrap`
returns its printed lines and its facts, which the packaging tool reads.

tests/cli_mcp.rs drives the binary with an MCP client: every tool, and the verifiers
agreeing vector by vector with jwp-conformance, claim-conformance,
live-conformance/rooms and live-conformance/audit. tests/cli_setup_agent.rs runs the
command in scratch projects, fresh and with files that exist.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`joule-moq-room dev` (src/dev.rs) runs the relay and the room service in one process
on loopback, with keys made at start and kept only in memory, media held to no
receipts and rate limits open, and says on standard error that it is for development
only. It answers JSON control lines: join (a test principal enters with its grant and
a proof, publishes audio and video, and the answer waits for the clock's join and
publishes), leave, session (the room as live-rooms §9 gives it to a verifier) and
stop. Its log goes to standard error. tokio's io-std feature, for its standard input
and output.

openapi.json describes every route of the service in each of its modes: requests,
answers and statuses. tests/openapi_contract.rs holds it to the code: the routes the
routers match are exactly its operations; each status it lists for an operation is one
the operation's handlers return, and each status they return is listed; and the
service, run beside a relay in each mode (a plain room, end-to-end encryption,
admission by age, co-performance, a watch room, a remote desktop room, a conversation,
calls, and without its relay), answers every operation with a status it lists.

tests/mcp_dev_room.rs builds `wai` with the feature `mcp` in a target directory of its
own and drives `wai mcp` with an MCP client: a development room started, two test
principals granted, joined and publishing, the session verified, a changed record
refused, a leave verified, and a grant from a service off the machine refused.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-conformance runs tests/cli_mcp.rs and tests/cli_setup_agent.rs, with the binary's
unit tests, under the feature `mcp` on each leg. The room service's workflow runs every
target, and now says what tests/openapi_contract.rs and tests/mcp_dev_room.rs hold.
wai/README.md says how a project is set up for a coding agent and what `wai mcp`
offers; CHANGELOG records both commands and the API description.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The two verbs join the one table, dx::VERBS, beside hello, create, dev and
verify; wai.rs keeps no second command table. A verb ends either as a check
(0 held, 1 did not, 2 usage) or with an exit status of the toolchain's table,
which setup-agent uses.

wai mcp (agent.mcp): each tool is an operation of the catalogue, named by it
with `_` for the dot, and nothing else names it. The tools come in toolsets,
chosen with --toolset (core when none is named):
- core: envelope_inspect, registry_list, registry_show, receipt_verify,
  package_build, conformance_list, conformance_run, docs_search;
- dev: dev_start, dev_stop, room_grant, room_join, room_leave, room_session,
  on the target local alone (a target named must be it).
receipt_verify takes the four kinds the verify tools took one each (delivery,
claim, room_session, audit_bundle), by `kind` or read from the arguments, and
answers with the kind beside the verifier's verdict. tools/list gives each
tool's operation and toolset in its _meta. The development room's program is
found as wai dev finds it: beside wai, then on PATH. envelope_inspect counts
what this build decodes as wai inspect does, the floor included.

wai setup-agent (agent.setup): AGENTS.md always; a CLAUDE.md only where the
project has one, which gains an import of AGENTS.md. --toolset registers the
server with those toolsets. Off a terminal it answers in the toolchain's JSON
envelope (envelope/1: op, ok, error {code, message, hint, retryable}, result,
and on exit 4 the proposed changes and the confirming command), with the
table's exit statuses: 2 usage, 3 permission, 4 confirmation required, 5 not
found, 7 another I/O error.

wai::ops holds the rule operation names keep: noun.verb, lowercase letters,
the verb from a closed list, and the few names the catalogue gives as they are
(room.session among them). The quickstart's wai holds `mcp`, so the server
setup-agent registers is in the archive's binary.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
openapi.json names its 40 operations as the toolchain's catalogue does,
noun.verb: room.show (GET /room) and room.grant (POST /grant) as the catalogue
gives them, and the rest by its rule (service.show and service.check, the
health; admission.show; mls.tail, mls.import, mls.update; performance.list
and .show, schedule.create, handover.create, window.create, fidelity.create;
time.show, source.fetch, watchchallenge.create, watch.tail, watch.show,
watch.join, watch.update; control.grant, remote.show, remote.verify;
conversation.show, .join, .tail, .import, .update, .leave,
conversationchallenge.create, message.create, acknowledgement.create,
member.delete; callchallenge.create, call.create, call.invite, inbox.show,
answer.create, call.show). The paths stay as the service serves them. The
description lists the service behind wai dev's front (/room-api) as a server.

tests/openapi_contract.rs gives each operation its name beside its handlers and
checks that the description names it so, that each name keeps wai::ops's rule
and names one operation, and that room.show and room.grant are the routes the
catalogue gives them. tests/mcp_dev_room.rs drives `wai mcp --toolset core,dev`
under the new tool names and checks that the tool room_grant and POST /grant
are the one operation room.grant, and that no other tool shares an API
operation's name.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-conformance runs `--lib ops::` beside the mcp and setup-agent tests, and
its comment says what they now hold (the tool list as operations, toolsets,
the dev tools' target, setup-agent's envelope and exit statuses). The room
service's workflow comment says the contract test checks every operationId.
wai/README.md gives the toolsets and their tools, and setup-agent's CLAUDE.md
and --toolset; the room service's README the operationIds; the CHANGELOG
entry is rewritten for the names.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai mcp: the tools table's test module after every item (clippy items_after_test_module)
All checks were successful
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 8m42s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 27s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 38s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m52s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 11m5s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 10m13s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 7s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 23m46s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m55s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 7m0s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m16s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 24s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m35s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m21s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m24s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 6m54s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m41s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 11m37s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 36s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m11s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 9m20s
wai-ledger service / service · macos (pull_request) Successful in 1m28s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 27m49s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h9m8s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 15m28s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 18m18s
wai-pack / wai-pack · macos (pull_request) Successful in 4m44s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 4m52s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 10m38s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 20m17s
bff1736e36
Co-Authored-By: Claude Opus 5.5 <[email protected]>
joule-ui takes in OpenUI Lang 1.0 the way it takes in A2UI: a model writes a
surface as a program, one widget a line, and joule-ui-lang builds a widget tree
against the host's registry as the program streams. After every chunk a snapshot
holds the tree as far as it can be built, each widget checked by joule-ui's own
validate, and every error with its source line and reason code. State, queries,
operators, conditionals, built-in functions and sequences of actions are parsed
and refused not-declarative. A canonical writer turns a tree back into the
language; it parses back to the same tree.

- joule-ui-core: WidgetSchema::positional, the order a positional call passes
  props in (SPEC §3); absent from the wire form when undeclared.
- joule-ui-interaction: begin_interaction and Pending::finish, the lifecycle's
  three phases in two steps for a host whose handler is asynchronous (SPEC §6);
  run_interaction is built on them and seals what it sealed before.
- conformance/lang/v1: L1 statements, L2 ingest, L3 streaming, L4 the canonical
  form, L5 refusals, with an independent Python verifier written from §11.
- docs/create.md: the design of Create.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- a joule-ui registry of WAI widgets: App, Room, WatchTogether, Show, Player, Chat,
  Poll, Participants, Receipts, EnergyMeter, Text; each room kind accepts only the
  widgets its room service keeps (a watch room holds no Chat and no Poll), so a line
  that asks for more is refused disallowed-child at its line;
- WAI's own rules on an app (one room, a poll's options, a show's audience, a watch
  room's source) and the room an app needs;
- the guide a model writes against, made from the registry;
- export: the one writer of a starter project (the program, its tree, the room
  service's configuration, the page, a check that is its build, a development front,
  README, AGENTS.md, the runtime under vendor/; no key);
- the page's WebAssembly surface: the program streamed into snapshots, and every
  action sealed into the page's hash-chained log through joule-ui-interaction;
- wai-ui mcp: an MCP server and a loopback bridge, so a person's own coding agent
  drives Create;
- web/: the streaming renderer (keyed, so a joined room survives the next chunk), the
  components over the room client in a same-origin frame, the Create page with its
  three model sources (the visitor's own model and key, their coding agent, a recorded
  stream), the exported app's page, and the runtime layout;
- e2e/: Create in a browser against a real room service and relay.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- runtime.mjs gives every runtime file a unique served name (wai-ui-<name>,
  wai-ui-room-<name>.js, wai_ui_room_moq, wai_ui_room_live): the WAI site fingerprints
  assets keyed by basename, and an export's vendor/ carries the same layout;
- a room widget takes the room service for its kind (data-service-live, -watch,
  -show) when the page names one;
- WAI's value rules (a poll's options and seconds, a show's audience, a watch room's
  source) wait for a pending statement to complete, as the line language's own errors
  do: a poll's `seconds` reads 2 before 20, and the poll no longer leaves the page for
  that chunk (found by the end-to-end run; a unit test now streams every recording a
  character at a time and requires that no widget, once shown, goes);
- .github/workflows/wai-ui.yml: tests, clippy and the wasm32 surface, the line
  language's verifier and its mutations, the page modules (linux); Create in the
  browser (macos);
- the e2e drives a WAI site build with --site;
- wai-ui cites joule-ui's spec by its file (joule-ui/SPEC.md §N).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai/wai-ui becomes wai/wai-app, the library `wai_app`, with no binary and no `cli`
feature: `wai`, built with its feature `app`, is its command line and its MCP
server. Its served files are named wai-app-* (the WebAssembly package wai_app),
the recordings wai-app-*.json.

- export.rs gives the files of a starter project for a program and the facts its
  project file holds (title, summary, `wai dev`'s mode for the app's room, a watch
  room's file, a show's audience); `wai create --from app.oui` writes them, the
  project file and the licence. The export no longer writes app.json, room.toml,
  relay.toml, package.json, check.mjs or serve.mjs: wai.json names the room, `wai
  dev` runs it and `wai app check` checks the project. Its README and AGENTS.md
  say so, and the README its licence.
- runtime.rs reads a Create runtime by its listing (create/wai-app-runtime.json),
  checking each file's SHA-256.
- bridge.rs keeps the bridge on 127.0.0.1 a coding agent streams a program into
  the page through, with a stream helper; the stdio server, its tools and the
  binary's test go (`wai mcp --toolset app` serves them).
- The page's Export hands over app.oui, the program in its canonical form, and the
  command that makes it a project; the ZIP writer and the page's export in
  WebAssembly go. The page names `wai mcp --toolset app` for the coding agent.
- joule-ui/docs/create.md §4 and §5: the export as `wai create --from app.oui`, and
  the agent's tools app_guide, app_check, app_stream and app_export.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The feature `app` links wai-app (with `mcp`):

- `wai create <dir> --from app.oui [--runtime DIR]` (app.export): the app's files
  from wai_app::export, its runtime copied from a Create runtime (the flag,
  $WAI_APP_RUNTIME, or share/wai/app beside wai) and checked against its listing,
  and its wai.json from project::render, the one writer every project file now
  has (`minimal` is a call of it, and a test holds it to three templates' own
  files byte for byte). The project file names the program (`app`) and the room
  `wai dev` runs (`dev.mode` room, watch or show; `dev.watch`; `dev.audience`).
- Every project `wai create` writes, from a template or an app, carries LICENSE
  (Apache-2.0, wai/LICENSE held in the binary); `--list --json` lists it, and each
  example's README names the licence.
- `wai app guide` and `wai app check [<dir> | <app.oui>] [--json]` (app.guide,
  app.check): the program against the registry, and in a project the room wai.json
  names against the app's own and vendor/ against vendor.json; exit 1 with each
  failure named, the JSON envelope off a terminal.
- `wai mcp --toolset app`: app_guide, app_check, app_stream and app_export, a bridge
  on 127.0.0.1 started when the toolset is served and not read-only;
  setup-agent's --toolset takes app.
- project.rs reads `app` and `dev.audience` (a show's alone, 1 to 255) and the mode
  show. `wai dev --show [--audience N]`: the room's [co] block, and the relay's
  [floor] holding the floor to the room's clock (its key read from the relay
  lines). The front refuses any path segment that starts with a dot, so a
  project's .wai/, where the room's keys are, is never served; .oui is served as
  text.
- tests/cli_app.rs (required-features app); the lock gains wai-app and the
  joule-ui crates it builds on, additions only.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- .github/workflows/wai-ui.yml becomes wai-app.yml: the unit job runs wai-app's
  tests, its clippy (native and wasm32) and the line language's verifier; the e2e
  job runs wai/wai-app/e2e/run.sh, which now also reads wai/quickstart/build-web.sh.
- wai-conformance runs tests/cli_app.rs with the feature `app`, and fires on
  wai/wai-app and the joule-ui crates it builds on.
- The e2e (run.sh builds `wai` with `app` in a target directory of its own, and
  the room client `wai dev` serves): the Create page served by `wai dev --show`; the
  show recording renders as it streams; the host joins, chats and opens the poll;
  the sealed log verifies; Export hands over app.oui and the command; `wai create
  --from app.oui` writes the project; `wai app check` passes on it and refuses it
  with its room not its app's, another audience, no room named, a runtime file
  changed or a refused line; `wai dev` in the project runs its own room, its keys in
  .wai/ that the front never serves, where a host and a viewer answer a poll the
  room's clock signs; the refused lines never render; the visitor's own model gets
  their key alone; `wai mcp --toolset app` streams into the page through its bridge
  and app_export writes the same project.
- CHANGELOG: Create as wai-app, `wai create --from app.oui`, `wai app`, the app
  toolset, LICENSE in every project, `wai dev --show`. wai/README.md: the app
  toolset and Create.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
--toolset takes app, and AGENTS.md mentions the app toolset, only in a build with
the feature `app`: a project set up from a build without it is never pointed at a
toolset its wai cannot serve.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-app e2e: the show's audience is the recording's (1)
All checks were successful
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 5m43s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 32s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 11m34s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 6s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 5m27s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 18m36s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 10m35s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m21s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m26s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 10m14s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m38s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 50s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m45s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m26s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m48s
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Successful in 28m15s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m29s
wai-ledger service / service · macos (pull_request) Successful in 1m13s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 22m51s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 8m50s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 22m55s
wai-pack / wai-pack · macos (pull_request) Successful in 3m15s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 17m38s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 11m40s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 2m55s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 3m10s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 1m59s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m22s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 18m16s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h3m2s
3363058002
Co-Authored-By: Claude Opus 5.5 <[email protected]>
# Conflicts:
#	joule-code/joule-code-rs/crates/joule-moq-room/README.md
#	joule-code/joule-code-rs/crates/joule-moq-room/src/main.rs
#	wai/CHANGELOG.md
#	wai/examples/android-app/README.md
#	wai/examples/apple-app/README.md
#	wai/examples/encoder-ingest/README.md
#	wai/examples/messaging/README.md
#	wai/examples/package-and-deliver/README.md
#	wai/examples/remote-desktop/README.md
#	wai/examples/verify-receipts/README.md
#	wai/examples/video-room/README.md
#	wai/examples/watch-together/README.md
#	wai/wai-rs/src/bin/wai.rs
#	wai/wai-rs/src/bin/wai_cli/dx/create.rs
#	wai/wai-rs/src/bin/wai_cli/dx/dev.rs
#	wai/wai-rs/src/bin/wai_cli/dx/mod.rs
Bring wai mcp, wai setup-agent, Create and the room service's API into the catalogue, renamed to N3
Some checks failed
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-quantum studio and desktop / does this change touch it (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-quantum WebGPU member / does this change touch it (pull_request) Has been cancelled
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been cancelled
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been cancelled
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been cancelled
wai-sink-android native sink library / does this change touch it (pull_request) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Has been cancelled
wai-sink-swift native sink package / does this change touch it (pull_request) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Has been cancelled
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been cancelled
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-quantum WebGPU member / member · DX12 and Vulkan (cbio-windows) (pull_request) Has been cancelled
fcf8518e23
Merged #508 (wai/create-2, stacked on #505) before they reach main, as the coordinator
directs: they merge before this branch, which builds the catalogue over them.

- The catalogue holds every operation they add: mcp.start (wai mcp; it was agent.mcp),
  agent.setup, app.guide, app.check, app.export (wai app export, also wai create --from),
  app.stream, registry.show, docs.search, dev.stop, room.join, room.leave, session.show
  (it was room.session), and the room service's 40 operations at their routes.
- Renamed to the verb rule: the MCP tool package_build is envelope_wrap (it does what wai
  wrap does; package.build stays for real packaging); the room service's challenges are
  watch.setup, conversation.setup and call.setup (no compound nouns); in the OpenAPI
  document, its contract test, the MCP table and tests, the docs.
- wai::ops is folded into wai::catalogue: the tool table's tests hold it to the catalogue
  both ways (every tool an operation the catalogue says wai mcp serves, in its toolset,
  and every such operation a tool; a tool of MCP alone takes the catalogue's input), and
  the room service's contract test holds its OpenAPI the same way.
- wai setup-agent and wai app check answer in the one envelope (wai: envelope/1, data),
  JSON with --json; wai mcp and setup-agent take --dry-run through the door; the binaries
  wai-relay and wai-room in the MCP dev room and Create's end-to-end script.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
extensions/conformance-results.md specifies the record a conformance run signs: its
members (§2) and corpus digest (§2.1), its signing input (the domain
`wai:conform-result` and 0x01, then the record without `sig` in RFC 8785 form) and
Ed25519 signature under SPEC §7's strict rule (§3), what a verifier checks and in what
order (§4: it reads, its version, its members, its signature, its summary, its verdict)
and the codes of each refusal (§5). conform-result/1 is registered as a document kind
(registry export and REGISTRY.md regenerated); SPEC §7 points to it.

wai-rs gains the module conform_result (feature conform_result, in quickstart): sign,
check and verdict, the corpus digest, and the corpus of §7, whose outcomes are stated
from the text and asserted before anything is written. `wai conform` signs with it and
`wai verify` checks with it. conform-result-conformance/ holds accepted records and
refused ones (a case flipped, the corpus digest changed, the summary alone changed, a
bad signature, S past L, a small-order key, a summary or verdict that disagrees though
signed, an unknown version, members missing, added or named twice, a fractional count,
a digest out of form, bytes that are not JSON); wai_conform_result_vectors generates
and verifies it, and conform_result_verify.py, written from the text and sharing no code
with wai-rs, reaches every outcome and fails the corpus with each check of §4 left out.
`wai conform` gains the verifier suite conform-result.

`wai breaking` leaves out an explicit list of corpus files that record a measured run
(the format probes' external decodes, the relay's recorded metering run), each with
its reason, and says so in a note; the vectors built from them stay compared.

A command `wai conform` runs is put in a process group of its own, so a timed-out
command's children are stopped too.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
conform-result-conformance: each summary count wrong alone, its other counts right
Some checks failed
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 21s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 3m41s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Failing after 4m59s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 19s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 35s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 3m19s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 6m37s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 2m25s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 1m47s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 15m15s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 1m0s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 12m5s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m41s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 3m22s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 9m0s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 17m37s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m34s
WAI conformance / cargo-class corpora · macos (pull_request) Failing after 2m20s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 29s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m23s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 11m57s
wai-ledger service / service · macos (pull_request) Successful in 1m58s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m44s
wai-pack / wai-pack · macos (pull_request) Successful in 3m56s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m18s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 12m55s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 16m43s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m28s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h8m37s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 19m4s
20e94861ee
The falsification of the reference found that leaving out the check of summary.cases
alone left the corpus passing: every summary vector had passed and failed wrong too.
Three vectors now carry each count wrong alone.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
# Conflicts:
#	wai/wai-rs/Cargo.toml
cli_breaking: the measurement test reads the envelope's data
Some checks failed
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m42s
WAI conformance / cargo-class corpora · macos (pull_request) Failing after 2m10s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 27s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 10m2s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m22s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 35m20s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 34m51s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 6m22s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 7s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 34m48s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m23s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m29s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m42s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 6m21s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 26s
wai-ledger service / service · macos (pull_request) Successful in 56s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 7m3s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m30s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m32s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m50s
wai-pack / wai-pack · macos (pull_request) Successful in 3m10s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m27s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 2m54s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h3m30s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 15m39s
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Successful in 3m1s
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Successful in 2m4s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 11m6s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 8m4s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 18m1s
270be911a8
wai breaking's report is the data of the agent rules' envelope; the test added with the
measurement list read its findings and notes at the top level.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Main's final #507 replaces the copy this branch carried: wai breaking's base holds every
standard its crate reaches by path (rust_api.rs), and the conform adapter is main's. The
agent rules stay in one module, dx/envelope.rs, as this branch extended it; the command line
stays the catalogue's (door.rs, dx::VERBS by operation id). wai verify reads fleet bundles as
main has it, its errors the envelope's. The quickstart build carries fleet; cli_ops and
cli_fleet are both test targets; lib.rs gates strict_json on fleet too. The changelog keeps
this branch's entry above #507's and the fleet's. The fleet's command module is declared and
is routed through the catalogue in the next commit.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
CHANGELOG: the breaks this branch makes on purpose, each by the id wai breaking gives it
Some checks failed
wai-fleet service / service · macos (pull_request) Successful in 43s
wai-ledger service / service · macos (pull_request) Successful in 52s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 3m21s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m40s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m45s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 33m25s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 6s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 19m3s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 14m4s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m14s
wai-pack / wai-pack · macos (pull_request) Successful in 2m47s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 32m20s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m25s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 10m1s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 32m31s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 18s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m41s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m8s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m32s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m19s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m34s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h0m5s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m14s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m10s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 17m15s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 1m22s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 4m19s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 59s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Failing after 8m0s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 15m39s
040a3b1053
wai::ops gives way to wai::catalogue, and the room service's three challenges take the
operationIds the naming rule gives them; wai breaking --against main names these eight and
nothing else.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
# Conflicts:
#	wai/CHANGELOG.md
#	wai/wai-rs/src/bin/wai_cli/dx/dev.rs
WAI Studio reads the catalogue; dev.start declares --show, --audience and Studio's route
Some checks failed
joule-code conformance gate / joule-moq-relay, its own energy on a counter (macos) (pull_request) Successful in 39s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 56s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m14s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m23s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m32s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 31m45s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 24s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m18s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 31m16s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 31m25s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m16s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 6m32s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 8m42s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 14m40s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m22s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Failing after 6m51s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 27s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 57m7s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Successful in 1m8s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 7m22s
wai-fleet service / service · macos (pull_request) Successful in 42s
wai-ledger service / service · macos (pull_request) Successful in 48s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 20m3s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 9m41s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 11m56s
wai-pack / wai-pack · macos (pull_request) Successful in 2m41s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m20s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 6m30s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 8m57s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 14m53s
baf37c0313
With the catalogue on this branch, Studio's pending copy of it goes:
wai/wai-studio/ops.pending.json is removed, and src/actions.generated.js is
generated from wai/catalogue/ops.json (96 operations). The fleet's four
operations, placed on the client, are bound as run from the command line,
as the drift check requires. dev.start's usage, help and inputs now name
--show and --audience, which `wai dev` already took, and say that Studio is
served at /_wai/ when its files are found.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-app e2e: read wai app check's envelope as envelope/1 lays it out
All checks were successful
wai-ledger service / service · macos (pull_request) Successful in 58s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 9m51s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 18m30s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 13m52s
wai-pack / wai-pack · macos (pull_request) Successful in 2m49s
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Successful in 10m16s
WAI HTTP delivery / HTTP corpus · falsify patches 0/3 (pull_request) Successful in 6m24s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 4m9s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Successful in 7m39s
WAI HTTP delivery / HTTP corpus · falsify mutations 0/3 (pull_request) Successful in 33m27s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 55s
WAI HTTP delivery / HTTP corpus · falsify patches 1/3 (pull_request) Successful in 6m39s
WAI HTTP delivery / HTTP corpus · every patch and mutation in exactly one shard (pull_request) Successful in 5s
WAI HTTP delivery / HTTP corpus · falsify mutations 1/3 (pull_request) Successful in 32m48s
WAI HTTP delivery / cache rules · controls and labelled caches (pull_request) Successful in 1m50s
WAI HTTP delivery / HTTP corpus · falsify mutations 2/3 (pull_request) Successful in 32m47s
WAI HTTP delivery / HTTP corpus · verified both ways, and the differential (pull_request) Successful in 2m20s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 21s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 9m33s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 2m2s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 1m39s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 1m32s
WAI HTTP delivery / HTTP corpus · falsify patches 2/3 (pull_request) Successful in 6m58s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 3m4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 59m15s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Successful in 16m40s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 7m34s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 4m6s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Successful in 7m30s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 15m49s
c3d41827c9
The catalogue's agent rules carry an operation's answer under `data`
(envelope/1); the Create e2e still read the older `result`, so each refusal
case found no failures and failed. The passing case only read `ok`.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!506
No description provided.