open-standards/wai/extensions/avatars.md
Transaction Science d009db9087
Some checks failed
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m48s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m17s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m16s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m7s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m29s
wai cross-architecture byte-equality / linux-x86_64 (pull_request) Successful in 22s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 2m7s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 22s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 42s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 39s
wai formal verification (integer core) / kani (pull_request) Successful in 4m59s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 52s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Failing after 1m7s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 6m49s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 24s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 2m28s
standards workspaces build + test / aac-rs (pull_request) Successful in 3m25s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 3m46s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m22s
standards workspaces build + test / map-rs (pull_request) Successful in 2m16s
standards workspaces build + test / mesh-rs (pull_request) Successful in 2m3s
standards workspaces build + test / openpay (pull_request) Successful in 18m29s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 1m58s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Failing after 7s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Failing after 7s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Failing after 8s
standards workspaces build + test / arl-rs (pull_request) Successful in 3m49s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 3m19s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m45s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 3m17s
standards workspaces build + test / sense-rs (pull_request) Successful in 4m0s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 3m42s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 27s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 2m43s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 28s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 1m14s
wai cross-architecture byte-equality / windows-x86_64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · windows (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · windows (pull_request) Has been cancelled
wai: on-chip counters and calibrated instruments are separate energy classes, and every joule-carrying receipt can say which
The single `HwShunt` acquisition class covered both an on-chip vendor
counter (RAPL, NVML, SMC, IOReport) and an external calibrated shunt. They
are different evidence: a calibrated instrument's uncertainty is traceable to
a calibration, while a counter is a vendor's reading whose error the vendor
states (RAPL readings are deliberately noised when SGX or TDX is enabled,
per security advisory INTEL-SA-00389).

- extensions/energy-measurement.md §2 splits hardware evidence into
  `OnChipCounter` and `CalibratedInstrument`, each with a required declared
  uncertainty (relative error and integration window). IOReport is an
  on-chip counter, like RAPL and NVML. `HwShunt` stays readable as the legacy
  class, ranked below both, and is not sealed into a new WAI receipt.
- Every receipt family that carries joules — video, world, film, reel,
  haptic, score, splat4d, audio scene, ternary, provenance and the wai-quantum
  receipts — can carry its class. The label is additive: every committed
  signed vector still verifies, and the signed bytes of unlabelled and
  legacy-labelled receipts are pinned by tests. A sealed figure declares its
  1 µJ resolution, and the floor is stated as the rule verified (0.5/√3 µJ).
- The acquisition rules are scoped to the receipt profiles WAI defines, and
  the text says what enforces each one.
- Meters open their window from rest, report an all-zero power reader as
  unusable rather than clean, and state the running-window count model as
  conservative.
- oer-receipts.md maps OER's evidential grade onto the refined classes. The
  rule that a producer must not grade `measured` a figure whose class is
  `Estimator` is kept as settled on main.
- wai-quantum verifies a receipt in either form on every in-tree verify
  path, including wai-quantum-serve's POST /verify.
- CI: wai-energy-receipts.yml runs the energy-class, label and legacy-pin
  tests for wai-rs, wai-quantum and wai-quantum-serve, which no workflow
  enabled before.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-29 01:27:37 -04:00

114 lines
5.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WAI Extension: Avatars (Digital Humans)
> Status: Draft. Phase 4 of the cargo roadmap. Motion as instructions:
> ship a signed stream of joint transforms — a skeleton, not a video of a
> body — and the sink skins a mesh by the deterministic pose. An avatar
> is a skeletal world, so conformance is **pose-equivalence**, a special
> case of replay-equivalence. Reference impl: the `world` feature of
> `wai-rs` (sim `wai.world.sim.skeletal0`); corpus: `avatar-conformance/`;
> live sink: wai.transaction.science/avatar.
Keywords **MUST**, **MUST NOT**, **SHOULD**, **MAY** are RFC 2119/8174.
## 1. Scope and model
A `wai.avatar.pose` object is a **skeletal world**: the same `WWLD`
container, op log, canonical ordering, causality, sealing, state hash,
and receipt chain as interactive-worlds (see `interactive-worlds.md`),
with the simulation step reduced to the **identity** (as with
state-feeds). The bones are nodes; an animation / expression op stream
sets joint transforms; nothing is integrated. A telepresence stream is a
live world of one avatar — the op log that drives a multiplayer world
drives a body.
In scope: the bone model, the registered skeletal sim
(`wai.world.sim.skeletal0`) and its mutation kinds, the statement that
conformance is worlds' replay-equivalence over the pose, and the
binding to a `wai.mesh.glb` for skinning.
Out of scope: everything interactive-worlds already defines (normative
here unchanged); the skinning algorithm and forward-kinematics
composition (sink presentation — a pure function of the hashed pose +
the hierarchy); a transport; blend-shape / morph-target semantics beyond
joint transforms (a later registration may add them).
Relationship to the core spec: a registration under interactive-worlds,
not a new container. `media` takes the value `"avatar"`; the
authoritative capability is `wai.avatar.pose`, carried in a `WWLD` whose
contract names `sim = wai.world.sim.skeletal0`. The avatar's mesh is a
content-addressed `wai.mesh.glb` asset (its armature + skin weights),
bound to the rig like any other presentation asset.
## 2. The bone
A node is a **bone**: a parent reference plus a local TRS transform.
Canonical field order (and therefore hash order) is exactly:
| field | type | meaning |
|---|---|---|
| `parent` | `[u8; 16]` | parent bone's node id, or all-zero for a root |
| `translation` | `[Fx; 3]` | local translation (Q32.32) |
| `rotation` | `[Fx; 4]` | local rotation quaternion `(x, y, z, w)` |
| `scale` | `[Fx; 3]` | local scale |
The canonical node serialization is `parent(16) | translation | rotation
| scale` = 16 + 10×`i64` = 96 bytes. The default bone is the identity
(zero translation, identity quaternion, unit scale).
The floor stays **trig-free**: a rotation is carried as a quaternion, and
the quaternion → rotation-matrix the sink uses for skinning is `+ − ×`
only. Axis-angle authoring (which needs sin/cos) happens once, off-line,
in whatever produces the op bytes — the canonical artifact is the `Fx`
quaternion, and every sink replays it exactly.
## 3. The skeletal sim — `wai.world.sim.skeletal0`
Registers these mutation kinds; the `step` is the identity. All are LWW
(a transform set rides the canonical total order — last canonical writer
wins; there is no commutative transform set, so no SUM kind).
| kind | payload | effect |
|---|---|---|
| `0x0001` CREATE | `parent[16] \| translation[3] \| rotation[4] \| scale[3]` | insert a bone; target MUST equal `mint_node_id(actor, lamport)` |
| `0x0002` DELETE | *(empty)* | remove the bone |
| `0x0010` SET_ROTATION | `rotation[4]` | set a joint's local rotation (the animation driver) |
| `0x0011` SET_TRANSLATION | `translation[3]` | set a bone's local translation |
| `0x0012` SET_SCALE | `scale[3]` | set a bone's local scale |
An op targeting an absent bone is a **deterministic no-op**
(interactive-worlds §6.4). `parent` need not name a present bone — a
missing parent is treated as a root at FK time; the *hash* depends only
on the stored values, so existence is irrelevant to conformance.
## 4. Conformance — pose-equivalence
> Given the same avatar container and the same signed op set, a
> conforming sink MUST compute the identical BLAKE3 **state hash** at
> every checkpoint — the per-bone local transforms, in node-id order — on
> every machine, no tolerance parameter.
This is interactive-worlds' criterion verbatim, applied to the bone
state. The forward-kinematics composition into world space and the
skinning of the mesh produce identical results on any two sinks that
agree on the pose (a pure function of the hashed locals + the hierarchy),
so they are legitimately left to presentation and excluded from the hash
— exactly as `wai.mesh.glb` geometry is.
## 5. 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 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 performance's seals into a timeline.
## Appendix
An avatar is the highest-bandwidth capture reduced to its instructions:
a body in motion is a rig plus a stream of joint angles, and the standard
carries the rig and the angles, not the pixels. Pose-equivalence makes
the *motion* auditable — two parties to a call hold the same signed
skeleton — while the *appearance* stays the sink's, skinned from a shared
mesh. Sight (worlds), sound (mixdown), touch (sample), live state (feed),
and now a moving body (pose) are one floor, one verification.