Release: develop -> main - #40
Merged
Merged
Conversation
* fix(invite): one list for a file-looking segment, one rule per path, two tests that prove something Four follow-ups the reviews of #34 and #37 left open. The gate that decides whether this pass owns a path and the parser that reads the code out of it both asked whether a suffix names a file, with two different sets: the gate carried jpg|jpeg|webp|ico|txt|xml that the parser lacked, the parser carried html that the gate lacked. So /invite/AB.HTML passed the gate and then lost its code, while /invite/AB.JSON never reached the gate at all. Both read one constant now, and a case asks the two as a single question across every suffix — the sweep includes html, a suffix that names no file type, and a mixed-case spelling — so a set that grows on one side and not the other fails there rather than in production. The two still ask it of different things, deliberately: the gate of the whole path, because /invite/AB12CD/logo.png is an asset request whoever owns the first segment, and the parser of the code segment alone. A case pins that difference as well as the agreement. html is not in the list for one reason: a code that happens to end in .HTML stays a code. The shell needs no help from the list — the parser names index.html outright — and the 308 that canonicalises it comes from the platform and is handed on either way. public/_headers had a rule for /invite/ and another for /invite/*, and the first matches the second. Every answer that matched both carried the value twice: measured on the deploy, /invite/ answered cache-control: public, max-age=60, public, max-age=60 Pages concatenates what every matching rule says rather than letting one win, and a parser takes the first. The rules the wildcards already cover are gone, the bare paths keep theirs, and /invite/invite.js keeps its own rule above the wildcard — the restatement below it, added when the match order was thought to be uncertain, only appended a third value nobody reads. check-site.mjs now requires the wildcard, rejects a rule the wildcard covers, and rejects the same exact path declared twice, which its own header parser had been merging out of sight. Two tests could not tell a working build from a broken one. The clipboard stub resolved and discarded what it was handed, so the case named after copying the canonical invite URL passed on any string, or on none; it records now, and the case requires exactly one write, equal to the href the canonical link names. And the fifteen-second lookup budget was asserted against its own constant and nowhere else: a request that never answers now has to leave the loading state by itself, and the case measures how long that took against the budget the page itself reports. * test(invite): say which of the two claims does which job The comment said the budget is read from the page rather than restated here, and the line under it restates it. Both belong there — the size is pinned outright, because bounds computed from the page's own number would follow it anywhere, and the elapsed time is measured against that number so another timer cannot pass for this one. The comment now says that instead of denying half of it. * test(invite): three comments that claimed a little more than the code The sweep's comment implied it catches any divergence between the two sides, where it walks a list of its own and catches a divergence on what it enumerates. The .PDF case called it a dot that names no file type, where PDF is a file type this rule simply does not call an asset. And the timeout case said the budget was asserted against itself, where the unit suite pinned it against a literal and went no further. * fix(invite): catch any covered rule, and start the clock where the wait does The covered-path check listed the four rules that happened to be there, so a rule added later would have slipped past it. It now rejects any exact path a landing wildcard covers, with the script's own rule kept on purpose: it wants a longer cache than the shells, and a parser takes the first of the two values. Proven by adding a rule for /invite/foo and watching it fail. The budget case took its timestamp before the navigation, so a slow page load counted against the budget and could push the upper bound over on a busy machine. It starts when the page says it is checking, which is when the timer the case is about was armed. --------- Co-authored-by: TaprootFreakAI <315477232+TaprootFreakAI@users.noreply.github.com>
TaprootFreak
approved these changes
Sep 10, 2026
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.
Automatic Release PR
This PR was automatically created after changes were pushed to develop.
Commits: 1 new commit(s)
Checklist