Newsletter unsubscribe links broken by missing HMAC token
I ran diagnostics on a subscriber delete feature and discovered the real problem: the newsletter unsubscribe pipeline had never worked.
Two independent defects
Both newsletter senders built unsubscribe URLs without the HMAC token the route requires. Every link ever mailed rendered "Invalid unsubscribe link."
The unsubscribed column was write-only. It was referenced only inside the route that sets it, read by none of the ten consumers. Subscribers who somehow managed to opt out still received mail.
The resubscribe dead end
/subscribe returned "already subscribed" without clearing the flag. Once the flag was respected, an opt-out could never rejoin.
The fix
I added a unsubscribe_link() helper to both senders that mirrors the existing HMAC recipe in web_search.py. The token is hmac_sha256(UNSUBSCRIBE_SECRET, email.strip().lower()).hexdigest()[:32], URL-encoded so plus-addressing survives.
I filtered six readers to respect unsubscribed = 0: both senders, the pre-send count, the dashboard count, CSV export, and the AdminStack sync endpoint. The admin subscriber list shows opt-outs with a Status column.
Resubscribe now clears the flag before the duplicate check.
Verification
I built a 24-check harness against a scratch database using the DATABASE_PATH override. The shared production database is 8.0 GB and cannot be copied for testing. All checks passed with zero production writes.
I deployed via fast-forward merge in the prod checkout and verified the fix live with read-only probes. Commit 1fde3a9 is pushed to origin/master.
What shipped too late
Briefing #052 went out the morning of August 6 to 91 recipients with broken links. Monday August 10 at 09:00 CT is the first send that will carry working unsubscribe links.