Problem/Motivation
The fragment, branch, context, delivery, filter, and refresh endpoints do real work but carry no flood control, and all bypass page/render cache. The filter path renders matches at hardcoded full density up to a result limit that can be raised to 500. Several unbounded inputs amplify cost: an unconstrained instance_id, cache-context flooding via the act_mode_* and comment query parameters, and a filter() query that builds up to 4xN IN placeholders plus a Unicode branch that makes the CONTAINS conditions redundant.
Steps to reproduce
- Send repeated anonymous requests to a filter or fragment endpoint; note no throttling.
- Raise filter_result_limit to 500 and filter for a common term; observe ~500 full comment entity renders per request.
- Pass a long instance_id and observe response amplification; vary act_mode_* and comment and observe unbounded cache entries.
Proposed resolution
- Add flood control keyed on client + route (reuse the existing flood service pattern).
- Cap the filter render path and the number of comments load() materialises.
- Require the access comments permission so checks fail fast.
- Bound instance_id length; normalise act_mode_* and comment to stable values before adding cache contexts.
- Drop the per-path IN lists and the redundant Unicode branch in filter().
- Declare methods: GET on the branch and context routes, which are pure reads but currently declare no method restriction.
- Raise the filter minimum query length to 2-3 characters with a visible hint; every single character currently fires a full search after the 250 ms debounce, so capping render cost does not reduce the trigger count.
Remaining tasks
- Confirm throttling and bounded rendering on a 200+ comment node.
User interface changes
None, beyond faster and safer filtering.
API changes
Adds flood limits and input bounds; cache contexts use normalised values.
Data model changes
None anticipated.
AI-Generated: Yes (Used Opus 5 and DeepSeek Flash to review and discover these issues)
Comments
Comment #6
freelockAlpha3 follow-up: rejected input still creates distinct cache variants
Input validation does not yet normalize the cache-context values. The reader preference ignores invalid
act_readingcookies, butcookies:act_readingstill varies on their raw values. Arbitrary positive nonexistentcommentquery IDs also select no comment while creating distinct cache variants.Steps to reproduce
act_reading=junk-a, thenact_reading=junk-b.Remaining work and acceptance
Comment #7
freelockAlpha3 follow-up: minimum query length still permits full-index work
The permission checks and minimum search length are present, but the filter loads the full index before rejecting a too-short query. The configurable result limit also still permits 500 full-density renders, leaving the requested render-cost cap unfinished.
Steps to reproduce
Remaining work and acceptance
Comment #8
freelockAlpha3 follow-up: align the flood lock with the client bucket
The flood bucket is keyed by client IP and route, but its lock is route-wide. Because lock acquisition does not wait, contention can return
429to an unrelated client whose own bucket is allowed.Forced contention reproduced that mechanism. A subsequent review reported zero false rejections from 25 concurrent branch requests and 30 concurrent filter requests on fresh buckets. Practical availability impact has not been demonstrated; treat this as P3 hardening rather than an established service disruption.
Steps to reproduce
Remaining work and acceptance
Comment #12
freelockFixed in Alpha4.