wai: staged delivery in the browser — one base decode, the wasm binding, and its check #152
Loading…
Reference in a new issue
No description provided.
Delete branch "wai/land-18-staged-browser"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Staged delivery, rebuilt in the browser by the reference sink.
staged::decode_basechecks the base's pin against the parameter set held in memory, counts the pin toward the tier only where it resolved, and records when a base was decoded through the manifest's fallback. The CLI and the browser binding share it.wai-web/src/stage.rsgives JavaScript the staged sink: decoding a base, offering, expiring and removing layers, attestation, the reports, and each unit's stage, producer, tier, output and stage hash. A layer's header, declared cost and byte split are also exposed. Reports and units come back in the corpus's own form.demo/verify_staged_wasm.mjsreplays every staged-conformance case through the wasm32 build, and CI runs it. It requires each integer base to decode to its stage 0, and every report, unit and stage hash to equal the native sink's.wai stage basewrites an integer-video base from raw frames.wai stage applyreplays layers and bases in any order and prints a JSON trace.wai_stage_benchreports bytes, quality and time per stage. Energy is reported as unmetered.A base is bounded and dispatched before it is decoded.
decode_baseanddecode_base_viatake a cost limit and the sink's key log.cost_over_limitand routes like an unsupported capability.StageSink::add_basecounts a base's state against the chain budget (staged-delivery §4.5).In the browser binding:
StageBase.decodetakes a limit.stageLayerInforeturns a base's declared cost.fromStage0) is checked against the manifest's capabilities, its tier is capped, and it is markedclaimed. That mark carries to every unit, report and stage hash of its chain.viaFallbackis read-only.Smaller fixes:
wai stage applynow routes exactly as the reference sink does, and a test replays the corpus through it.--jsontrace records every stage a unit passes through.Checked locally on macOS arm64: the link gate, the wasm verifier, the staged corpus through both verifiers, the CLI tests and the public-text checks. The forge CI runs on this pull request.
🤖 Generated with Claude Code
- staged::decode_base: decode a base envelope for a sink through int_payload::decode_int, verifying its pin against the set held in memory; the tier counts the pin only where it resolved. The CLI and the browser binding both call it, so there is one base path. - int_payload::encode_wiv1_zero_motion: the reference keyframe-0 WIV1 encoder (zero motion, one block per frame, closed GOP) moves out of the corpus generator into the library. The corpus regenerates byte for byte through it. - wai stage base: writes a wai.video.int_motion base from raw RGB8 frames, decoded back before it is written. - wai stage apply: a StageSink replay. Envelopes are taken in order; a later base is decoded and releases the layers held for it. --json prints each step's reports in the corpus's form and the units each step changed, with their stage hashes, for a sink elsewhere to check against. Tests: int_payload::tests::encode_wiv1_zero_motion_round_trips, staged::tests::decode_base_reads_the_pin_and_the_corpus_units, cli_stage::{base_refine_apply_json_trace, apply_holds_layers_for_a_later_base}. Co-Authored-By: Claude Opus 5.5 <[email protected]>- wai stage apply: with --stage0 the base is claimed; its step, its units, every report of its chain and its final entry say "claimed": true (as the browser binding marks a claimed chain). A base the tool cannot decode (encrypted, inert, refused by its pin or payload) is its step's error by code, and the replay goes on. - staged::decode_base refuses in a stated order: not-wai1, encrypted (SPEC §6.4 before §4), not-offered, then §4; a parameter set's listing is made only for a capability that reads a set, so a stray file name is no refusal for wai.video.int_motion. The doc states each token's vocabulary, and that the cost limit binds a base whose capability declares a cost (int_synth and int_mlicpp decode under their formats' caps, as with_cost_limit does). - wai-web: fromStage0 applies SPEC §4 as decode_base_via does (an inert envelope, a refinement-only or companion-only capability, is claimed neither through its capability nor its fallback; the capability must be dispatchable). StageBase.decode requires its limit argument: left out it is refused; null means the format's caps only. - cli_stage::apply_json_replays_the_corpus also replays the four PNG and FLAC cases through --stage0 (claimed marks set aside, and required) and budget_partly_applied: 43 cases agree. Tests: staged::tests::{decode_base_refuses_in_its_stated_order, decode_base_limit_binds_declared_costs_only}, cli_stage::{apply_stage0_marks_the_base_claimed, apply_records_a_refused_base_and_goes_on}, the inert cases in stage::tests::a_claimed_base_cannot_raise_its_facts and in demo/verify_staged_wasm.mjs, which also requires the limit argument. Co-Authored-By: Claude Opus 5.5 <[email protected]>