@@ -119,12 +119,14 @@ export const FREEBUFF_RESTRICTED_COUNTRIES: readonly string[] = ['CN']
119119 * `flaggedEmailDomain` instead. Catching it there is what makes this tier
120120 * affordable.
121121 *
122- * $5 and not $15: SG remains a top VPN and datacenter exit, so the tail this
123- * bounds is real even with the farm named. Five dollars is the same figure a
124- * limited-region account gets — enough for a full day's ordinary work, still a
125- * bound — and deliberately not a number that has to be defended per-country.
122+ * $1 as of 2026-08-31 (operator decision; was $5 from 2026-08-15): the tail
123+ * kept growing and the farm-domain pricing did not shrink it enough. One
124+ * dollar still buys a normal day of ordinary sessions, and unlike the
125+ * restricted tier it now carries the live-session leeway multiplier below —
126+ * at this size, letting an open session run to 1.25x and then cutting is the
127+ * bound that matters, exactly the reasoning the restricted ceilings use.
126128 */
127- export const FREEBUFF_ELEVATED_DAILY_SPEND_USD = 5
129+ export const FREEBUFF_ELEVATED_DAILY_SPEND_USD = 1
128130
129131/**
130132 * Countries held at the elevated ceiling.
@@ -308,18 +310,63 @@ export function freebuffSessionSpendNotice(verdict: {
308310 */
309311export const FREEBUFF_SPEND_CEILING_HARD_MULTIPLIER = 2
310312
313+ /**
314+ * Daily-spend FLOORS for accounts holding a live paid plan (2026-08-31).
315+ *
316+ * The cohort ceilings above were sized for free usage, and until this floor a
317+ * paying customer inherited them unchanged: measured over the 48h before it
318+ * shipped, 11 live subscribers were spend-refused — six limited-region
319+ * Starters at the $3 region ceiling they had paid to escape, three in a
320+ * restricted country at thirty cents a day against an $8/month plan.
321+ *
322+ * A floor, not an exemption: the plan's own monthly spend cap remains the
323+ * money bound, and a stolen card should still not buy unbounded daily burn.
324+ * Composed as max() AFTER the cohort minimum, so it can only ever RAISE a
325+ * paying account's ceiling, never lower one — a full-region paid account whose
326+ * cohort maths already exceeds the floor keeps the higher number.
327+ *
328+ * Full access floors higher than everyone else ($7 vs $3) on the operator's
329+ * explicit split: paid limited-region and paid suspicious-cohort accounts go
330+ * to $3. `third_party_client` is deliberately NOT floored — an account
331+ * observed sending a foreign toolset while paying is the reseller pattern
332+ * (see freebuff2api), and the one cohort where a card is evidence of a
333+ * business model rather than a person.
334+ */
335+ export const FREEBUFF_PAID_DAILY_SPEND_FLOOR_USD : Record <
336+ FreebuffAccessTier ,
337+ number
338+ > = {
339+ full : 7 ,
340+ limited : 3 ,
341+ }
342+
343+ /** The reasons a paid floor may override. Everything except the reseller
344+ * cohort — see FREEBUFF_PAID_DAILY_SPEND_FLOOR_USD. */
345+ const PAID_FLOOR_REASONS : ReadonlySet < string > = new Set ( [
346+ 'region' ,
347+ 'elevated_country' ,
348+ 'restricted_country' ,
349+ 'privacy_egress' ,
350+ 'flagged_email_domain' ,
351+ 'unverified_egress' ,
352+ 'trust_level' ,
353+ ] )
354+
311355/**
312356 * Reasons whose ceiling is small enough that the hard multiplier applies.
313357 *
314- * `region`, `elevated_country` and `trust_level` are excluded: all three are
315- * whole-population limits where the fresh-admission gate is proportionate, and
316- * applying a hard cut there would interrupt ordinary paying-in-attention users
317- * mid-thought. `elevated_country` sits at the same $5 as a limited-region
318- * account precisely so it can be reasoned about as a region ceiling rather
319- * than as a suspicion, and cutting it live would undo that.
358+ * `region` and `trust_level` are excluded: whole-population limits where the
359+ * fresh-admission gate is proportionate, and applying a hard cut there would
360+ * interrupt ordinary paying-in-attention users mid-thought.
361+ *
362+ * `elevated_country` JOINED this set on 2026-08-31 when its ceiling dropped
363+ * $5 → $1: at one dollar, overshoot is no longer proportionally small, and
364+ * the multiplier is what grants an open session leeway to finish before the
365+ * hard cut — the same trade the restricted ceilings make.
320366 */
321367const HARD_CAPPED_REASONS : ReadonlySet < string > = new Set ( [
322368 'restricted_country' ,
369+ 'elevated_country' ,
323370 'privacy_egress' ,
324371 'flagged_email_domain' ,
325372 'third_party_client' ,
@@ -391,12 +438,20 @@ export interface FreebuffSpendCeilingInput {
391438 /** The trust matrix's ceiling, when that rollout is enforcing. */
392439 trustLevelCeilingUsd ?: number | null
393440 /** Overrides, all optional so a missing env var changes nothing. */
441+ /**
442+ * True when the account holds a live paid plan (Postgres-entitling row —
443+ * never a mirror; see the coercion rule in triggerGates). Resolved LAZILY
444+ * by the caller, only when the cohort ceiling would refuse: the ordinary
445+ * request must not pay a subscription read to learn a ceiling it is under.
446+ */
447+ hasPaidSubscription ?: boolean
394448 overrides ?: {
395449 regionUsd ?: Partial < Record < FreebuffAccessTier , number > >
396450 restrictedUsd ?: number
397451 restrictedCountries ?: readonly string [ ]
398452 elevatedUsd ?: number
399453 elevatedCountries ?: readonly string [ ]
454+ paidFloorUsd ?: Partial < Record < FreebuffAccessTier , number > >
400455 }
401456}
402457
@@ -462,6 +517,18 @@ export function resolveFreebuffSpendCeiling(
462517 if ( candidate . usd < winner . usd ) winner = candidate
463518 }
464519
520+ // The paid floor, AFTER the minimum: it may only raise. The reason keeps
521+ // naming the cohort that was floored — a support question about a paid
522+ // account still deserves the one-word answer for why it isn't higher.
523+ if ( input . hasPaidSubscription && PAID_FLOOR_REASONS . has ( winner . reason ) ) {
524+ const floor =
525+ input . overrides ?. paidFloorUsd ?. [ input . accessTier ] ??
526+ FREEBUFF_PAID_DAILY_SPEND_FLOOR_USD [ input . accessTier ]
527+ if ( typeof floor === 'number' && floor > winner . usd ) {
528+ return { usd : floor , reason : winner . reason , applied }
529+ }
530+ }
531+
465532 return { usd : winner . usd , reason : winner . reason , applied }
466533}
467534
0 commit comments