A build appearing in App Store Connect wakes seven agents on Google ADK. They take the app to Waiting for Review with nothing typed. The first real run found a rejection no API field exposes.
I ship iOS apps for a living — fourteen of them on the store. The part of a release nobody talks about is the mile between "the binary uploaded" and "Waiting for Review": name, subtitle, a 100-character keyword field where repeating a word is a wasted slot, screenshots in exactly the right pixel sizes, 175 territory prices, availability, an age-rating questionnaire that grew seven new mandatory booleans this year, review notes with a phone number that needs a country code, and in-app purchases that sit in MISSING_METADATA until you upload a review screenshot nobody told you about.
Last week that mile took me two days. I keep an error index of every rejection and silent trap I've hit — 64 rows. So for this hackathon I built the agent I wanted to have: Shipwright. A build appearing in App Store Connect wakes it (Apple has webhooks now — real push, HMAC-signed). Seven agents on Google ADK take it from there.
LoopAgent. The trick that made it work: the critic's only job is to reject, and it has a deterministic validator as a tool. Without the tool, a second LLM approves 31-character names. With it, the loop converges in one round and the model spends its judgment on claims and tone — the things code can't see.ParallelAgent: fourteen checks, each an error-index row as an API read, with an auto-fix where Apple's API allows one and a one-click operator item where only a web page can do it.DRY_RUN, ALLOW_SUBMIT, and a hard allowlist of app ids. Thirteen of my apps are live; a write to the wrong record is damage.Including two that only exist because I'd done this by hand before: new apps have no price schedule (required even for Free) and no availability (sold nowhere).
And then the one I didn't plan for. I added a Gemini-vision pass over the real screenshots with the app's fact sheet as context. It flagged that the paywall promised "multi-device sync" and a "custom keyboard" — neither ships in this version — and that the sample data on screen one showed a cleartext Wi-Fi password. Both are App Review rejections. Neither is a field in any API.
Code: github.com/byasb/shipwright · 4-minute demo: youtu.be/jGTf0HXESDc
Stack: Google ADK · Gemini 3.5 Flash on Vertex AI · Gemma 4 · Cloud Run · Pub/Sub · Firestore · Secret Manager. #AllThingsAgenticHackathon