open-standards/wai/extensions/state-feeds.md
Transaction Science 5df961d526
Some checks failed
wai-quantum energy-landscape jobs / does this change touch it (push) Successful in 15s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (push) Successful in 24s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (push) Failing after 48s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (push) Failing after 2m9s
wai-quantum energy-landscape jobs / the module under wasm32-wasip2 (wasmtime) (push) Successful in 3m5s
wai-quantum energy-landscape jobs / the same bits · macos (push) Successful in 4m6s
wai-quantum energy-landscape jobs / native against WebAssembly, over many seeds (push) Successful in 5m9s
wai-quantum energy-landscape jobs / reader, kernels, answers and the stated result · linux, release (push) Successful in 7m44s
wai-audit collector and player integration / does this change touch it (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
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (push) Has been cancelled
WAI operation catalogue / does this change touch it (push) Has been cancelled
WAI operation catalogue / the catalogue and every door · linux (push) Has been cancelled
wai-quantum for JavaScript / does this change touch it (push) Has been cancelled
wai-quantum for JavaScript / javascript · linux (push) Has been cancelled
wai-quantum energy-landscape jobs / the same bits · linux-arm64 (push) Has been cancelled
wai-quantum studio and desktop / does this change touch it (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 / does this change touch it (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 / does this change touch it (push) Has been cancelled
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (push) Has been cancelled
WAI Studio / does this change touch it (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
joule-moq-remote host agent / joule-moq-remote · does this change touch it (push) Has been cancelled
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 · does this change touch it (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 · does this change touch it (push) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (push) Has been cancelled
wai-app and Create / wai-app · does this change touch it (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-fleet service / does this change touch it (push) Has been cancelled
wai-fleet service / service · linux (push) Has been cancelled
wai-fleet service / service · macos (push) Has been cancelled
wai-key-proxy / does this change touch it (push) Has been cancelled
wai-key-proxy / proxy · linux (push) Has been cancelled
wai-ledger service / does this change touch it (push) Has been cancelled
wai-ledger service / service · linux (push) Has been cancelled
wai-ledger service / service · macos (push) Has been cancelled
wai-vector vector graphics / does this change touch it (push) Successful in 16s
wai-vector vector graphics / macos-arm64 (push) Successful in 2m15s
wai-vector vector graphics / wasm32 under Node (push) Successful in 30s
wai-vector vector graphics / wasm32-wasip2 (wasmtime) (push) Successful in 1m13s
wai-vector vector graphics / fuzz, peak allocation, comparison count (push) Successful in 28s
wai-vector vector graphics / linux-x86_64 (push) Successful in 3m19s
wai-vector vector graphics / wasm32 in three browser engines (push) Successful in 3m11s
wai-vector vector graphics / linux-aarch64 (push) Successful in 5m19s
wai-vector vector graphics / independent checker (Python) (push) Successful in 4m42s
wai-pack: packages of several components, and the composing sink's package packed by it
packaging §5.8: a package leads with its video component and carries
beside it up to seven more on one presentation timeline, each cut at the
lead's piece starts and each piece one object of the capability that
suits it: audio as FLAC from a WAV, a score with a FLAC floor of its
mixdown, vector graphics (wai.graphics.vector), timed text
(wai.text.timed, each piece the WebVTT segment of its span, its target
naming its language) and a feed (wai.feed.state, each piece sealed by
the package's key and starting from the state the one before seals).
Every decode-equivalent base states its piece's decoded-output digest
in the stage index the receipt signs: the SHA-256 of interleaved s16le
samples for audio and a score's mixdown, the clip digest of the
overlay's RGBA8P frames for graphics, the SHA-256 of the segment its
cues write back to for text. wai-pack packs, lists, signs and verifies
them, and refuses by name what it does not pack.

The policy takes the media graphics and text and a text component's
lang; the stage index the media classes 7 and 8. wai.graphics.vector
is read as its pending registration states and wai.text.timed, a
record, as a text component's base whose payload is a segment, each
with no licence class. wai-rs adds codecs::audio::flac_encode_i16 and
flac_decode_i16, FLAC of 16-bit mono or stereo samples in pure Rust
(feature flac); the mono f32 encoder is unchanged.

pack-conformance/multi/: three goldens and multi_verify.py, which
recomputes every digest and payload from the sources. The composing
sink's reference package (wai-web/compose/package/, browser-sink §14)
is now wai-pack's, from compose/policy.toml, the fixture compose-01,
committed sources and a supplied AV1 floor, held byte for byte by the
corpus check, which also writes the forged receipt; wai-compose-package,
its own policy schema and native.json are gone. The page plays each
component piece by piece and holds every overlay piece and caption
segment to its signed digest too; run.mjs exits non-zero on any
failure, page error, missing engine or missing check.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-09 12:58:33 -05:00

122 lines
5.9 KiB
Markdown

# WAI Extension: State-Feeds
> Status: Draft. Phase 3 of the cargo roadmap. State as instructions:
> ship a signed op log of typed-field updates — a scoreboard, a
> telemetry stream, a market tape — not a recorded video of a dashboard.
> A state-feed is a non-physics world, so conformance is
> **replay-equivalence**, reused wholesale from interactive-worlds.
> Reference impl: the `world` feature of `wai-rs` (sim
> `wai.world.sim.feed0`); corpus: `feed-conformance/`; live sink:
> wai.transaction.science/feed.
Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
## 1. Scope and model
A `wai.feed.state` object is a **non-physics world**: the same `WWLD`
container, op log, canonical ordering, causality, sealing, state hash,
and receipt chain as interactive-worlds (see `interactive-worlds.md`),
with one difference — the simulation step is the **identity**. Nothing is
integrated; state changes only when a signed op applies a typed-field
update. It is lever 3 (instructions-at-the-sink) for live state: a
scoreboard update is a few signed bytes ("add 7 to field 1"), not a
frame of a broadcast.
In scope: the record/cell model, the registered feed sim
(`wai.world.sim.feed0`) and its mutation kinds, the broadcast profile,
and the statement that conformance is exactly worlds' replay-equivalence.
Out of scope: everything interactive-worlds already defines (it is
normative here unchanged); a transport; a schema *language* (a declared
schema is an edge-level validation/labelling layer — the floor parses
self-describing cells without one).
Relationship to the core spec: a registration under interactive-worlds,
not a new container. `media` takes the value `"feed"`; the authoritative
capability is `wai.feed.state`, carried in a `WWLD` whose contract names
`sim = wai.world.sim.feed0`.
## 2. Records and cells
A node is a **record**: an ordered vector of self-describing typed
cells. Canonical field order is index order (hence hash order). Three
cell types cover scoreboards, telemetry, and market data:
| tag | type | encoding | use |
|---|---|---|---|
| `0x01` | `Int` | `i64` LE | scores, counts, volumes, enums, booleans |
| `0x02` | `Fixed` | `i64` LE (Q32.32 `Fx` bits) | gauges, prices, percentages |
| `0x03` | `Text` | `u16 len` + UTF-8 | names, ticker symbols, labels |
A record body is `n_cells u16 | cells…`; each cell is `tag u8 | payload`.
Cells being self-describing is deliberate: the canonical state bytes —
and therefore the state hash — parse with no external schema, so the
determinism contract has no schema dependency.
## 3. The feed sim — `wai.world.sim.feed0`
Registers these mutation kinds (a field-update kind carries a
`field_idx u16` prefix). The `step` is the identity.
| kind | payload | resolution | effect |
|---|---|---|---|
| `0x0001` CREATE | record body | LWW | insert; target MUST equal `mint_node_id(actor, lamport)` |
| `0x0002` DELETE | *(empty)* | LWW | remove the node |
| `0x0010` SET_CELL | `field_idx u16 \| cell` | LWW | replace one cell |
| `0x0011` ADD_INT | `field_idx u16 \| i64` | SUM | add to an `Int` cell (saturating) |
| `0x0012` ADD_FIXED | `field_idx u16 \| i64` Fx bits | SUM | add to a `Fixed` cell (saturating) |
An op targeting an absent node, an out-of-range index, or a wrong-typed
cell is a **deterministic no-op** (an op set MUST mean the same thing on
every sink — interactive-worlds §6.4). LWW rides the canonical total
order for free; SUM kinds accumulate, and because every op within a tick
applies in canonical order, the result is deterministic regardless of
arrival.
## 4. Conformance — replay-equivalence
> Given the same feed container and the same signed op set, a conforming
> sink MUST compute the identical BLAKE3 **state hash** at every
> checkpoint — on every machine, no tolerance parameter.
This is interactive-worlds' criterion verbatim; the feed adds no new
conformance idea. `state_hash = BLAKE3("wai:world-state\x01" ||
canonical_state_bytes)`, the canonical bytes being the records in
node-id order, each as `id | len | record-body`.
## 5. Broadcast profile
The commercial shape of a feed is one authoritative **publisher** and
many read-only **sinks** ("ship state, not pixels" for sports, events,
telemetry). This is a deployment profile of `wai.world.live`, not a new
format: the publisher signs ops and fans them out over the same relay;
a read-only sink simply never publishes. A sink that wants a literal
picture falls back to a spectator AV1 stream of a capable participant's
render (interactive-worlds §9) — presentation, never conformance. The
authoritative artifact a spectator can audit is the op log + the sealed
state hash.
## 6. Receipt (JWP profile)
The interactive-worlds session receipt (`jwp-receipts.md`) applies
unchanged: world identity over contract + tick-0 graph; the group's
objects are the op batches, Merkle-bound; one Ed25519 seal (verified as
SPEC §7 *Signatures* requires) over world
hash + root + checkpoints + exact signed `work` + carried `joules_micro`
(with its acquisition class as an optional signed label,
[energy-measurement](energy-measurement.md) §2.8);
`parent_receipt_hash` chains a feed's seals into a timeline.
In a package ([packaging](packaging.md) §5, *Components beside the lead*), a feed is cut at the lead's piece starts:
each piece a sealed `WWLD` of the state at its start and the signed ops of its ticks, sealed
by the package's key, each piece's graph the state the piece before it seals.
## Appendix
A state-feed is the minimal world: drop the physics and you are left
with exactly the part of interactive-worlds that was always doing the
load-bearing work — a signed, canonically-ordered, content-addressed,
sealed-and-receipted log that every sink replays to the same state. That
the same machinery covers a multiplayer game and a stock ticker is the
point: the cargo class is "any live state worth auditing", and the
verification is identical to sight (worlds), sound (mixdown), and touch
(sample).