2.9.0
Released
Features
Added a staff-triggered control on feedback detail pages that creates one GitHub issue, stores the durable association, and opens the existing issue on later visits (#496).
Fixes
Stopped two simultaneous staff requests from opening duplicate GitHub issues for one feedback report. The row is reserved before GitHub is called, so the second request answers
409— or200with the association once the first finishes — instead of creating an untracked issue. The association write is retried once, and its reservation is kept if it still fails, so a retry cannot mint a second issue either (#496).
Security
Restricted issue creation to staff with
feedback.write, limited feedback submissions to user-authored fields so clients cannot forge triage, notification, or timestamp state, excluded submitter identity, screenshots, and admin notes from GitHub content, validated GitHub responses before storage, and kept credentials and upstream error details server-only (#496).
Technical changes· 5 entries for database, tooling, CI, tests and docs
Database
Added a protected, all-or-none GitHub issue association to feedback reports; ordinary authenticated clients cannot forge or alter it (#496).
Added
feedback.github_issue_claimed_at, a service-role-only reservation that serializes GitHub issue creation for a report. It is written before the external call, cleared when that call fails, and expires after ten minutes so a request that dies mid-flight does not wedge the control (#496).
Tooling & Configuration
Added optional
GITHUB_TOKEN,GITHUB_REPO_OWNER, andGITHUB_REPO_NAMEconfiguration to the web environment, Turborepo allow-lists,.env.example, and the dev TUI's masked managed keys (#496).
Tests
Added pgTAP, Vitest, and Playwright coverage for protected associations, configuration, issue formatting, authorization, idempotency, failure handling, and the admin create/view experience (#496).
Documentation
Documented the staff-triggered feedback-to-GitHub contract, API, schema, privacy boundary, and local configuration (#496).