ANTIGRAVITY LABJP
Articles/Agents & Manager
Agents & Manager/2026-05-26Advanced

Splitting Pre-release QA Across Four Antigravity Subagents — A Design Note from a Solo Mobile Developer

A design note from a solo indie developer running six iOS / Android apps in parallel, sharing how Antigravity subagents are split into four parallel paths for pre-release QA. Covers the boundary decisions, prompt templates, termination rules, and merge logic with concrete examples.

antigravity430subagent3qarelease2ios36android27

Premium Article

I am Masaki Hirokawa, an indie developer. I have been building iOS and Android apps on my own since 2014, and these days I operate six apps in parallel — mostly wallpaper, healing, and law-of-attraction style apps. Once cumulative downloads passed 50 million, the workload of a release week became too much to run sequentially. For the last six months I have been pushing on how much of the pre-release QA work I can hand off to Antigravity subagents. This article is the design note that came out of that experiment. The short answer: I split the work into four parallel paths and let four subagents run side by side.

When I ran release weeks sequentially, the order was static analysis first, then Simulator, then asset diff, then store submission review. Each app took about 90 minutes, so six apps was a 9-hour slog. In practice I did most of it late at night, and decision fatigue meant the last checks of the night were always the weakest. Once I handed sliced responsibilities to subagents and designed an explicit merge point, the total time for all six apps came down to about two and a half hours, and the dependence on late-night focus disappeared.

Why four paths

I started with the obvious idea: hand everything to a single agent and let Plan Mode walk through it. Antigravity's Plan Mode is excellent for high-level planning, but for repetitive QA across six apps the context grows too large, and the agent's judgment gets sloppy partway through. On my own setup, by the third app the agent would start saying things like "this is the same as the previous app, so we can skip," and twice I caught it missing a real diff that way.

So I drew the boundaries based on the kind of resource each subagent has to read. If the read surface is restricted, the context stays small. The four paths I settled on are:

  • Path 1: source code and git diff — static analysis and diff review
  • Path 2: built app runtime behaviour — Simulator / Emulator smoke
  • Path 3: assets and localization resources — diff inspection
  • Path 4: store submissions and external configuration — metadata, AdMob, Crashlytics, and so on

These four paths almost never touch the same files. Path 1 reads src/ and app/src/main/, while Path 3 reads Assets.xcassets/ and res/drawable*/. Because the context surfaces do not collide, I can run the four Antigravity subagents in parallel and each one stays focused on its own slice.

Where I had to be careful was the grey area between paths. For example "did the icon get swapped correctly" belongs to Path 3, but "is CFBundleIconName in Info.plist updated" touches both Path 1 and Path 3. For grey-zone items I write a rule up front — Path 1 owns it — so the merge step never has to resolve a contradiction. Having both paths look at the same item sounds safer but actually pushes complexity into the merge prompt.

Path 1: static analysis and diff review

The Path 1 subagent gets the diff from the previous release tag to the candidate commit and looks for risky patterns that might have slipped in. Because my codebase is a mix of Swift, Kotlin, and TypeScript, I split the checklist by language.

These are the patterns that bite most often:

  • New try! or as! in Swift (a frequent crash culprit)
  • New !! in Kotlin (same)
  • Leftover debug output like console.log, print, Log.d
  • Feature flags whose default was flipped to true accidentally
  • UserDefaults / SharedPreferences keys that collide with the previous version

Some of these can be caught by lint, but my lint severity policy varies project by project. "Be stricter only right before release" is not something a lint config expresses cleanly. A subagent, on the other hand, can take a temporary stricter threshold via a natural language instruction.

The Path 1 subagent definition looks like this. Antigravity supports YAML subagent definitions, and I keep mine in a Markdown-ish prompt template per project because I tweak them often.

# .antigravity/subagents/path1-static-diff.yaml
name: path1-static-diff
role: static analysis and diff review
read_paths:
  - src/**
  - app/src/main/**
  - ios/**/*.swift
  - android/**/*.kt
write_paths: []  # Path 1 is read-only
termination:
  on_finding_count_exceeds: 30  # too many findings → switch to manual review
  on_critical_severity: true     # 1 critical → terminate immediately
output_format: json_schema_v1

Here is the prompt template I use when Plan Mode dispatches this subagent. The most important part is pinning the output format. Since four paths get merged downstream, any drift in the output schema explodes the merge logic.

You are the Path 1 subagent. For {REPO_NAME}, evaluate the diff between
{PREV_TAG}...HEAD against the following criteria. Do not suggest anything else.
 
Criteria:
- New force unwraps / force casts (Swift: try!/as!, Kotlin: !!)
- Leftover debug output (console.log, print, Log.d)
- Feature flags whose default is true in the commit
- UserDefaults/SharedPreferences key collisions with prior versions
- Breaking changes to public APIs (function signatures, enum cases)
 
Return only this JSON:
{
  "path": "path1-static-diff",
  "status": "pass" | "warn" | "fail",
  "findings": [
    { "severity": "info|warn|critical", "file": "...", "line": 0, "summary": "..." }
  ],
  "took_seconds": 0
}

I deliberately impose the status rule from outside. fail if any critical, warn if five or more warnings, pass otherwise. When I let the subagent decide its own status, the same project flipped between warn and pass between runs, so externalising the threshold is more stable.

One concrete win that only Path 1 could catch: in one of my wallpaper apps, a piece of code that was supposed to clear the icon cache only in debug builds had an #if DEBUG block that ran past a missing #endif, so the code ran in production too. At the git diff level the only visible change was the position of #endif, and that is virtually impossible to catch by eye.

Path 1 also does one less obvious job: it audits dependency lockfiles. Package.resolved, Gemfile.lock, and package-lock.json sometimes pull in unintended minor bumps, and surfacing the diff here keeps everything in one context window with the code that depends on those libraries.

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
The reasoning behind splitting pre-release QA for six iOS / Android apps into four parallel paths
Prompt templates, termination rules, and JSON output schemas for the four subagents
Merge logic and rollback criteria covering AdMob mediation, dSYM uploads, and store metadata
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

Agents & Manager2026-05-22
Handing Nightly Wallpaper Asset Updates to a Background Agent — Time Budgets, Duplicate Detection, and a Completion Gate
A reproducible account of handing nightly wallpaper asset updates to Antigravity's Background Agent. Covers how to write the task definition, perceptual-hash duplicate detection, one-pass resizing across 12 device profiles, a morning report you can review in five minutes, and the time-budget and completion-gate design that makes unattended runs safe.
Agents & Manager2026-05-18
Splitting Daily Crashlytics Triage Across Five Antigravity Sub-Agents
Running six indie iOS and Android apps, the morning Crashlytics triage was draining me. I split the workflow across five Antigravity sub-agents (Fetcher, Classifier, Repro, Patch, PR) and locked their input and output to JSON schemas. Two weeks of production data shows where the human review boundary belongs.
Agents & Manager2026-05-27
Orchestrating Six iOS App Updates in Parallel with Antigravity's Main and Sub Agents
Running six iOS app updates in parallel — new resolutions, Firebase SPM migration, StoreKit 2, and ATT ordering — with Antigravity's Main + 6 Sub agents. The notes on what to parallelize and what to keep serial.
📚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
See all →