One morning I opened App Store Connect and noticed that the English screenshots for a wallpaper app I had been shipping for five years were still showing a UI from six months ago. I had quietly refreshed the Japanese set after the iOS 26 redesign, but the English locale had drifted four versions behind. I was running Apple Search Ads against that English listing at the time, so the 18% month-over-month drop in CTR was not exactly mysterious.
This is the kind of drift that happens almost guaranteed if you are an indie developer running several apps in parallel. I have been shipping apps since 2014 — roughly 50 million cumulative downloads by now — and localized screenshots have always been the first thing to slip. When I started using Antigravity's Background Agent for release-time monitoring, I decided to also hand it the multilingual screenshot refresh. This article is a five-week operations log: what I let it do, what I kept on my own desk, and why.
Why I Reduced the Scope From "End-to-End" to "Prep Work Only"
Both of my grandfathers were temple carpenters, and one habit I picked up from them is that the final pass should be done by a human hand. In the first week I got greedy and wrote a job that would pick the lead screenshot, translate the copy, render every locale, and push everything straight to Connect. I rolled that back almost immediately. Design judgment — which cut goes in slot 1, whether the English copy's rhythm matches the Chinese — is not something I'm ready to fully delegate to an agent yet.
After five weeks the boundary settled here:
- Prep work — per-device renders, layer alignment, character-overflow detection per locale — goes to the Background Agent
- Lead visual selection, copy tone, and final approval stay with me
Once I drew that line, my own time on this task collapsed to roughly 90 minutes on a Sunday morning.
The Skeleton of the Job
The definition I'm passing to Background Agent looks roughly like this. I've trimmed it to the load-bearing parts; the real one is close in shape.
# antigravity/agents/appstore-screenshots-weekly.yaml
name: appstore-screenshots-weekly
schedule: "0 4 * * SUN" # Sun 04:00 JST
inputs:
apps:
- { bundle_id: jp.dolice.wallpaper.zen, locales: [ja, en, zh-Hans, zh-Hant, ko, es-MX, fr, de] }
- { bundle_id: jp.dolice.wallpaper.dark, locales: [ja, en, zh-Hans, zh-Hant, ko, es-MX, fr, de] }
- { bundle_id: jp.dolice.wallpaper.mind, locales: [ja, en, zh-Hans, zh-Hant, ko] }
- { bundle_id: jp.dolice.wallpaper.kid, locales: [ja, en, zh-Hans, ko] }
tools:
- fs.read_master_psd
- text.translate # uses my glossary
- image.render_screenshot # renders PNG with device frame
- asc.list_localizations
- notify.slack
steps:
- id: detect_master_diff
run: fs.read_master_psd($app.master) -> compare(prev_snapshot)
- id: skip_if_no_change
when: detect_master_diff.changed == false
run: notify.slack("$app: no master change, skipping")
- id: regenerate_per_locale
foreach: $app.locales
run: |
text.translate(source=$app.master.copy, target=$locale, glossary=$app.glossary)
-> image.render_screenshot(device=[iPhone-6.9, iPhone-6.5, iPad-13])
- id: report
run: notify.slack(diff_summary + warnings)The shape is: only act on weeks where the master PSD changed; report results to Slack so a human can decide whether to push to Connect. The asc.list_localizations step is there to pull the current locale list for diffing; the write-back step (asc.upload_screenshot) is intentionally absent. The next section is why.
Three Reasons I Pulled Auto-Upload Out
I had auto-upload turned on in week one. By week two, an English caption shipped with a half-finished phrase ending; I caught it on the metadata screen before review, but only just. I removed the write-back step right after, and the reasons I wrote down were:
- Copy rhythm still belongs on the human side. I have been technically open to new things since I taught myself programming in 1997, but I don't think we're at the point where the cadence of a one-line caption can be fully delegated.
- Rollback on Connect is expensive. Once a screenshot is overwritten on Connect, reverting requires a manual re-upload. Catching a bad overnight job in the morning becomes a heavy chore.
- Apple Search Ads timing matters. When I change a screenshot, I often want to nudge the corresponding keyword bid at the same time. Letting a human review both as one change makes attribution easier to read later.
What Actually Broke Across Five Weeks
A few concrete numbers. Four apps × up to eight locales = 32 sets, run five times across five weeks, so 160 generated sets total. Of those, 121 were used as-is and 39 needed a human touch-up. The breakdown was roughly:
- Chinese simplified / traditional overflow on portrait devices (ugly wrap on long phrases): 18 cases
- Korean font baseline offset, with the glyph overlapping the lead visual: 9 cases
- Spanish copy nuance (Mexican vs. Spain register couldn't be fully absorbed by the glossary): 8 cases
- Japanese master's line-height not respected by the renderer: 4 cases
The Chinese overflow problem was something the agent could absorb if I added a validation step — I bolted that on in week three. The Korean baseline issue depends on per-device font rendering and turned into a "check by eye" rule. The boundary I had a vague sense of going in became something I could write down in concrete terms after five weeks.
Why I Kept Reporting on a Single Slack Channel
I kept notifications to one Slack channel because every extra destination becomes another "I'll check it later" pile. My kids live some distance away from me, and the operational rule I wanted to preserve was: once they're asleep, one quiet check on Slack should be enough. I also told Background Agent to keep reports short — bullet only what changed, write "no changes" when the diff is empty.
The report format settled here after a few rewrites:
[Sun 04:18 JST] appstore-screenshots-weekly
- zen: ja=OK en=⚠️ copy end zh-Hans=⚠️ overflow zh-Hant=OK ko=OK es-MX=OK fr=OK de=OK
- dark: ja=OK en=OK zh-Hans=OK zh-Hant=OK ko=⚠️ font height es-MX=OK fr=OK de=OK
- mind: no master change, skipped
- kid: ja=OK en=OK zh-Hans=OK ko=OK
to_review_in_drive: 5 PNGsFrom here I open a review folder in Google Drive and only touch what's flagged.
Closing Thoughts After Five Weeks
This job has become a useful experiment for thinking about where Background Agent really fits in indie development. Week one with full auto-upload was fast but accident-prone. From week two onward — with the write-back step removed — my own time dropped to 90 minutes a week and the accidents stopped. The lesson wasn't "automate everything because it's available." It was that drawing a careful line around what still requires me as the responsible party is itself part of the workflow.
I started weighing visual work more heavily after a particular moment in 2019, when I saw a ring of light above Kichijoji Station — it shifted how I treat my own apps. My screenshots are, to me, an extension of that work. Keeping the final tone and the lead-frame decision on my side is partly about leaving room for that.
The next thing I want to wire together is a single diff view for Apple Search Ads keyword bid changes and screenshot updates, so the two things move in step. If that experiment runs long enough to be worth writing about, I'll post a follow-up.
Thank you for reading. If you're somewhere in a similar boundary problem in your own indie operations, I hope some of this is useful.