Repository navigation
Rate-limit the hot-seat beacon and cap its stored rows - #35
Merged
Merged
Conversation
POST /api/events/hotseat inserted a row for every completion, with no caller limit and no cap. It now calls the room-creation limiter, using that limiter's caller key, before insert. The eleventh beacon from one caller in a minute returns 429 and stores nothing. Stored hot-seat rows stop at 50, counted on their own. The unfinished-room floor stays 50 and still counts only unfinished rooms. A beacon that would store a new row past the cap is refused. A repeat for a game already stored is still accepted. The beacon request and SM-1 are unchanged. Tests: packages/server/tests/hotseat-beacon.test.ts.
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.
Summary
POST /api/events/hotseatnow uses the room-creation limiter, then refuses a new stored row past 50.The unfinished-room floor is unchanged.
RoomManager.createstill stops atcountActiveRooms() >= 50, and that count is stillterminal_event IS NULL.Seams
POST /api/events/hotseat: caller key, shared 10-per-minute allowance, 429 with no insert, cap of 50 new hot-seat rows, repeat of a stored game, floor left at 50 unfinished rooms.RoomDatabase.getRoom,countHotseatRows, andcountActiveRooms: a refused beacon leaves no row, and hot-seat rows are not the floor.Evidence
npx vitest run packages/server/tests/hotseat-beacon.test.tsfailed on the 11th beacon (expected 204 to be 429). After the limiter, the 51st new beacon still failed (expected 204 to be 400). A repeat at the cap then failed (expected 400 to be 204).After:
npx vitest run packages/server/tests/hotseat-beacon.test.ts— 7 passed.npm run typecheck -w @clave/serverpassed.npx vitest run --testTimeout 20000— 117 passed. Defaultnpm testhit the 5s timeout inpackages/engine/tests/properties.test.ts(about 7.7s, not in this diff); that file passed with--testTimeout 20000.Merge Danger
Door: two-way
Revert the server deploy and unlimited inserts return. Rows already stored stay until the 30-day expiry sweep. No migration.
Blast Radius: hot-seat completions and room creation
One caller now shares 10 requests a minute across
POST /api/roomsand the beacon. A 51st new hot-seat row is refused, so SM-1 can miss couch games past that cap or past the rate limit. The beacon body andops/metrics.sqlare unchanged. The online floor stays 50 unfinished rooms.Unaddressed findings
Standards
Mysterious Name (judgement call).
roomCreateCallerandRoomCreateLimiterstill say room create, at the new call inpackages/server/src/app.tslines 106-111. Issue Rate-limit the hot-seat beacon and cap its stored rows #34 says "Call the existing room-creation rate limiter, with its existing caller key." Those names inpackages/server/src/room-create-limit.tsare that limiter. Renaming them is not this issue.Duplicated Code (judgement call). The beacon handler repeats the allow-or-429 shape of
POST /api/rooms(packages/server/src/app.tslines 38-43), and the beacon tests repeat the caller-key cases frompackages/server/tests/room-create-limit.test.ts. The room route still answers "Too many rooms created. Try again in a minute." The beacon's 429 string is different because a beacon is not a room create. The beacon tests are what checkPOST /api/events/hotseat; the room-create tests never hit that route. A shared helper would edit the room-creation path this issue leaves alone.Spec
None.
Security
None.
Security review outcome
No unaddressed introduced findings.
Review coverage
Both axes read every changed file:
packages/server/src/app.ts,packages/server/src/database.ts, andpackages/server/tests/hotseat-beacon.test.ts. No changed file was left unread. No generated output was excluded.Closes #34
Built with grok · grok-4.7 · xhigh