# Player bug reports The header's **Send bug report** button opens `/support`. Players can report a bug with an optional PNG, JPEG, or WebP screenshot up to 5 MB. Each submitted report creates one Medium-priority issue in Linear. Retries reuse server-generated issue and comment IDs. Screenshots are normalized, stripped of metadata, and uploaded to private Supabase Storage and Linear assets. Signed-in players keep reports in their account. Guests keep access through a 180-day HttpOnly browser cookie. A guest can sign in in the same browser and choose **Keep this report in my account**. Clearing the cookie before linking loses guest access. Conversations and screenshots are private. ## Linear commands Add a new comment on the report's issue beginning with: ```text #player-report-send Dear user, we found the bug. Thank you for reporting it! ``` The text after the prefix appears in the player's conversation. Other staff comments remain internal. Player follow-ups appear in Linear with `#user-report-message`; the initial report uses the same prefix in its description. Editing an existing comment does not send another message. Players can select **Close report** after support has received it. The conversation shows **Done**, becomes read-only, and displays its deletion date. MineGeo moves the matching Linear issue to the team's **Done** status. Staff can also post the exact command `#player-report-close`, or move the issue to Done in Linear. Three days after closing, a durable Vercel Workflow deletes the Linear issue, both the original and normalized Supabase screenshots, the local report, and its messages. It runs even when nobody visits support. Linear's normal deleted-issue trash retention still applies. Username glow and Bug finder rewards already granted to an account remain. Guest rewards must be linked before the report is deleted. Reopening the issue in Linear before cleanup starts cancels deletion; closing it again starts a new three-day period. Repeated close requests and replayed staff commands do not extend the existing deadline. To grant or remove the actual account reward, add a separate new comment: ```text #player-report-glow grant #player-report-glow revoke ``` Use one command per comment. A guest reward is held until the report is linked to an account. The glow appears beside account names on the dashboard, settings, leaderboard, and public map credits. Only verified Linear webhook commands can change rewards; browser writes cannot grant them. The follow-up migration `20261008075322_profile_identity.sql` adds a permanent **Bug finder** badge when a glow is granted. Revoking the glow preserves the badge. Guest reports retain confirmed-bug recognition when linked after a glow revoke. Players with an active glow can choose any hex color in **Settings → Username glow**. Moderators display a shield badge, and Admins display a crown. Admins can find an account in **Moderation → Player prefixes** to assign, change, or remove a custom text/icon prefix. Account IDs disambiguate players with identical names. Prefixes do not change permissions. These decorations appear in account views, leaderboards, map credits, support conversations, and authenticated multiplayer rosters and chat. Guests cannot gain badges by copying a registered player's display name. ## Deployment setup Apply `20261008071054_bug_reports.sql`, `20261008075322_profile_identity.sql`, and `20261010053310_bug_report_retention.sql` before deploying. Production environment variables in Vercel: - `LINEAR_API_KEY`: sensitive personal API key with **Read and Write** access to the support team. Create issues/comments alone cannot update status or delete issues. If needed, create a replacement in Linear **Settings → Security & access → Personal API keys**, then replace this variable in Vercel **Production** and redeploy. Never paste the key into chat. - `LINEAR_WEBHOOK_SECRET`: sensitive signing secret of the team's Linear webhook. - `LINEAR_TEAM_ID`: support team UUID. - `LINEAR_PROJECT_ID`: optional project UUID or Linear project identifier. Enable **Comment and Issue** events on the team webhook and set its URL to `https://minegeo.vercel.app/api/support/linear`. Redeploy after saving environment variables. Keys stay server-side and must never be pasted into issue descriptions, client configuration, or source uploads. Webhook requests require a matching raw-body HMAC signature and a timestamp within 60 seconds. Duplicate events have no effect. Delivery to Linear happens after the HTTP response; opening the conversation retries interrupted or failed delivery. The page shows saved/pending and delivered states. Issue events immediately synchronize Done/reopened states. Opening the inbox or conversation also checks status, at most once per minute per report, as a fallback. If Linear or Storage deletion fails, the local report is retained for retries; the conversation shows a retry action if cleanup exhausts its automatic retries. Keep Vercel's **Enable access to System Environment Variables** setting enabled for durable timers. No additional secret or cron is needed. Validation: `npm test`, `npm run typecheck`, `npm run build`, and `node scripts/test-bug-reports-sql.mjs` (uses the isolated PGlite installation under `.data/sql-verification`, as the other SQL verification scripts do). `node scripts/test-bug-retention-http.mjs https://minegeo.vercel.app` verifies the deployed flow with a clearly labeled temporary report and screenshot. It checks ownership, Done synchronization, the three-day deadline, and deletion from both systems by advancing only that test report's deadline. The fixture ID is journaled under the ignored `.data/retention-check` directory for recovery.