Agenda doc for the in-person session. Four initiatives from the brain dump, each grounded against current code and data. Two of them turn out to need a different framing than the brain dump assumed — those are flagged ⚠ premise check and are the most valuable conversations to have in the room.
Read order is deliberate: #1 is the multiplier that makes #3 cheap, #2 depends on a primitive we just built, #4 needs a definition before it needs a buyer.
Added 2026-07-28 — read section 0 first. Four days after this was written, a full pass over Search Console, site analytics and the vpn-clicks database changed the framing. The four initiatives below are still right. They are no longer the first conversation.
Every number here is measured. Nothing is modelled or assumed. Sources: vpn-clicks D1 (11,299 outbound clicks, 30 days, 142 countries), Search Console (6,405 clicks, 30 days), site analytics (27,858 sessions, 30 days).
We have spent a year improving the machine — Divi to Astro, edge delivery, a deeper funnel, 17 languages. Conversion did not move. This is why. Four independent filters sit between our traffic and our revenue, and each removes a large share of whatever the previous one left.
Determined from the actual destination URL of every click, not from what we believe our deals are.
| Where the click actually goes | Clicks / 30d | Share |
|---|---|---|
| A real affiliate link — nord, proton, expressvpn, cyberghost, surfshark, pia, nordlayer | 7,520 | 66.6% |
| Straight to the provider's own site, earning nothing — windscribe, mullvad | 1,241 | 11.0% |
| A gateway interstitial recommending a partner that does pay — tunnelbear, purevpn, mcafee, privado, hotspot shield, vypr, hideme, bitdefender, norton, ipvanish, ivpn, avast | 2,538 | 22.5% |
Only 7 of the 29 partners we route traffic to have a working affiliate link.
The 22.5% is not wasted, and it is worth understanding before anyone calls it a leak. When a partner has no affiliate URL, /out does not redirect — it serves the verdict interstitial ("You chose TunnelBear · We recommend NordVPN"). The visitor then chooses:
| Outcome | Clicks / 30d |
|---|---|
Took the recommendation (gw_verdict_pick) | 333 — 279 of them to Nord |
Continued to the original provider (gw_verdict_continue) | 257 |
Versus template, chose Nord (gw_versus_nord / nordfb) | 74 |
That is deliberate revenue recovery: rather than hand a click to someone who pays us nothing, we pitch someone who does. The https://www.vpn.com/vpn/{provider}/ URL recorded in the database is the "continue anyway" target, not where visitors are sent.
The genuine loss is the 11.0% — Windscribe and Mullvad redirect straight to their own sites, with no interstitial and no recovery. 1,241 clicks a month, given away.
Site-wide unengaged rate is 52.1% (13,426 of 25,777 sessions). "Unengaged" means the visit failed every test: under 10 seconds, one page only, no conversion, no meaningful click, less than half the page scrolled.
Half of everyone who arrives does nothing whatsoever. No funnel change reaches them.
www.vpn.com free vpn, vpn gratis, 免费vpn, vpn مجاني).Our single best-converting audience is looking for a product that costs nothing. We have been optimising against a metric — the affiliate click — that rewards exactly that behaviour.
Across all 142 countries in the click data:
| Clicks / 30d | Share | |
|---|---|---|
| Countries that reliably buy subscriptions — US, CA, GB, DE, FR, NL, JP, KR, AU, the Nordics, SG, HK | 6,826 | 60.4% |
| Everywhere else | 4,473 | 39.6% |
Largest sources in that second group: PK 3.0% · IN 2.9% · IR 2.9% · EG 2.1% · ID 1.9% · AZ 1.7% · BD 1.6% · CN 1.5% · VN 1.3%.
These are markets with low card penetration, little subscription habit, and a strong preference for free VPNs. The product we send them is priced for a different economy.
Related, from analytics: India, Indonesia, Pakistan, Bangladesh and Vietnam are 21.9% of sessions but only 10.7% of outbound clicks — half the engagement rate of the average visitor. (This one compares two measurement systems and should be read as directional — see traffic-quality-queries.md for the caveat.)
| Clicks / 30d | Share | |
|---|---|---|
| Nord — the only partner reporting sales back to us | 3,103 | 27.5% |
| No reporting at all | 6,961 | 61.6% |
| No deal, earns $0 | 1,236 | 10.9% |
We judge the entire VPN business on one partner that is 27.5% of outbound clicks — and it is the one that pays us best. We are extrapolating from the single most favourable case we have.
The debate has been "traffic problem or selling problem." The measured answer is that neither side has been arguing from evidence, because three quarters of the outcome is invisible.
What we can say with confidence:
PIA and CyberGhost sharing aff_id=1312 is correct, not a bug. Both are Kape brands on one affiliate account, and the links differ by offer_id (PIA 2416, CyberGhost 10), so attribution separates properly. It had been flagged in three separate notes as a possible revenue misroute. It isn't one.
Cut the time from "idea" to "reviewable concept in front of a person" from days to hours, permanently. Not a one-off cleanup: a standing capability, so every future design conversation starts from something you can look at.
Concepting is currently expensive for reasons that have nothing to do with design. Every visible string has to exist in 17 languages, every surface has to clear a WCAG 2.2 AA gate at 0 violations, and build.sh runs a stack of gates — SEO audit, key-leak, translation QA, FAQ integrity, contamination, a11y — before anything ships. Each of those is correct and worth keeping (they were built because things broke), but together they mean a throwaway concept currently pays the full price of production code.
The result: we argue about designs in the abstract, or we skip the concepting step and build straight into the real page, which is the expensive way to be wrong.
Ben's read: 2/10 against where this needs to be. That is the right score, and the spec itself shows why.
What exists at /Applications/MAMP/htdocs/design-factory/ (WORKER.md, FACTORY-SPEC.md) is a filing system for mockups: registry contract, stable concept IDs, /factory/ galleries, star/comment feedback to a queryable feedback.jsonl, and a promotion procedure. That is genuinely useful and worth keeping. It is also not a pipeline.
vpn-astro has no factory/ folder yet, so even the 2/10 isn't installed here.
The gap between 2 and 10 is precisely the friction named above, and the spec explicitly leaves all of it out:
| Gap | What the spec says today | Why it caps the score |
|---|---|---|
| i18n | not mentioned | Promotion is "port the concept using project-native patterns" — i.e. the 17-language cost is paid manually, by hand, every time |
| a11y | not mentioned | Same: the WCAG gate is met by hand after the fact, not by construction |
| Design system | "should not enforce specific visual style" | A concept can drift off the token system, so a winner needs rework before it can ship |
| Real data | concepts are static | VPN.com surfaces are data-driven (provider JSON, pricing, Speed Lab). Reviewing a concept full of placeholder content is reviewing the wrong thing |
| Deploy | dfx build → dist/ | Nothing about how /factory/ reaches a URL a reviewer can actually open |
| CLI | dfx is listed as a "CLI Target" | Aspirational — it doesn't exist |
So the honest framing: the factory currently makes concepting cheap and leaves promotion exactly as expensive as it is today. Since promotion is where the i18n/a11y/deploy cost lives, installing the kit as-is buys us maybe 3/10.
Phase 1 — install the 2/10 and prove the loop. Seed vpn-astro/factory/, put the current live /vpn/ hero in as concept 1.1, get it on a reviewable URL. Cheap, and it makes the remaining gaps concrete instead of theoretical.
Phase 2 — close the promotion gap (this is the actual project). In rough value order:
t() keys from day one means promotion is a translate run, not a refactor. This is the single biggest lever on the 2→10 score.a11y-audit.mjs against /factory/ on demand, so a concept that can't pass is caught while it's still cheap to change./factory/ that a reviewer opens without a local build.Phase 3 — evergreen. Every design task starts in the factory. Heroes, proof blocks, CTAs and pricing tables accumulate as reviewed, token-native, i18n-shaped starting points. That is the compounding asset.
Agree what 10/10 means — the table above is my read of the gap, not Ben's definition. Then install Phase 1, since it costs little and makes Phase 2 concrete.
/factory/ (noindex, not a real surface), enforced on promotion. Needs an explicit decision so nobody helpfully wires the gates in and reinstates the friction we're removing.Turn Perks from a dead email list into an owned, re-reachable audience with a reason to come back.
ops/growth-backlog.md.Show Perks on the /out gateway: give us email/phone, get rewarded for this purchase.
This is the right surface, and we can now prove it. The gateway is where the money actually happens — July NordVPN attribution puts gateway_buy at $900 of $1,257 (72%) of traced revenue. It is the highest-intent moment on the property, and today we ask nothing of the visitor there. It is also, usefully, the moment where "get rewarded for this purchase" is a true statement rather than a promise.
A ledger that can answer "how many points does this person have, and why." Then the email flow hangs off the ledger rather than off a signup event.
The load-bearing dependency, and the good news: crediting a purchase requires detecting the affiliate sale and tying it to a specific person. That needs a unique per-click ID passed to the network and returned on conversion. As of the 2026-07-24 attribution work, aff_click_id is already mapped on NordVPN and sitting empty — filling it is a small build, not a research project. Same primitive also unlocks revenue-per-click reporting, so it pays for itself twice.
A logged-in surface to see and spend points. Deliberately last: it is the most build and the least learning.
/vpn/ as a real use-case results pageThis is the initiative where the brain dump is most right, and it is worth being precise about why.
Today /vpn/ swaps text per use case. VpnPage.astro renders every variant's copy into the same HTML and reveals one via a data-uc-var attribute on <html> (flicker-free, but purely presentational). There is exactly one route: src/pages/vpn/index.astro.
So today, choosing "streaming" changes the headline, the sub-head, and one credibility line. It does not change which providers are shown, or in what order. The results are identical for a torrenting user and an enterprise user. That is the actual gap — and it means the current implementation cannot deliver the thing a "results page" implies.
Consequences of the single-route design:
The personalization itself works and is worth building on, not replacing:
/vpn/, hero engagement runs ~31% of viewers at ~66% conversion.So intent capture is proven. What is missing is that the intent then changes nothing material.
Phase 1 — make results actually use-case-driven. Rank and filter the provider set per use case from the existing provider JSON. use-cases.ts already carries a champion per case, so the data model is half there. This is the change that makes it a results page.
Phase 2 — give each use case a real URL. A proper template with a route per case, so the page can rank and be linked, and so the copy for one case is not shipped to everyone.
Phase 3 — the modal fallback. If no use case is set, ask. This is the brain dump's instinct and it is correct — but sequence it last: a modal that captures intent is only worth the interruption once the intent visibly changes the page. Shipping the modal first trains people that answering does nothing.
Decide whether per-use-case pages are new indexable routes or a personalized layer over one canonical URL. That single call determines whether this is an SEO play or a conversion play, and everything else follows from it.
The broker cherry-picks. They take buy-side work and want no sell-side leads at all. Today a seller who fills in our form gets an email with a generic GoDaddy link — we monetise them at exactly $0.
That is 70% of everything the form produces:
action_type | Rows | Unique people |
|---|---|---|
| sell | 340 | 184 |
| buy | 142 | 116 |
| mixed | 6 | 5 |
Per month, and the qualification outcome:
| Month | Sell rows | Unique sellers | Qualified |
|---|---|---|---|
| June | 158 | 100 | 4 |
| July (24d) | 182 | 87 | 1 |
~90–100 unique sellers a month, and 5 qualified across two months (1.5%) — not because they're bad leads, but because the broker declines the category. They aren't failing a quality bar; they're being refused at the door.
And they are not small. Stated value on the sell side skews high — 128 sell rows at the $250k band, 17 at $500k, 12 at $1M. We are handing away sellers with quarter-million-dollar asking prices with a GoDaddy referral link.
An earlier version of this doc reported that $10k leads qualified at 16.3% vs $250k at 6.3%, and framed budget as an inverted quality signal. That was a confound and I was wrong. Sell leads dominate the upper bands (128 sell vs 39 buy at $250k) and almost never qualify, which dragged those bands' rates down. Filtering to buy-side only:
| Stated budget | Unique buy leads | Qualified |
|---|---|---|
| $10k | 75 | 59 (79%) |
| $50k | 9 | 7 (78%) |
| $250k | 24 | 16 (67%) |
| $500k / $1M | 5 | 2 |
Buy leads qualify at roughly 67–79% across every populated band. Budget was never the signal — buy-vs-sell was. (Raw ads_stage, so still inflated by the stale-CRM backfill sweep; the point is the flatness across bands, not the absolute level.)
The practical upshot is better than the earlier framing: there is no ambiguity about which segment to route away, and no risk of accidentally selling our best buyers.
Ben's read: pass any sell lead to a hungry overseas team and make a killing. The data supports it — this is ~90–100 qualified-intent sellers a month, with real inventory, currently worth nothing to us.
"We have the pipeline, we're missing the buyer" is exactly right here, and unlike the earlier framing, nothing is blocked on the broker side. We don't need their dead-lead list to identify this segment; action_type='sell' already identifies it at intake.
Phase 1 — stop the bleed, capture the value. Keep the seller experience intact but replace the generic GoDaddy email with something that preserves the relationship and the option value. Even before a buyer exists, the sell leads should be tagged, retained and reachable rather than waved off.
Phase 2 — find the buyer. The commercial question, and the main thing to work through in the room: a partner brokerage, an overseas team on commission, or a per-lead sale. Volume (~100/month, valuable inventory) is a real negotiating position.
Phase 3 — build the routing. Cheap once 2 is settled. Intake already writes to D1 before forwarding to GHL and already carries action_type plus per-domain action in domain_intake_items, so the branch point exists — it's a fork in domain-intake.js, not new plumbing.
Decide the disposition model (Phase 2). That is the only real blocker; the identification and the plumbing are both already done.
/factory/?#4 first, and it is not close. ~90–100 unique sellers a month currently worth $0, the segment needs no definition work, and the plumbing already exists. It is the only initiative here where the identification and the engineering are both already done and the sole blocker is a commercial decision that can be made in the room. Highest value, least work, fastest.
#1 second — it is the multiplier for everything after it, but it is now understood to be a real project rather than an install. Phase 1 (install the 2/10) can happen immediately and cheaply; Phase 2 is the scoped work, and it needs the 10/10 definition first.
#3 third, deliberately after #1. It means designing and comparing a new results template — several attempts, exactly the work the factory is supposed to make cheap. Doing it before #1 means paying the old concepting cost on the initiative most likely to iterate.
#2 Phase 1 in parallel where capacity allows. The gateway is provably where the revenue is (72% of traced Nord dollars) and currently asks the visitor for nothing — but Phase 1 can't honestly launch until the point-value question is answered, so it is gated on a decision rather than on engineering.
ops/growth-backlog.md — the prior points-to-cash design, cap structure, and the sub-ID passback dependencyops/digest-2026-07-28.md — the attribution work that makes Perks Phase 2 a small build/Applications/MAMP/htdocs/design-factory/WORKER.md — the prototyping standard to install