open-standards/wai/CONTRIBUTING.md
Transaction Science 3fac029a71 wai: every corpus states the provenance of its content
Each *-conformance/README.md now has a line that begins **Provenance.**:
the generator that writes the corpus and its input, and for an input not
generated here its source and licence. OER/2's corpus is settled and left
as it is. byte-exact-conformance and quantum-ops-conformance get a README.
wai-rs/tests/vectors/README.md gives a row per vector directory. Where the
staged-delivery, staged-measurement and telemetry READMEs called their
content "synthetic", that sentence is now their provenance line.

Two vectors are recorded as not generated, from the provenance audit:
int_video's video_real (a pan over a third-party picture) and
neural-conformance's photo (a third-party picture, with a decoder trained on
unrecorded images). Their lines say so and that they are to be replaced;
the photo bullet no longer names the picture's source product.

tests/corpus_provenance.rs requires the line in every corpus and a row for
every vector directory; CI runs it with the carriage tests. CONTRIBUTING
states the rule: corpus content is generated here, or recorded with a
licence that permits redistribution, and a word like "synthetic" is not a
provenance line.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 10:09:21 -04:00

133 lines
6.5 KiB
Markdown

# Contributing to WAI
WAI is a specification ([`SPEC.md`](SPEC.md) and its [`extensions/`](extensions/))
with a reference implementation in Rust ([`wai-rs/`](wai-rs/), with
[`wai-quantum/`](wai-quantum/) and the browser crate [`wai-web/`](wai-web/)). Both
are pre-1.0 drafts: substantive changes are welcome.
The canonical repository is the forge at
`https://git.transaction.science/Transaction-Science/open-standards`. Send changes
there; mirrors of it are read-only.
## To the specification
A change is in scope if it:
- names a real ambiguity in the text (point at the section and the case that
breaks);
- adds a missing structural requirement (byte layout, conformance rule, dispatch
behaviour) needed to make another implementation falsifiable;
- registers a capability with a byte-precise payload format and conformance
vectors, not a placeholder (see *Registering a capability*, below).
A change is out of scope if it adds optional fields with no testable conformance
effect. §8 says what a revision may change: a registered capability's payload
format and role are fixed once registered, and a later edition of a standard that
changes its bitstream takes a new capability string.
## Registering a capability
[`REGISTRY.md`](REGISTRY.md) states the procedure: add the string to the registry
table in `wai-rs/src/codecs/`, register it in SPEC §5 under the same heading, run
`wai registry export`, and link it from the codec glossary or list it there as
having no entry. The tests hold SPEC, the registry and the exported files to the
same set of strings.
## To the reference implementation
### Building
The default `codecs` feature links system codec libraries (libjxl, libavif,
libopus, libdav1d, liblzma, libflac); without them the build stops in a codec
crate's build script. Everything else builds without them, and CI builds that way:
```bash
cd wai-rs
cargo test --lib --no-default-features --features world,audio_scene,haptic,splat4d,score,provenance,neural_int,film
cargo run --no-default-features --bin wai -- capabilities
```
Name the features a change touches explicitly; `cargo test` with the defaults is
not what CI runs.
### Tests that CI must see
- A test file gated on a feature (`#![cfg(feature = "...")]`) compiles to an empty
binary, which reports success, in any build without that feature. Declare it in
`wai-rs/Cargo.toml` with a `[[test]]` stanza and `required-features`, and add
`--test <name>` with the right `--features` to a step in
`.github/workflows/`. A test no workflow names runs nowhere.
- A test that reads inputs from outside the tree skips without them. CI sets
`WAI_REQUIRE_SOTA_VECTORS=1` where it provides them, and a missing input then
fails.
- Falsify every new test once: change the code it guards, show it fails, restore
the code through git, and show it passes again.
### Vectors
Committed conformance vectors and pinned hashes change only through their
generator (the `wai_*_vectors gen` binaries and the export tools in
[`tools/`](tools/)), never by hand. A test whose comment says its hex must never
be edited to make it pass means exactly that.
### Corpus content: where it comes from
Corpus content is generated in this repository, by a generator from a seed or a
formula, or it is an input whose source and licence are recorded and whose licence
permits redistribution. An image, a recording or footage that was not made here and
has no such licence is not committed, as content or as training data.
Every corpus states its provenance: each `*-conformance/README.md` in a line that
begins `**Provenance.**`, and `wai-rs/tests/vectors/README.md` in a row for each
vector directory. The line names the generator and its input, and for an input not
generated here, its source and licence. A word such as "synthetic" is not a
provenance line. `wai-rs/tests/corpus_provenance.rs` requires the line in every
corpus, and `tools/wai_audio_provenance_check.py`, which CI runs, fails when a
committed audio vector correlates with a reference recording the host has.
### Independent implementations
Conformance is defined by the committed corpora (`*-conformance/`) and the
criteria of SPEC §7, not by agreement with this implementation's own tests. A
second implementation in another language is validated against the same corpora;
the OER receipt kernel in C (`oer-conformance/settle/`) is one.
## Public text
The specification, the extensions, READMEs, research notes, code comments and
the CHANGELOG state what WAI does, plainly:
- name no company, vendor, customer or commercial product. Standards, standards
bodies, protocols, papers and open-source projects may be named, factually;
- make no comparisons with other products or approaches;
- give no counts that drift (crate counts, test counts, line counts).
Three checks enforce this. `scripts/check-no-vanity-metrics.sh` (opt-out marker
`allow-vanity: <reason>`) and `scripts/check-comparative-prose.sh` (opt-out
`allow-phrase: <reason>`, for an identifier or a quotation) run on every change.
`scripts/check-public-names.sh` reads its patterns from a private list (the
`WAI_NAME_DENYLIST` secret in CI, given only to the run on a push to main, so a
pull request is checked when it lands); a functional identifier — a capability string,
a model-hub id a tool defaults to, a repository URL, an OS API name, a security
advisory id — is kept and its line marked `allow-name: <reason>`. Put the marker
in a comment of the file's own syntax (`<!-- ... -->`, `// ...`, `# ...`); the
reason must contain a letter or a digit. JSON has no comments, so a JSON file
carries no such identifier: the codec glossary titles a format by its own name,
FourCC, file extension or designation, and never by a company, a product or a
person ([`glossary/SCHEMA.md`](glossary/SCHEMA.md)). The checks fail closed: a
pattern that does not compile, or any grep error, fails them, and
`scripts/test-public-text-checks.sh` proves that on every run.
Dated research records are not rewritten: a correction is a dated annotation
after the original text, and a name is redacted in place with a dated marker.
## Licence
The specification and the reference implementation are Apache-2.0. By
contributing, you agree your contribution is licensed under the same terms. Each
payload and companion capability carries a licence class (royalty-free,
patent-pool, proprietary, non-commercial) for implementing it, recorded in the
registry; derivations carry the class `codecs::derivation` gives them; records
carry none. Companion implementations outside this tree keep their own licences.
No CLA. The licence is the agreement.