Privacy
What we store
- A short-lived anonymous cookie identifies a voter session. - Voter hashes and ballot pseudonyms are derived tokens used only for anti-duplicate voting. - Operational logs store request and route-level events; they do not store raw IP addresses. - Catalog search terms travel in the request URL to return results. Application logs record the route path, not raw `q` values, and application analytics do not retain raw searches. - Public pages use the self-hosted Umami service at `umami.ros.pw` for page-view analytics. The tracker sends the website ID, hostname, page path, title, referrer, browser language, and screen size. It excludes query strings and URL hashes and respects Do Not Track. - Umami uses the request IP address, user agent, and website ID to make an anonymous session hash. The tracker sets no cookie and sends no distinct ID or custom session data. - The private admin layout does not load Umami. Session replay, heatmaps, performance telemetry, and custom events are not enabled. - Turnstile verification uses challenge-only payloads and does not persist, forward, or log raw IP addresses. - Metric events are limited to operational outcomes needed for moderation and reliability, and only on an aggregate basis. - Denominator for results is the total number of accepted votes per matchup.
Retention
- Anonymous voter token: 30 days. - Ballot pseudonym set: 14 days. - Raw vote rows: retained for operational review window, then moved to immutable aggregates. - Vote void evidence/audit trail: retained as documented in operational runbooks. - Rate-limit state: limited short window for abuse control. - Umami page-view rows: stored on the operator-owned server until operator deletion. No automatic expiry is configured. - Other optional analytics or telemetry defaults to disabled.
Vendors
- Hosting and edge: Cloudflare (Pages, Worker, DNS, R2, Turnstile).
- Page-view analytics: self-hosted Umami behind Cloudflare at `umami.ros.pw`.
- Database: managed PostgreSQL provider.
- Each vendor receives only the fields needed for service operation and follows standard contract terms.
Product metrics, denominator rules, and consent basis
- Approved metric events:
- Umami page views on public routes, without query strings, URL hashes, custom data, or user IDs.
- `competition_state_view`: route visits to duel/archive/winner/template routes for latency and availability monitoring.
- `catalog_request`: aggregate result/no-result and latency counters without the raw query.
- `vote_attempt`, `vote_accept`, `vote_reject`: operational quality signals for integrity and abuse controls.
- `finalization_complete`: finalizer outcomes with round count and elapsed duration.
- `policy_lookup`: policy content access for legal review workflows.
- Denominator rules:
- Voting conversion and completion metrics are based on accepted votes per matchup.
- Duplicate retries, invalid payloads, and challenge failures are excluded from percentage counts.
- Consent basis:
- The owner enabled cookie-free Umami page-view analytics for public traffic.
- The tracker respects the browser Do Not Track setting.
- Operational counters are off by default and require a separate owner decision.
- Optional analytics outside this page-view scope stays disabled unless explicitly approved.
Rights and disclosure
- No personal accounts.
- No ad tracking.
- No public profile linkage.
- Anonymous voting lowers abuse risk for open voting, but it does not prevent coordinated or cookie-reset manipulation.
- Cross-day voting behavior is not inferred across dates without explicit retention policy changes.
Requests and deletion
- Removal or correction requests are handled through the policy contact path.
- Retention and deletion outcomes are logged with request IDs, actor, and reason.
Abuse and bot controls
- Turnstile or equivalent challenge is required before write actions when configured.
- Rate limits and token entropy checks run on every vote attempt.
- Bot activity is rate-limited, but not blocked by default in a way that prevents ordinary accessible use.