Some checks failed
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Successful in 45s
wai-audit collector and player integration / does this change touch it (push) Successful in 1m1s
joule-moq-room room service / joule-moq-room · does this change touch it (push) Successful in 1m34s
wai-ledger service / does this change touch it (push) Successful in 1m31s
wai-fleet service / does this change touch it (push) Successful in 1m33s
WAI operation catalogue / does this change touch it (push) Successful in 1m33s
wai-app and Create / wai-app · does this change touch it (push) Successful in 1m40s
joule-moq-web browser client / joule-moq-web · does this change touch it (push) Successful in 1m48s
wai-quantum for JavaScript / does this change touch it (push) Successful in 1m8s
wai-quantum studio and desktop / does this change touch it (push) Successful in 35s
wai-sink-android native sink library / does this change touch it (push) Successful in 38s
WAI Studio / does this change touch it (push) Successful in 33s
wai-sink-swift native sink package / does this change touch it (push) Successful in 35s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (push) Has been cancelled
joule-moq-remote host agent / joule-moq-remote, every target (macos) (push) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (push) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Has been cancelled
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has been cancelled
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (push) Has been cancelled
wai-app and Create / wai-app · Create, browser end-to-end (macos) (push) Has been cancelled
wai-audit collector and player integration / collector · linux (push) Has been cancelled
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (push) Has been cancelled
WAI operation catalogue / the catalogue and every door · linux (push) Has been cancelled
wai-fleet service / service · linux (push) Has been cancelled
wai-fleet service / service · macos (push) Has been cancelled
wai-ledger service / service · linux (push) Has been cancelled
wai-ledger service / service · macos (push) Has been cancelled
wai-quantum for JavaScript / javascript · linux (push) Has been cancelled
wai-quantum studio and desktop / studio · browser (push) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (push) Has been cancelled
wai-quantum studio and desktop / desktop app · linux (push) Has been cancelled
wai-quantum studio and desktop / desktop app · windows (push) Has been cancelled
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (push) Has been cancelled
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (push) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Has been cancelled
WAI Studio / the catalogue's actions, the unit tests and the core · linux (push) Has been cancelled
WAI Studio / Studio in Chromium and Firefox · macos (push) Has been cancelled
WAI Studio / Studio in WebKit · linux (push) Has been cancelled
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 10s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Successful in 2m6s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Successful in 7m46s
The catalogue (wai/catalogue/ops.json) and the MCP door's tools (wai/catalogue/mcp.json, new, held to the tools' table by a test of the binary) are a surface of category api: each operation's id, command line, doors, effect, confirmation and stability; its flags and arguments; the schema of its --json data and streamed lines, read as a reader reads them; the envelope, the exit codes and the agent flags; each tool's name and input schema. A stable operation's change is a break. A preview operation's change is no break and is owed a changelog line that names it. An id, a flag or an agent flag renamed with the old name kept, deprecated, is no break; removing the old name is acknowledged only once its window (two minor releases and six months, from the export's version and the release tag's date) has closed, and a stable name removed without that is a break no line acknowledges. The JavaScript surface is the browser packages' #[wasm_bindgen] items by their JavaScript names (and any committed .d.ts); Swift and Kotlin are the native sinks' public declarations, each with its parameters, labels, defaults and result. In a project (a directory with wai.json, or --project), wai breaking compares the project with itself at a git ref or as published (--baseline: the project, or its package alone): the package wai build wrote, class by class as sinks are configured for it (the sink-class check), and the API named under breaking.api. With wai 0.5.0 released, wai.json's version 1 is published, so breaking (api, and allow: each accepted break with its reason) is version 2's (wai/schema/wai-json-2.schema.json): a file that names it says "wai": 2, a reader of version 1 alone refuses it as a later version, and wai create still writes version 1. An accepted break with no reason is refused with the file. A run with no package to compare with stops with exit 5. Planted faults, each caught: a stable operation renamed; a preview change unsaid; an accepted break with no reason; a version-1 file naming breaking; a sink class gone; a Swift label and a Kotlin required parameter; an MCP tool's required argument; a confirmation compared on a door that is new. Co-Authored-By: Claude Opus 5.5 <[email protected]>
125 lines
9 KiB
Markdown
125 lines
9 KiB
Markdown
# The WAI toolchain: versions, stability and deprecations
|
|
|
|
This page says what anyone building on the `wai` command line can rely on: which parts are public,
|
|
what a version number promises about each, and how a change is announced before it happens. It
|
|
covers the `wai` binary, the operation catalogue and the doors the catalogue names. WAI Quantum's
|
|
packages have their own page, [wai-quantum/VERSIONING.md](wai-quantum/VERSIONING.md).
|
|
|
|
The deprecated items, each with the version that deprecated it and its replacement, are listed in
|
|
[DEPRECATIONS.md](DEPRECATIONS.md).
|
|
|
|
## One version
|
|
|
|
`wai`, the standard's text and the reference implementation are released together, under one
|
|
version: the `wai` crate's (`wai-rs/Cargo.toml`). The newest release heading of
|
|
[CHANGELOG.md](CHANGELOG.md) names it, the catalogue's export carries it, and a test holds the three
|
|
equal, so a version can be read from the binary and never has to be read from a page:
|
|
|
|
```text
|
|
wai --version --json
|
|
```
|
|
|
|
| Member | What it says |
|
|
|---|---|
|
|
| `toolchain` | This binary's version |
|
|
| `catalogue` | The export's format, its operations, and the SHA-256 of `wai ops export`, which is [catalogue/ops.json](catalogue/ops.json) byte for byte |
|
|
| `envelope` | The version of the JSON envelope `--json` prints |
|
|
| `registry` | The registered capabilities, and the SHA-256 of [registry/capabilities.json](registry/capabilities.json) |
|
|
| `specification` | The release of the standard this binary implements, and the envelope formats it reads |
|
|
| `features` | The build features the catalogue names that this binary was built with, which decide the operations it holds |
|
|
|
|
## What is public
|
|
|
|
| Surface | What is public | What holds it in CI |
|
|
|---|---|---|
|
|
| The operation catalogue | Each operation's id, its command line and declared aliases, its flags and arguments, its effect, when it waits for confirmation, its stability and the schema of its `--json` `data`: [catalogue/ops.json](catalogue/ops.json), which `wai ops schema <id>` prints one entry of | `wai ops export --check`, and the catalogue's rules (`wai-catalogue.yml`); `wai breaking`, category `api` (surface `catalogue`, `wai-breaking.yml`) |
|
|
| The agent rules | The exit codes, the envelope `envelope/1`, its `error.code` strings, `--json`, `--dry-run`, `--yes` and `--no-input` | `wai-rs/tests/cli_ops.rs` |
|
|
| The MCP door | Each tool's name, the operation of the catalogue it is, and its input schema: [catalogue/mcp.json](catalogue/mcp.json), which the binary's tests hold to the tools `wai mcp` serves | `wai-rs/tests/cli_mcp.rs` and the binary's tests, in `wai-conformance.yml`; `scripts/check-wai-ops-doors.py`; `wai breaking`, category `api` (surface `catalogue`) |
|
|
| The project file | `wai.json`, as [schema/wai-json-1.schema.json](schema/wai-json-1.schema.json) and, for version 2 (version 1 and `breaking`), [schema/wai-json-2.schema.json](schema/wai-json-2.schema.json) state it | The reader's tests, which hold the reader to both |
|
|
| The lock and the build record | `wai.lock` and `wai-build.json`, as [schema/wai-lock-1.schema.json](schema/wai-lock-1.schema.json) and [schema/wai-build-1.schema.json](schema/wai-build-1.schema.json) state them, and the lock's bytes in [project-conformance/](project-conformance/README.md) | `wai-rs/tests/cli_project.rs` and the second reader, `project_verify.py`, in `wai-conformance.yml` |
|
|
| The C ABI, the Rust API of the library crates, the JavaScript, Swift and Kotlin APIs and the HTTP services' OpenAPI documents | `wai.h`, what the crates document, the browser packages' bindings (`wai-web`, `wai-live-web`), the native sinks' public declarations (`wai-sink-swift`, `wai-sink-android`), and each document's operations | `wai breaking`, category `api` (`wai-breaking.yml`) |
|
|
| The wire and the signed records | The registry's capabilities and wire identifiers, the conformance corpora, the signing domains and the published JSON Schemas | `wai breaking`, categories `wire` and `record`, and the corpora's generators and verifiers |
|
|
|
|
What is not public: the text a command prints without `--json`, which is for people and may change
|
|
in any release; an operation marked `internal`, which is never published; and the keystore's own
|
|
files (`wai.key/1`), which only `wai key` reads and writes.
|
|
|
|
An operation's `stability` says how far its entry is promised. A `stable` operation changes only
|
|
with a deprecation window. A `preview` operation is published and works, and its shape may still
|
|
change: a change to one is in the changelog, and the window below is not owed.
|
|
|
|
## What a version number promises
|
|
|
|
The toolchain follows [Semantic Versioning 2.0](https://semver.org). Every release so far is 0.y.z,
|
|
for which that promises nothing, so this page does: the first non-zero component is the major.
|
|
|
|
- **A change of y** (0.4.0 to 0.5.0) may break a public surface. Every break is in the changelog
|
|
with what to do instead, and the deprecation rule below holds for a stable operation.
|
|
- **A change of z** adds or fixes, and breaks nothing a public surface promised.
|
|
|
|
The wire format is the exception the standard states: until v1.0 freezes, it may change, and such a
|
|
change is recorded in the changelog.
|
|
|
|
## Deprecation
|
|
|
|
A renamed command, flag, route or tool stays as an alias for **at least two minor releases and six
|
|
months**, and says it is deprecated when used. Removing it after that is a break, in the changelog
|
|
with what to do instead.
|
|
|
|
| Where it is used | How a deprecated item says so |
|
|
|---|---|
|
|
| A flag on the command line | It still works, and prints one line on standard error: `wai: deprecated: --confirm, use --yes instead` |
|
|
| An operation's id or spelling | Its catalogue entry's `deprecated` member (`since`, `use_instead`) |
|
|
| Help and the catalogue's export | `wai --help` and each operation's help name it, and `agent_flags` lists it with `deprecated` |
|
|
| The list | [DEPRECATIONS.md](DEPRECATIONS.md), from the release that deprecates it |
|
|
|
|
A test holds [DEPRECATIONS.md](DEPRECATIONS.md) to the catalogue: every flag and operation the
|
|
catalogue marks deprecated is listed there, and every item listed there is marked in the catalogue
|
|
or has its removal named.
|
|
|
|
## How a break is acknowledged
|
|
|
|
`wai breaking --against <git-ref>` reports what the working tree breaks, by category, and exits 1 on
|
|
a break the changelog does not acknowledge. A change acknowledges one with a `**Breaking:**` line
|
|
naming the finding's id in backticks, in its entry under [changes/](changes/README.md). CI runs it on
|
|
every pull request that touches WAI, and on every push to main that does.
|
|
|
|
The catalogue is read as this page promises it:
|
|
|
|
- A change to a **stable** operation, its flags, its `--json` output or its MCP tool is a break.
|
|
- A change to a **preview** operation is no break, and is owed a line: the change's entry names the
|
|
finding's id in backticks, with or without the word "breaking". Without one the run fails.
|
|
- A stable name the catalogue can keep under its old spelling (an operation's id, kept as a
|
|
deprecated operation; a flag, kept as a deprecated alias; `--confirm`) renamed with the old one
|
|
kept, deprecated, is no break. Removing the old one is a break a line acknowledges only once its
|
|
window has closed: two minor releases after the release that deprecated it, read from the
|
|
export's version, and six months after that release's tag (`wai-v<version>`). Removing it
|
|
before then, or removing a stable name that was never deprecated, is a break no line
|
|
acknowledges, and the run says so: keep the old name, deprecated, until its window closes.
|
|
|
|
## A project's breaking changes
|
|
|
|
`wai breaking` runs on any project, in its directory (one with `wai.json`) or with
|
|
`--project <dir>`, against the project at a git ref (`--against <ref>`) or as it was published
|
|
(`--baseline <dir>`: the project's directory, or its package alone, as served). It compares:
|
|
|
|
- **The package** `wai build` wrote under `dist/`, as the sinks that play it are configured for it
|
|
(category `wire`): a class of the packaging policy that is gone, or whose playlists or stage view
|
|
are gone, or whose objects need a capability they did not, is a break for the sinks set up with
|
|
that class; so is a floor codec the classical presentation no longer offers, and a MoQ track a
|
|
subscriber named that is gone or changed. A class that now takes the floor alone is no break:
|
|
its sinks still play. A run with no package to compare with on either side stops (exit 5); it
|
|
does not pass what it did not compare.
|
|
- **The API** the project names under `breaking.api` in `wai.json`: JavaScript and TypeScript
|
|
modules, Swift and Kotlin sources, OpenAPI documents and JSON Schemas, each read by its kind.
|
|
|
|
A project accepts a break in `wai.json`, with the reason it is accepted, which the report gives
|
|
beside the finding; an entry with no reason is refused with the file. `breaking` is a member of the
|
|
project file's version 2, which says so, so that a `wai` that reads version 1 alone refuses the file
|
|
as a later version:
|
|
|
|
```json
|
|
{ "$schema": "https://wai.transaction.science/schema/wai.json/2", "wai": 2,
|
|
"breaking": { "api": ["sdk/index.d.ts"],
|
|
"allow": [{ "id": "api:js:sdk/index.d.ts:play", "reason": "renamed start in 2.0; call start" }] } }
|
|
```
|