Referral wiring

Buttondown-first attribution without exposing reader data.

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

Export inputs before a live leaderboard

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

id

Private: Stable Buttondown subscriber key for dedupe and ledger reconciliation.

Public: Never displayed.

Required

email

Private: Hash immediately with a per-market salt before storage.

Public: Never displayed or written to public JSON.

Required

creation_date

Private: Used to order referral credit and detect burst abuse.

Public: Never displayed.

Required

metadata.referral_source

Private: Maps a confirmed subscriber to the inviting reader token.

Public: Used only after aggregation into confirmed referral counts.

Required

metadata.reader_token

Private: Maps the subscriber to their own invite link.

Public: Never displayed raw.

Required

metadata.signup_market

Private: Filters exports to St Albans only.

Public: Can only appear as broad market label.

Required

tags

Private: Confirms website-subscribe origin and excludes imports/test rows.

Public: Never displayed.

Required

is_confirmed

Private: Only confirmed subscribers increment referral totals.

Public: Never displayed.

Private ledger schema

These fields stay outside public website output

Private field

buttondown_subscriber_id

Private field

confirmed_email_hash

Private field

reader_token_hash

Private field

referral_source_hash

Private field

signup_market

Private field

created_at

Private field

confirmed_at

Private field

source_tag

Private field

fraud_review_status

Private field

manual_reward_status

Public JSON schema

Safe public fields only

Public field

rank

Public field

display_name

Public field

area

Public field

confirmed_referrals

Public field

reward_tier

Public field

reviewed_at

Metadata contract

Fields the website passes to Buttondown

metadata__referral_source

Incoming subscribe URL ?ref= token

Never displayed raw; used only to attribute a confirmed subscriber to an inviter.

metadata__reader_token

Browser-local share token generated on /share/

Can be mapped to an approved display name after opt-in.

metadata__signup_market

Static hidden field

Market filter for multi-newsletter dashboards.

tag

Buttondown embedded form tag website-subscribe

Operational filter only; never shown to readers.

Transform checks

Assertions before any live export

Transform check

Reject rows where signup_market is not good-morning-st-albans.

Transform check

Reject rows without website-subscribe tag unless they are manually whitelisted.

Transform check

Reject rows where is_confirmed is false.

Transform check

Hash email, reader_token and referral_source before writing any private ledger file.

Transform check

Exclude self-referrals where subscriber hash and referrer-owned hash match.

Transform check

Exclude duplicate confirmed_email_hash rows from public counts.

Transform check

Emit only publicLeaderboardSchema fields to website/public/leaderboard/leaderboard.json.

Dry-run proof

Evidence to attach before enabling live attribution

Dry-run proof

Run export transform against a fixture with confirmed, unconfirmed, duplicate and self-referral rows.

Dry-run proof

Assert no email, Buttondown id, raw reader token or raw referral source appears in public JSON.

Dry-run proof

Assert the public leaderboard stays hidden if any top-ten row has fraud_review_status other than cleared.

Dry-run proof

Record fixture result in Linear MY-2571 before enabling a live Buttondown export.

Manual refresh sequence

How a safe leaderboard refresh should work

Export confirmed subscribers

Use Buttondown confirmed subscriber data only after credentials and approval exist; never commit raw exports or private emails.

Build private counts

Deduplicate by subscriber email and reader token, then review same-IP clusters, disposable domains and suspicious bursts before publishing.

Publish redacted projection

Update only /leaderboard/leaderboard.json with initials, area labels, confirmed counts and reward tiers after manual approval.

Publication gates

Hard stops before gamification goes public

Rule

Export or webhook source must include only confirmed Buttondown subscribers.

Rule

Referral counts must be deduplicated by subscriber email and reader token before any ranking is shown.

Rule

Public display names must use initials, explicit opt-in names or area labels; never raw emails.

Rule

Prize eligibility must be reviewed manually before any sponsor-backed draw is announced.

Rule

Leaderboard JSON must be generated as a static artifact; no private subscriber API response is exposed client-side.