Pull in the capture page that re-fetches relay-config when the key changes and
links to the service claim page, so the bundled page matches the invite flow.
The relay no longer stores per-room credentials. It reads one origins-only
config with a base64url master secret and derives each room name and capability
token by HMAC, byte for byte with caption-local/keys.py, accepting short-lived
expiring tokens. Rooms are created on first authorized join and retired when
idle, so users are isolated without per-event configuration. Probes, benchmarks
and tests generate their credentials from the same master; a vector test pins
the derivation against the Python implementation.
- Resync the capture bundle (caption-local e5637d1): relay-config.js and
ws-publisher.js have no default relay, and the capture page starts with
empty relay and caption website fields.
- overlay.html, overlay_enhanced.html and editor.html always go through
CaptionRelay.setup(), which asks for a relay address when the link does
not carry ?relay=, instead of connecting to the public relay.
- relay/init-config.cjs no longer adds https://caption.ninja to the
generated origins.
Removes the 664 MB models/ tree (history keeps it; no rewrite). The download
script now pins version 0.3.4, verifies every file against the registry's
SHA-256, writes latest.txt last so partial downloads are never served, and
accepts MODEL_PAIRS to fetch a subset.
links.html hardcoded the captions.dev.autonomic.zone hosts. It now reads
window.CAPTIONS_SITE {relay, capture} from site-config.js, which each
deployment serves; capture links stay hidden when unset.
Resynced the Caption Local bundle (caption-local 709fe68): private-only relay
auto-fill, no hardcoded dev hostnames, sharing off by default, Firefox
sample-rate fallback.
sanitize() parsed untrusted caption text with innerHTML on a detached div, so
<img src=x onerror=...> executed in every overlay (including OBS), and its
textContent output was inserted as HTML again, so <img ...> ran too.
Parse with DOMParser (inert document) and escape the result before callers
insert it. Covers overlay.html and overlay_enhanced.html; Steve's upstream
fix/overlay-escaped-caption-text-20261006 only addresses the second decode.
- Remove remote translation providers (Google Cloud Translation, OpenAI,
Anthropic): translation-providers.js is now a local-only shim and the
overlays translate through the bundled Mozilla Bergamot worker only.
- Remove Google Cloud TTS (ttskey/googlettskey parameters and the speak()
branch); native browser TTS plus opt-in ElevenLabs/Speechify remain.
- worker.js loads only the bundled /models directory and no longer falls
back to the remote model proxy.
- Update translation-guide.html, README.md, CLAUDE.md and
overlay_enhanced_readme.md for the local-only workflow.
- Sync the caption-local browser bundle (relay defaults, Firefox
resampling, session token, favicon, CSP).