open-standards/wai/extensions/capability-constraints.md
Transaction Science fb103ac5ae wai: one registry table, candidate capabilities, public-text checks
Every registered string now lives in one table (codecs/registry.rs) with
its kind, status, media class, registering SPEC section, edition and
registration date. `wai registry export` writes registry/capabilities.json,
its JSON Schema, the generated table in REGISTRY.md and vocab v2; --check
fails on drift. vocab v1 stays stable.

A candidate capability (a registered string whose payload format no
revision has pinned) must not be emitted. The C packers, the browser
writers and `wai wrap` refuse one, and `codecs::is_dispatchable` is the
single dispatch and selection predicate (SPEC §4): candidates,
companion-only capabilities, records and derivations are not
dispatchable, and an unregistered string is decoded only where the sink
advertises it.

The codec glossary is linked to the registry through a reviewed table and
held to its schema by a library test; `org` becomes `body`, from a closed
allowlist. The SPEC gains §5 sections on kinds and candidates, a §8
edition rule, corrected citations and rewritten appendices. The
quantum-ops vectors are regenerated with neutral device ids.

CI declares the feature-gated test targets with required-features, checks
the registry export, builds wai-web for wasm32, and runs two public-text
checks (comparative prose, and private name patterns) with a self-test.
The specification, extensions, research notes, READMEs, glossary and
source comments are rewritten to name no company or product and to make
no comparisons.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-30 22:38:09 -04:00

4.3 KiB

WAI Extension: Capability Constraints

Status: Draft. Makes capability dispatch (WAI SPEC.md §4) a precondition check rather than a binary claim, by ingesting the constraint-set grammar and register pattern the broadcast-IP world already ratified. No transport, no registry service, no negotiation protocol — it evaluates values WAI already carries. Keywords MUST, MUST NOT, SHOULD, MAY are RFC 2119/8174.

1. The problem: support is not binary

WAI dispatch treats a capability as present or absent: a sink either claims cap or does not. Real sinks are not like that. A decoder supports a codec to a level — up to a resolution, a frame rate, a bit depth, a profile. "This capability, but only to 4K60 10-bit, this profile" is the normal case and is currently unexpressible.

The consequence is that partial support fails at decode time rather than at selection time. A sink advertises the capability, receives an object it cannot actually handle, and fails after committing to the bytes. Worse, WAI's rendition selection has nothing to evaluate, so it defers to a deployer policy the specification never states.

2. Constraint sets

A constraint set is an ORed set of constraints over named parameters, each constraint being an enumeration, a minimum, a maximum, or a combination. A sink satisfies a capability when it advertises cap and the object's declared parameters satisfy at least one of the registered constraint sets for cap.

This grammar is deliberately not invented here. It is the shape AMWA's Receiver and Sender Capabilities specifications (BCP-004-01 and BCP-004-02, both v1.0.0) use, with parameters drawn from a public register rather than a bespoke schema per implementation. WAI ingests the grammar and the register pattern, not the transport or the discovery model those specifications sit in.

  • A capability registration MAY publish one or more constraint sets. A capability with none is unconstrained, which is the current behaviour and remains valid.
  • A sink MUST evaluate constraint sets before dispatch, not during it. The point is to move the failure earlier; a check performed at decode has bought nothing.
  • A sink MUST NOT advertise a capability whose constraint sets it cannot evaluate. Advertising a capability while ignoring its constraints is the binary behaviour this extension exists to replace.
  • Where an object's declared parameters satisfy no set, the sink MUST treat the capability as unsupported for that object — not as a decode error, and not as a reason to attempt it anyway.

3. Parameters and the register

Parameters are named in a register, so two implementations constrain the same property under the same name. WAI adopts the pattern; it does not adopt the existing register wholesale, for a reason worth stating plainly:

The ratified registers are broadcast-essence-shaped. They cover media type, frame rate, colour sampling, bit depth, codec profile — which serves WAI's conventional media capabilities and nothing else. There are no entries for the neural, quantum, world or haptic families. Those register entries WAI must author itself, and until it does, those capabilities remain unconstrained under §2, which is the honest state rather than a pretended one.

  • A parameter name MUST resolve in a register. An implementation-local name is not a constraint anyone else can evaluate.
  • WAI-authored parameters MUST be namespaced so they cannot collide with entries authored elsewhere.

4. What this is not

  • It is not a negotiation protocol. There is no pre-flight exchange, no controller, and no registry service. Capability-plus-budget binding before execution is already owned by JCP, and duplicating it here would put two mechanisms in the tree for one job.
  • It is not a transport concern. Constraint evaluation reads values the object already declares.
  • It is not an energy mechanism. A constraint says what a sink can decode, never what it should spend.

5. Framing

The grammar is thin — close to a JSON-Schema subset — and that is fine. The value is not expressiveness; it is that a ratified, register-backed way of saying "supported, to here" already exists, and WAI's dispatch, which has only "supported", gains a range by adopting it.