Skip to content

Remove the chat ad placement (offers stay on discovery surfaces) โ€‹

Date: 2026-06-15 Branch: claude/remove-chat-offers (off dev) Outcome: Complete. The chat offer placement is fully removed across the stack; offers now live only on hero, inline, and feed surfaces.

Why โ€‹

Lantern's 1:1 chat is end-to-end encrypted and is the most intimate surface in the app. An ad in that thread either breaks the encryption promise (to target on content) or, even untargeted, signals that the private space is monetized and watched. That corrodes the trust the whole privacy architecture exists to earn, for marginal revenue. Offers belong on discovery surfaces (venue listings, hero, inline, feed), where they read as venue hospitality (pull, not push), not surveillance.

Decision: full removal (no dormant code, no re-enable foot-gun) and a full sweep (code, data, docs).

What changed (by area) โ€‹

  • Render path: removed ChatOfferPill (shared @lantern/ui and the admin inline-style copy), its AdSlot routing/label, and all exports; removed the chat-offer fetch and render block from Chat.jsx.
  • Selection + backend: removed SURFACES.CHAT from @lantern/shared/ads; dropped chat from the merchants-api offer placement Zod enum (now hero/inline/feed).
  • Merchant offer form (admin + web): removed chat from the placement constants, the placements picker row and ChatGlyph, the per-placement content doc, and the phone preview (unwrapped the chat-vs-venue ternary, deleted the orphaned phone-preview__chat-* CSS); removed the chat label in OfferDetail; removed the Chat Assist Pill option from the web MerchantDashboard demo.
  • Tests + stories: updated unit/integration tests and the AdSlot story catalog to the 3-placement set (removed the ChatPreview story, the chat grid entry, the chat selection/filter assertions, and the Chat Pill checkbox/preview expectations).
  • Docs: reconciled docs/economics/AD_PLACEMENT_ECONOMICS.md to 3 placements (the chat-assist pill is removed; bundled financial assumptions are flagged for re-baselining rather than silently rescaled); added a "Where Ads Live (and Where They Never Will)" principle to docs/privacy/PRIVACY_PRESERVING_ADVERTISING.md making the ad-free chat a stated guarantee; added deprecation notes to the two offers design specs.

Data โ€‹

Probed the live dev Firestore offers collection for documents with placement == 'chat': 0 found. No data migration or deletion was required. (Read-only probe; no prod touched.)

Deliberately left alone (unrelated uses of "chat") โ€‹

  • The real admin chat assistant UI (lantern-chat-bubble in LanternChat.*).
  • Analytics entityType: 'chat' (chat messages as a trackable entity).
  • Chat-window routing params (?chat=<connectionId>), the initialMood: 'chat' value, and the docs mockup nav.

Validation โ€‹

npm run validate was run from the worktree before opening the PR.

Built with VitePress