◉ANTIGRAVITY LABJP
Articles/App Development
▣ App Development/2026-08-31Advanced

Why I took the show-or-not decision away from every dialog

A paywall prompt, a review request and a rewarded-ad confirmation landed on the same frame. Here is how I moved the show-or-not decision out of each dialog into a single gate, how I rewrote the agent instructions as invariants, and how a CI check keeps it that way.

antigravity464android30agent20ui-design3

✦ Premium Article

About a second after launch, the paywall prompt opened. A review request landed on top of it, and a rewarded-video confirmation was queued behind both.

It never reproduced on my test devices. It happened only on devices that had reached the category screen in a previous session, been closed there, and reopened the next day.

This was a real path through the Android wallpaper app I maintain as an indie developer.

Each dialog was correct on its own

All three owned their display conditions locally.

DialogCondition it ownedCorrect in isolation?
Paywall promptLaunch count above threshold, not ad-freeYes
Review requestDays-used above threshold, not yet ratedYes
Rewarded-video confirmationAd inventory loaded, not ad-freeYes

Nothing in that table is wrong. The problem is that every condition answers only one question: "am I allowed to show?" Nowhere in the codebase did anything ask "is someone else already showing?"

Ask an agent to add one dialog at a time and you get exactly this shape, because the spec you hand over is the spec for that dialog. The agent wrote correct code for the scope it was given. What was missing was the cross-cutting condition I never wrote down.

I had already centralised the ad-free value itself, which I covered in where the source of truth for billing state lives. The value was centralised; the decision was not.

Trap 1: conditions do not add up to an ordering

My first instinct was to add "and nobody else is showing" to each of the three conditions.

That does not scale. Three dialogs mean six references, four mean twelve, and every addition requires opening the existing files to extend their conditions. Ask an agent to add one dialog and only that file changes — the other three quietly go stale.

A design that keeps conditions distributed breaks a little on every addition. The failure mode is "occasionally overlaps" rather than "never appears", which is exactly the kind of thing tests do not catch.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦You will be able to look at your own dialog code and decide whether the display rules should stay local or move into one gate
✦You will be able to catch overlapping-modal defects with a CI check instead of waiting for them to reproduce on a user's device
✦You will be able to hand UI work to an agent as invariants rather than as isolated features, so the next dialog does not reopen the same hole
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $10 for lifetime access
View Membership →

Related Articles

▣ App Dev2026-04-03
Antigravity × Capacitor Hybrid App Implementation Guide: An AI-Driven Workflow for Taking a Web App to iOS/Android Native
Implementation notes for taking an existing web app to iOS/Android with Capacitor and Antigravity, drawn from running indie apps. Covers native API integration, AdMob initialization order, launch-time white flash, and pre-submission checks, separating what is verified from what is not.
▣ App Dev2026-10-14
Before Turning Undocumented Code Into a Spec, Decide the Reading Order by Fan-In
When you ask an agent to turn undocumented code into a spec, which files do you hand over first? A 36-line Python script ranks files by import count (fan-in) plus route entry points, with measurements from a 77-file Next.js project.
▣ App Dev2026-10-08
Three Safety Nets to Test with a Fake agy Before Running the Antigravity CLI in a Container
Before you call the Antigravity CLI (agy) from Docker or a Cloud Run job, reproduce three failure modes with a fake agy: an installer that returns gzip, a hang on tool approval, and an exit code of 0 with nothing produced. Everything here rests on official docs and on code I ran myself.