Migrating to Antigravity 2.0 Without Stopping Your Automation: Parallel-Run and Rollback Design
How to move to Antigravity 2.0 without breaking running automation: how to set up a parallel-run window, verify output parity, pin versions, and keep a one-command rollback path, based on migrating four sites one at a time.
On June 18, the Gemini CLI and the Gemini Code Assist IDE extension stopped accepting requests, and the migration path consolidated onto Antigravity. If you only touch the editor by hand, this is just a matter of getting used to a new screen.
The problem is when you have the CLI wired into scheduled jobs. As an indie developer, I run daily scheduled article generation and deploys across four blog sites, so a migration with a hard cutoff date became an operations problem: not "when do I learn the new UI" but "how do I move a running process without stopping it."
Here is the sequence I actually followed to move to a major upgrade without taking my live automation offline.
A migration with a deadline is a parallel-run, not a switch
The most dangerous way to handle a deadline migration is to flip everything the day before the cutoff. The first job you ever run in the new environment ends up being that day's production run. That is exactly the situation to avoid.
I do not think of migration as "swap from old to new on a given day." I design it as an overlapping process: run old and new side by side for a fixed window, confirm the outputs match, and only then retire the old path.
Whether you can afford a parallel-run window almost entirely determines how safe the migration is. Once a deadline is announced, I work backward first: when do I need to start the parallel run so that I get enough comparison cycles before the cutoff?
During the parallel run, check only one thing: are the outputs the same
Boiled down, there is a single signal to watch during the parallel run. Given the same input, does the new environment produce the same artifact the old one did?
In my case, the final artifact of the article pipeline is the MDX file plus the pass/fail result of the quality gates. So I compare at the artifact level. I hand the same topic to both environments and diff the generated MDX mechanically.
# Feed the same input to old (gemini) and new (agy), then compare artifactsINPUT="content/_fixtures/sample_topic.json"gemini run generate --input "$INPUT" --out /tmp/out_oldagy run generate --input "$INPUT" --out /tmp/out_new# Check that frontmatter structure matchesdiff <(grep -E '^(title|slug|category|level|premium):' /tmp/out_old/*.mdx) \ <(grep -E '^(title|slug|category|level|premium):' /tmp/out_new/*.mdx) \ && echo "OK frontmatter parity" || echo "WARN frontmatter drift"# Check body length has not drifted wildly (aim for within ±15%)OLD=$(wc -m < /tmp/out_old/body.txt); NEW=$(wc -m < /tmp/out_new/body.txt)echo "old=$OLD new=$NEW ratio=$(awk "BEGIN{printf \"%.2f\", $NEW/$OLD}")"
The prose itself changes every generation, so I do not demand a character-for-character match. What I check is structural parity: are the required frontmatter fields present, is the body length within range, does it pass the same quality gates. When those three line up consistently, I treat the outputs as practically equivalent.
✦
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 1–2 week parallel-run procedure that verifies output parity before cutover
✦Version pinning and a one-command rollback path for when an upgrade breaks your setup
✦The actual order I used to migrate four scheduled sites one at a time, and why
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.
Just as important as the parallel run is the way back. Before I start the migration, I make sure I can return to the old environment within minutes if something goes wrong after the switch.
The easy mistake here is deleting the old environment. "I've migrated, so the old one is unnecessary" — uninstall it early and you cannot return when you need to. I keep the old environment around until a week after the parallel-run window ends.
Rollback should be reduced to a single command, not a written checklist.
# The scheduled runner always calls a stable name; swap only the target# Cut over to the new environment:ln -sfn "$(which agy)" /usr/local/bin/site-runner# Roll back to the old environment instantly:ln -sfn "$(which gemini)" /usr/local/bin/site-runner
The scheduled tasks always call site-runner, and I swap only the target with a symlink. Both cutover and rollback become the same one-liner, so even if a late-night automated run misbehaves, returning to yesterday's state is just resetting the link the next morning.
Pin versions so the environment does not break under you
In the early days of the 2.0 move, several developers reported that the update changed their whole setup at once. In a major upgrade, tool behavior and defaults can shift without you noticing, and a job that passed yesterday fails quietly today.
The best defense is to pin versions explicitly. During migration verification I pin the new environment's version and keep it off auto-update until I am done.
Here is what to pin and why.
Target
What happens if unpinned
What to do
CLI version
An update changes flags or the default model and jobs fail
Pin during verification; apply updates manually
The model you call
It silently switches to a new model and output shifts
Name the model explicitly; do not rely on the implicit default
Config file location
Migration changes the config path and old settings are ignored
diff the actual config files before and after migration
Pinning is not a permanent policy. It is a safety device just for the verification window. Once output parity is confirmed, I unpin and return to normal update operations. Reverse that order and the changes from migration and from updates blur together, leaving you unable to isolate the cause.
The order I used to migrate four sites one at a time
I did not migrate all four sites at once. Moving everything to the new environment simultaneously means that if something breaks, all four operations stop at the same time. To keep the blast radius small, I moved them in order of least impact first.
The actual order was:
Move the lowest-update-frequency site to the new environment and parallel-run for a week, comparing outputs
If clean, move a mid-sized site where problems would be easy to notice next
Retire the old path for any site whose artifacts matched the new ones three times in a row
Move the highest-frequency, highest-impact site last
Keep the old environment for a week even after all sites have moved, then delete it once no surprises appear
The point of this order is to make the first site a practice run. The pitfalls you hit on the first site you will usually hit on the rest. Lock in the fix on site one, and sites two onward become a matter of repeating the same steps, minimizing the impact on production.
How I decide not to rush a migration
Once a deadline is published, it is tempting to move everything quickly and be done. But the goal of a migration is not "make the deadline" — it is "keep operations running."
I will not fully migrate live automation to the new environment while any of the following is true: fewer than three parallel-run comparisons completed; rollback is not yet a single command; the old environment cannot be summoned back instantly. I treat those three as the minimum conditions for a safe migration.
Conversely, when all three are in place, you can switch calmly even right at the deadline. The faster you rush across a major upgrade in one leap, the higher the cost when you cannot get back. Build an overlap, secure the return path, and break it in starting from the lowest-impact place. It looks slow, but for an indie developer with live operations to protect, I find it ends up being the fastest migration. If you also run scheduled jobs, I hope this helps.
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.