◉ANTIGRAVITY LABJP
Articles/App Development
▣ App Development/2026-07-09Advanced

Deciding When to Stop a Staged Rollout, Before You Have To — Agents Watch, I Halt

Field notes on building a Google Play staged-rollout watcher with Antigravity. Crash rate as a ratio to baseline, delayed ANR evaluation, and an explicit insufficient_data verdict — with the halt action kept in human hands.

antigravity461staged-rolloutgoogle-play5agent19release-engineering

✦ Premium Article

One in the morning. I had just widened the rollout to 20%.

The crash rate sat slightly above the previous version — 0.44% against 0.31%. Not enough to stop. Not enough to sleep, either. I watched the dashboard for two hours.

By morning it had settled at 0.29%. Overnight traffic had come mostly from a cluster of older devices, and the sample had simply been too small.

Those two hours cost me more than sleep. They exposed something: I had never written down what would make me stop.

Deferring the halt criteria means deferring to fatigue

Working solo on Google Play apps, nobody else watches the rollout. At 1%, 5%, 20%, 50%, you look at numbers and choose: proceed, or pull it.

The trouble is that the choice tracks your own state more than the data. Late at night I lean optimistic. On the morning after a release, still tense, I lean the other way.

When people talk about handing rollout monitoring to an agent, the conversation usually slides toward handing it the halt button too. I drew the line elsewhere.

Let the agent collect and evaluate. Keep the halt action. In exchange, write the stopping conditions down first, in a form the agent can read.

Automate the criteria, not the decision. Follow that order and a two-hour vigil collapses into a ten-second glance.

The first obstacle is sample size, not thresholds

Early stages produce numbers you cannot trust. At 1% exposure my wallpaper apps see roughly 600–900 sessions a day. Three crashes in that window make the rate look alarming.

Read crash rate as a ratio, not an absolute

"Under 1% is healthy" ignores what your app actually does on a normal day. I anchor everything to the previous stable build still serving 100% of users.

If the old build sits at 0.28% and the new one at 0.42%, the ratio is 1.5. If the old build sits at 0.9% and the new one at 1.1%, the ratio is 1.22 — high in absolute terms, but no regression.

I set warn at 1.5x and halt_candidate at 2.0x. Nothing sacred about those numbers. They fall outside the 0.8–1.35 band my last twelve releases moved within.

ANR arrives late

Crashes surface on launch. ANRs surface after someone has actually used the app for a while. In a wallpaper app they appeared only after users had scrolled through dozens of images.

So ANR evaluation waits roughly 12 hours behind crash evaluation. Judged together, an early "zero ANRs" reads as health when it really means "not yet." The classifier from Reading ANR causes from ApplicationExitInfo with an Antigravity triage pass feeds straight into this loop.

Below the sample floor, return "I don't know"

This turned out to be the single most useful piece of the design. Even when a threshold trips, if the window holds fewer than 800 sessions, no verdict is issued.

The agent returns insufficient_data and stays quiet until the next poll. Giving it a third answer beyond yes and no eliminated every false halt I had been suffering.

✦

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
✦A three-state verdict: warn at 1.5x baseline crash rate, halt candidate at 2.0x
✦Why an explicit insufficient_data return below 800 sessions removed every false halt
✦A four-stage gate keyed to exposure volume rather than clock time, with numbers from four releases
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 $15 for lifetime access
View Membership →

Related Articles

▣ App Dev2026-08-31
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.
▣ App Dev2026-08-18
Ordering Six App Updates for the API Level 36 Deadline, and Sizing Each Staged Rollout
Google Play's API level 36 requirement lands on every app you own with the same date. When the deadline is fixed, the only thing left to decide is the order. Here is how I ranked six apps by fragility and worked each rollout step backwards from the observations I actually needed.
▣ 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.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links