ce8a03ab16
- N124: denoise shim cleanup() now disconnects the noise gate AudioWorkletNode (var-scoped, guarded), releasing the gate processor thread instead of leaking it on every getUserMedia within a session. - N125: denoise-status postMessage now targets the parent origin (derived from the parentUrl widget param via new URL(...).origin, falling back to this frame's origin) instead of broadcasting with '*'. - N128: patch-folds.mjs fails hard (process.exit(1)) when the patch target is missing, so an unpatched folds can't silently ship. The idempotent "already applied" path still exits 0 (verified by re-run). - N120: the avatar-decoration CDN URL is now single-sourced in avatarDecorations.ts (DECORATION_CDN); syncDecorations.mjs extracts it by regex (can't import across the build/app boundary) and fails hard if renamed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>