Required
id
Private: Stable Buttondown subscriber key for dedupe and ledger reconciliation.
Public: Never displayed.
Referral wiring
This is the implementation bridge for MY-2571 and MY-2577: static invite links, Buttondown metadata, private review, then a safe public leaderboard artifact.
Internal prep only: no webhook, subscriber email, reward fulfilment, public leaderboard refresh or sponsor-backed prize is triggered from this static page.
Buttondown export contract
Define the minimum Buttondown subscriber export shape needed to build a private St Albans referral ledger and a redacted public leaderboard.
Do not publish live rankings, email subscribers, contact referrers, fulfil rewards or expose raw Buttondown exports until attribution, abuse review and editor approval have passed.
Required
Private: Stable Buttondown subscriber key for dedupe and ledger reconciliation.
Public: Never displayed.
Required
Private: Hash immediately with a per-market salt before storage.
Public: Never displayed or written to public JSON.
Required
Private: Used to order referral credit and detect burst abuse.
Public: Never displayed.
Required
Private: Maps a confirmed subscriber to the inviting reader token.
Public: Used only after aggregation into confirmed referral counts.
Required
Private: Maps the subscriber to their own invite link.
Public: Never displayed raw.
Required
Private: Filters exports to St Albans only.
Public: Can only appear as broad market label.
Required
Private: Confirms website-subscribe origin and excludes imports/test rows.
Public: Never displayed.
Required
Private: Only confirmed subscribers increment referral totals.
Public: Never displayed.
Private ledger schema
buttondown_subscriber_id
confirmed_email_hash
reader_token_hash
referral_source_hash
signup_market
created_at
confirmed_at
source_tag
fraud_review_status
manual_reward_status
Public JSON schema
rank
display_name
area
confirmed_referrals
reward_tier
reviewed_at
Metadata contract
metadata__referral_source
Never displayed raw; used only to attribute a confirmed subscriber to an inviter.
metadata__reader_token
Can be mapped to an approved display name after opt-in.
metadata__signup_market
Market filter for multi-newsletter dashboards.
tag
Operational filter only; never shown to readers.
Transform checks
Reject rows where signup_market is not good-morning-st-albans.
Reject rows without website-subscribe tag unless they are manually whitelisted.
Reject rows where is_confirmed is false.
Hash email, reader_token and referral_source before writing any private ledger file.
Exclude self-referrals where subscriber hash and referrer-owned hash match.
Exclude duplicate confirmed_email_hash rows from public counts.
Emit only publicLeaderboardSchema fields to website/public/leaderboard/leaderboard.json.
Dry-run proof
Run export transform against a fixture with confirmed, unconfirmed, duplicate and self-referral rows.
Assert no email, Buttondown id, raw reader token or raw referral source appears in public JSON.
Assert the public leaderboard stays hidden if any top-ten row has fraud_review_status other than cleared.
Record fixture result in Linear MY-2571 before enabling a live Buttondown export.
Manual refresh sequence
Use Buttondown confirmed subscriber data only after credentials and approval exist; never commit raw exports or private emails.
Deduplicate by subscriber email and reader token, then review same-IP clusters, disposable domains and suspicious bursts before publishing.
Update only /leaderboard/leaderboard.json with initials, area labels, confirmed counts and reward tiers after manual approval.
Publication gates
Export or webhook source must include only confirmed Buttondown subscribers.
Referral counts must be deduplicated by subscriber email and reader token before any ranking is shown.
Public display names must use initials, explicit opt-in names or area labels; never raw emails.
Prize eligibility must be reviewed manually before any sponsor-backed draw is announced.
Leaderboard JSON must be generated as a static artifact; no private subscriber API response is exposed client-side.