# ollywoo — standards review

Each browser capability the ollywoo set uses, or should use, is listed below against the specification
that governs it.

- **Maturity** is the status printed on each spec's own page. It was fetched on **2026-10-10** from the URL
  shown, and was not recalled from memory.
- **Used how** describes what the code actually does.
- **Fallback** describes what happens where the capability is missing. A capability the browser lacks is
  feature-detected and reported, never shown as if it worked.

## Capture: camera and microphone

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| getUserMedia, enumerateDevices, constraints, getCapabilities/getSettings, applyConstraints | [Media Capture and Streams](https://www.w3.org/TR/mediacapture-streams/) · Candidate Recommendation Draft, 9 Oct 2025 | Mic and cam. The device pickers, capabilities and settings in the 👁/👂 panels. Mic processing is read back after applyConstraints. | Every failure is named (blocked / not found / busy / over-constrained). The IR sensor is detected by label **and by measured frames**. |
| ImageCapture.grabFrame | [MediaStream Image Capture](https://www.w3.org/TR/image-capture/) · Working Draft, 23 Apr 2025 | `/still`: a still of the camera for the eye's analysis. | Feature-detected. Without it, the `<video>` is drawn to a canvas, and the panel says which path was used. |
| Depth tracks (`videoKind: "depth"`) | [Media Capture Depth Stream Extensions](https://www.w3.org/TR/mediacapture-depth/) · **Discontinued Draft**, 1 Feb 2022 | `/depth sensor` checks `getSupportedConstraints().videoKind` and asks for a depth track. | Discontinued, so no browser is expected to support it. `.depth` is extrapolated from contrast and labelled as such. |
| MediaRecorder | [MediaStream Recording](https://www.w3.org/TR/mediastream-recording/) · Working Draft, 16 Mar 2026 | ⏺ clip, the cam-monitor recording, and the mic's rolling capture. | `isTypeSupported` picks webm/vp9 → webm → mp4. |
| Permission state | [Permissions](https://www.w3.org/TR/permissions/) · Working Draft, 6 Oct 2025 | The 👁/👂 panels show camera/microphone permission and re-render on change. | "not reported by this browser". |

## Audio, speech and codecs

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| AnalyserNode, decodeAudioData, OfflineAudioContext | [Web Audio API](https://www.w3.org/TR/webaudio/) · Working Draft, 22 Sep 2026 | Mouths, the ground, mic level/pitch, and the ear's files. `.frequency` decodes actual audio. | AudioWorklet is not used yet. The analysis runs on decoded buffers off the frame loop. |
| WebCodecs | [WebCodecs](https://www.w3.org/TR/webcodecs/) · Working Draft, 7 Oct 2026 | Not used on the set. playdocs' device-render uses it for Opus. | — |
| SpeechRecognition (listen) | [Web Speech API](https://webaudio.github.io/web-speech-api/) · **Draft Community Group Report**, 18 Sep 2026 (not a W3C Recommendation track spec) | Mic → words into the console. | Feature-detected, with "not supported" said in the HUD. Chrome/Edge send the audio to the vendor's service, and the FAQ says so. |
| WebVTT | [WebVTT](https://www.w3.org/TR/webvtt1/) · Candidate Recommendation Draft, 20 May 2026 | The ear's reader exports the sentence timings (from the render's own marks) as `.vtt`. | — |
| Media Fragments | [Media Fragments URI 1.0](https://www.w3.org/TR/media-frags/) · Recommendation, 25 Sep 2012 | Not used yet. A `#t=start,end` link per sentence is the natural next step. | — |

## Vision and face

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| FaceDetector | [Shape Detection API](https://wicg.github.io/shape-detection-api/) · Draft Community Group Report (WICG), 12 Sep 2026 | Not used: MediaPipe FaceLandmarker, vendored, gives 478 landmarks where FaceDetector gives a box. | — |

## Files and input

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| File, Blob, `file.text()`/`arrayBuffer()` | [File API](https://www.w3.org/TR/FileAPI/) · Working Draft, 12 Sep 2026 | Ear and eye drops. Size caps apply (64 KB for text); types are checked, and WAV headers are validated by RIFF. | — |
| Drag and drop, `<input type=file>` | [HTML (WHATWG Living Standard)](https://html.spec.whatwg.org/multipage/dnd.html) | Drop on the eye (images) and on the ear (audio, .txt). Each has a button and a file picker as the second way in. | Keyboard and touch users use the buttons. |
| Pointer Events | [Pointer Events Level 3](https://www.w3.org/TR/pointerevents3/) · **Recommendation**, 30 Jun 2026 | Eye/ear hit-testing, the colour map, and airtype keys. | — |

## Hashing and colour

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| SubtleCrypto SHA-256 | [Web Cryptography API](https://www.w3.org/TR/WebCryptoAPI/) · First Public Working Draft, 22 Apr 2025 (the API itself has long shipped) | Every hash on the set: forge log, `.event` chain, faceprints, `.depth`/`.color`/`.frequency`, and print recomputation. | Needs a secure context (https), which the set always is. |
| OKLab / OKLCh, `color()` | [CSS Color Level 4](https://www.w3.org/TR/css-color-4/) · Candidate Recommendation Draft, 9 Oct 2026 | `.color` medians and ΔE in OKLab. The picker readout prints `oklch()`. | The maths is done in JS, so it does not depend on CSS support. |
| The 16 basic colours | [HTML 4.01 §6.5](https://www.w3.org/TR/html401/types.html#h-6.5) · Recommendation | Tier 1 of the palettes. | — |
| EyeDropper | [EyeDropper API](https://wicg.github.io/eyedropper-api/) · Community Group draft (WICG; `specStatus: CG-DRAFT`) | "pick from the screen" in the colour picker. | Offered only where `'EyeDropper' in window` (Chromium). Elsewhere it says "not supported". |

## Rendering and display

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| WebGL / WebGPU | WebGL is Khronos, not W3C · [WebGPU](https://www.w3.org/TR/webgpu/) · Candidate Recommendation Draft, 15 Sep 2026 | three.js r184 on WebGL draws the set. WebGPU is not used. | — |
| WebXR (AR button) | [WebXR Device API](https://www.w3.org/TR/webxr/) · Candidate Recommendation Draft, 9 Jun 2026 | three.js ARButton. | The button itself says "AR not supported" when the device can't. |
| Screen Wake Lock | [Screen Wake Lock](https://www.w3.org/TR/screen-wake-lock/) · Working Draft, 29 Sep 2026 | Held while the camera is on, and released when it stops. | Silently absent where unsupported. Nothing depends on it. |
| Picture-in-Picture | [Picture-in-Picture](https://www.w3.org/TR/picture-in-picture/) · Working Draft, 16 Jun 2026 | ⧉ in the camera monitor floats the monitor canvas: the actual frames plus the mesh. | Shown only where `document.pictureInPictureEnabled`. |
| requestVideoFrameCallback | [WICG draft](https://wicg.github.io/video-rvfc/) · Draft Community Group Report, 2 Aug 2024 | Not used yet. Frame work runs on rAF and pauses when hidden. | — |

## Accessibility

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| WCAG 2.2 | [WCAG 2.2](https://www.w3.org/TR/WCAG22/) · **Recommendation**, 12 Dec 2024 | Targets of at least 24 px in the panels; the airtype keys are 38 px. Focus is visible. Every 3D target (eye, ear) has a button. The colour map is one focusable control moved by the arrow keys. `prefers-reduced-motion` limits the mouths to 4 Hz, and the ground draws one frame. | The finest colour-map density is under 24 px. Its keyboard path is the equivalent control. |
| ARIA | [WAI-ARIA 1.2](https://www.w3.org/TR/wai-aria-1.2/) · **Recommendation**, 6 Jun 2023 | `role="dialog"` panels, `aria-label` on buttons and canvases, `role="tablist"`/`tab` in the eye's analysis. The senses line is `aria-live`. | — |

## Provenance and data

| Capability | Spec · maturity (2026-10-10) | Used how | Fallback · support notes |
|---|---|---|---|
| JSON-LD, PROV-O | [JSON-LD 1.1](https://www.w3.org/TR/json-ld11/) · Recommendation, 16 Jul 2020 · [PROV-O](https://www.w3.org/TR/prov-o/) · Recommendation, 30 Apr 2013 | `/events jsonld` exports the chain as `prov:Entity` records. A response is `prov:wasDerivedFrom` its input, and each event is `prov:wasRevisionOf` its predecessor. | This describes provenance; it does not sign anything. |
| Verifiable Credentials, DIDs | [VC Data Model 2.0](https://www.w3.org/TR/vc-data-model-2.0/) · Recommendation, 15 May 2025 · [DID 1.0](https://www.w3.org/TR/did-core/) · Recommendation, 19 Jul 2022 | **Not implemented.** See below for how a signed chain could be expressed. | No signature is faked. |

### How a signed chain could be expressed with Verifiable Credentials

A signed `.event` chain could be expressed as a VC. Its `credentialSubject` would be the chain head
(`urn:sha256:<id>`) plus the event count, its issuer would be the participant's `did:pkh` (from the
wallet that already signs consents with EIP-191), and its proof would be a Data Integrity proof over it.
None of that is built.

## Tested on

- **Real images.** Six public-domain portraits from Wikimedia Commons: the *Mona Lisa*, Lincoln 1863 ×2,
  Lincoln 1864, and Frederick Douglass c.1866 and c.1879. Licences and URLs are in `reference/sources.json`
  and the test report.
- **Real data.** A real `/voicey` render and the real `/voicey/measure`.
- **Fake media.** Headless fake camera and mic are used as a regression harness only. They are not
  verification of capture.
