Repository navigation
fix(core): tell an opaque document how to actually get its Web Audio back - #3940
Merged
Merged
Conversation
…back The opaque-origin fix in #3937 routed correctly but sent the diagnostic down a dead end. An opaque document reached the same `cross_origin_no_cors` verdict a genuinely foreign asset gets, so the message told the author to "proxy or download the asset to a same-origin URL". That is impossible advice, because nothing is same-origin with an opaque origin and the asset is usually same-origin by URL already. Split the verdict into two reasons and give each its own note and remedy. The opaque case now names the two fixes that work: `allow-same-origin` on the sandbox, or `crossorigin` plus an `Access-Control-Allow-Origin` of `null` or `*`. Opacity wins when both conditions hold, since it is the blocking one and the one an author cannot fix by moving the asset. The CLI scraper matches on the code prefix only (checkBrowser.ts:309), so the new reason value does not touch that contract. - Rames
miguel-heygen
approved these changes
Sep 14, 2026
miguel-heygen
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed 68e1f970202f4c46136599115fb921fc5e4b4c57. The predicate retains the same HTTP/non-HTTP, same-origin, and CORS-opt-in decisions; the behavioral change is the reason/remediation chosen for an opaque document. The opaque reason takes precedence and is exercised for same-host and remote assets, with console and bridge assertions. No other runtime consumer compares the old reason literal. Current CI is green; reviewed the complete diff and tests, without a new browser/audio experiment. No database changes.
Verdict: APPROVE
Reasoning: The diagnostic now names the correct origin problem without changing the media-routing decision. No blocking finding.
— Magi
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Follow-up to #3937. Splits the Web Audio bypass verdict into two reasons,
cross_origin_no_corsand a newopaque_document_origin, and gives each its own diagnostic note and remediation text.Why
#3937 fixed the real bug correctly: a composition inside a sandboxed iframe no longer loses its sound. But the fix added a new path into a diagnostic, and the diagnostic gives dead-end advice on that path.
This module exists so something gets said. Its own docstring says the complaint in #3458 was that nothing was. On the new opaque path it now says, at
webAudioRoute.ts:279:In an opaque document that is a guaranteed no-op. The asset is usually already same-origin by URL, which is exactly why the bug existed, and nothing is same-origin with an opaque origin, so there is no URL that satisfies the instruction. The two remediations that do work,
allow-same-originon the sandbox orcrossoriginwith a matchingAccess-Control-Allow-Origin, were never mentioned.The reason token had the same problem one level down. An opaque document reached the identical
cross_origin_no_corsverdict a genuinely foreign asset gets, so the two cases were indistinguishable at the classifier's output and on the bridge message. That is defensible in the narrow sense, since from an opaque document every http(s) origin genuinely is foreign, but it is what forced the message to be wrong for one of the two cases it covers.Credit to Somu for the shape: a second reason is cleaner than branching the prose, because it fixes the conflation rather than papering over it.
How
isCorsSilencedbecomescorsSilenceReason, returning which reason applies or null. Module-private, one call site.NOTE_BY_REASONandREMEDY_BY_REASONcarry the per-reason text, so the console line and thedetailson the bridge message stay in sync.httpMediaUrl, and thewindow.originread intodocumentSecurityOrigin. That was not cosmetic: fallow blocked the first commit at cyclomatic 10 / CRAP 31.6 on the merged function, and it reads better split.No behaviour change to the routing. A
crossoriginopt-in still rescues the opaque case,file:still exits at the scheme guard, and a normal document is untouched. Only the reason value and the words change.The scraper contract is safe.
packages/cli/src/utils/checkBrowser.ts:309matchestext.startsWith("[hyperframes] runtime_web_audio_bypass"), the code prefix only, never the reason.checkBrowser.test.ts:447-453exercises the whole console line as a fixture with a genuinely cross-origin asset, so it keeps the old reason and is unaffected. I checked this before choosing the approach, not after.Test plan
webAudioRoute.test.ts: the opaque classification, opaque-plus-remote (opacity wins), acrossoriginopt-in still rescuing an opaque document, the opaque remediation line, and the reason and note crossing the bridge.webAudioRoute.tstoorigin/mainand re-ran: 4 failed, 25 passed. With the fix: 29 passed. The opaque test previously asserted the misleading token, so it was pinning the defect as expected.packages/coresuite: 576 passing. 18 test files fail to collect on@hyperframes/parsers/*imports, which is an unbuilt workspace in my worktree, not this change. Confirmed by stashing the diff and re-running on a pristine tree: the same 18 fail there, with 571 passing.oxfmt --checkclean, and all lefthook hooks pass including fallow and typecheck. Commit is signed.— Rames