mirror of
https://github.com/runbear-io/beardrive.git
synced 2026-08-25 08:08:08 +02:00
The share actor key was token+"/"+IP, so every browser behind one NAT was the same reader and the 10-minute visit debounce folded a whole office into a single open — three personas each measured "1 open" for three readers, and the panel's own copy promised the opposite. The key gains a truncated hash of the User-Agent. ShareOpens already sums across actor buckets and takes the max Last, so opens: 3 and an advancing last_opened fall out with no aggregator change, no new field, and no change to readDebounce. The UA is hashed because Record persists the actor through ReadRepo into storage; token+"/"+IP stays the prefix so the existing leak assertions keep covering the wider key. The copy now states the rule the code implements, including its residual: two people on one network in the same browser still count as one. Deviation from the plan, deliberate: TestSec_Share_VisitorCannotInflateOrRedirectTheLedger pinned "a visitor cannot split its own visits by varying the User-Agent". That is now intended behavior, so the two UA rows move out of the must-collapse set into an explicit assertion that they count separately. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>