Context
Tiers are the retention mechanism of a loyalty program: they give a member something to lose. That also makes them the most emotionally charged feature in the module — a downgrade a member did not see coming is a support ticket and often a churned customer. Two decisions carry most of the weight. The qualification window — rolling twelve months versus calendar year — changes the entire feel of the program: rolling is continuous and fair, calendar creates a year-end push and a January cliff. And the downgrade policy, which needs a grace period not for correctness but because dropping someone the instant they fall below a threshold is a product failure even when it is arithmetically right. This is what status points exist for (ADR-011). Qualifying on redeemable points would mean a member loses status by spending, which punishes exactly the behaviour the program wants.Scope (normative)
loyalty.tier_definitions: ordered levels with thresholds against a qualification metric.loyalty.tier_qualification_metrics: parametric,is_systemseedspoints_earned,spend,event_count.- Window modes
rolling_daysandcalendar_year. loyalty.tier_membershipswith full history: entered, exited, reason.- Explicit downgrade policy with a configurable grace period.
loyalty.tier_overrides: earning multipliers, reward pricing, expiration extension per tier.- Recomputation driven by ledger events, with a scheduled safety net.
Non-scope (normative)
- Tier-based notifications. This feature emits the events; the campaigns are
messaging. - Manual tier assignment by staff — a later console feature with its own audit semantics.
- Tier-gated reward visibility beyond the pricing override, which is FS-LOY-0005’s concern.
Behaviour (normative)
- Tiers are ordered by
level, unique per program, with strictly increasing thresholds. Two tiers at the same level are FORBIDDEN. - Qualification uses the configured metric over the configured window. Redeemable points never qualify: spending must not cost status.
- Upgrades are immediate on crossing a threshold. A member should never wait to receive good news.
- Downgrades are never immediate. The member enters a grace period; if they requalify before it ends, no downgrade is recorded at all. Only on expiry does the downgrade apply and emit.
- Membership history is append-only. A member’s tier at any past date must be reconstructible — this is what answers “why was I charged that price”.
tier_overridesapply at the moment of the transaction, not retroactively. Reaching Gold does not re-price yesterday’s redemption.- Recomputation is event-driven on ledger writes and re-verified by a scheduled job at the
tenant’s freshness tier. Divergence is alerted, never silently corrected.
7b. When the status currency is configured to expire (OQ-LOY-02, FS-LOY-0002), the
qualification metric falls on its own and a member can drop a tier without having stopped
buying. In that configuration the grace period and the
tier.grace_startedevent are mandatory, andmembers/me/tierMUST show the projected drop and its date before it happens. Flexibility that surprises a member is a support ticket, not a feature. tier_qualification_metricsis not tenant-extensible: the metric governs system logic.
Data (normative)
API (normative)
members/me/tier returns the current tier, progress toward the next, and — when in grace — the
date the downgrade would apply. Hiding that date would be the single most user-hostile choice
available here.
Events (normative)
loyalty.tier.upgraded and loyalty.tier.downgraded, both available as outgoing webhooks. Entering
grace emits no event in F1; whether it should is an open question below.
Acceptance criteria (normative)
- Crossing a threshold upgrades within 5 s p95 of the qualifying ledger write and emits once.
- Falling below a threshold starts grace and does not downgrade. Requalifying inside grace records no downgrade at all.
- Grace expiry downgrades and emits exactly once.
- Rolling-window correctness: a member whose qualifying activity is 366 days old no longer counts it, verified against a seeded timeline.
- Membership history reconstructs the tier held on any given past date.
- A tier override multiplier applies to earnings after the upgrade and not to earlier ones.
- Negative: redeeming points never lowers a member’s qualification metric.
Execution
Asynchronous pipeline, driven by ledger events; the safety-net recomputation is a scheduled per-tenant fan-out job.Open questions
None outstanding. Every question this spec carried was answered in the consolidated register (../../../design/open-questions-v1.md, v1.1) and folded
into the normative sections above.