Sergey Kopanev: you sleep — agents ship

Go Back
AMORE: Acquisition, Monetization, Onboarding, Retention, Engagement · Part 5

No Cognitive Whiplash on Offers


User A cancels their subscription. Fourteen days later, the engine fires a winback push: “50% off your first year. Tap to claim.”

User A taps the notification. The app launches.

At that exact moment, a global Summer Sale goes live. It offers 30% off to all free users. The app boots, the generic campaign engine evaluates first, finds the Summer Sale, and overrides the deep-link context.

User A stares at a paywall offering 30% off.

They close the app. They never come back.

The problem here is not the price. If you had offered them 30% off in the push, they might have bought it. But promising 50% and showing 30% is not a pricing strategy. It is cognitive whiplash. It tells the user your system is either broken, disorganized, or predatory.

Contradictory signals break trust faster than any discount fixes it.

What AMORE Is

AMORE — Acquisition, Monetization, Onboarding, Retention, Engagement — is the retention engine I built for a B2C health app. Previous articles covered grace periods, dormant users, fatigue index, and state voices. This article covers offer conflict resolution.

The Rule of Monotonic Value

Once a price is put in the user’s head during a session, the price can only go down. The value can only go up.

If the engine grants a 50% offer via a push notification, email, or a previous in-app banner, any subsequent offer shown in that session must mathematically evaluate to a better or equal deal. If it is worse, it must be suppressed.

Most monetization engines do not do this. They evaluate rules in a hardcoded priority order, or worse, they let the last-loaded API response win. A personal lifecycle discount collides with a global holiday sale, and the user gets caught in the crossfire.

The Value-Comparison Guard

The fix is a policy engine rule: the Value-Comparison Guard.

To make this work, offers cannot be opaque strings. They must be structured data evaluated against a session-level ledger.

When the user taps the 50% push, the engine writes to local state: session.best_offer_seen = { id: "winback_50", rank: 2 }

When the Summer Sale paywall tries to present itself, the engine checks the guard. The Summer Sale is ranked 4. The guard blocks the render and forces a fallback to the 50% winback paywall.

The Ranking Problem

You cannot just compare percentage strings. Is 50% off the first year better than one month free? Is $10 off a monthly plan better than 30% off an annual plan?

Comparing absolute dollar values across different durations requires assumptions about LTV that the client-side engine cannot reliably make in real time.

Instead, we use a static, absolute rank for offer tiers:

Rank 1: Free (e.g., 1 month 100% off)
Rank 2: Aggressive Winback (e.g., 60-70% off annual)
Rank 3: Standard Winback (e.g., 50% off annual)
Rank 4: Global Campaign (e.g., 30% off annual)
Rank 5: Full Price (Base offering)

The guard logic is strictly integer comparison: if candidate.rank > session.best_offer_seen.rank, drop the candidate.

When Offers Collide

A worked example.

State: free-churned, Day 14. Active Offers: winback_50 (Rank 3), summer_sale_30 (Rank 4).

If the user opens the app organically, the engine evaluates the highest-ranked valid offer. They see the 50% winback.

If they tap a push notification for the Summer Sale (maybe they saw an ad), the deep link attempts to force the Rank 4 offer. The engine catches the collision. It knows they are eligible for Rank 3.

What happens? The engine overrides the deep link. The user tapped a 30% off push and gets a 50% off paywall.

Surprising the user with a better deal is a pleasant anomaly. Surprising them with a worse deal is a betrayal.

The Trade-Off

Cost: The engine must maintain a session.best_offer_seen state that survives backgrounding and memory warnings. You also have to manually rank every offer you create, which adds overhead to marketing ops. The mapping must be universally agreed upon.

Benefit: You stop breaking trust. A user who feels subjected to a bait-and-switch does not just reject the current offer; they churn permanently.

Takeaway

Do not create cognitive whiplash. A worse deal than expected is worse than no deal at all. Protect the user’s mental model of your pricing by enforcing monotonic value.


Next: One offer across ten channels = one narrative line