Skip to main content

EngineeringCodeCross Team

Harden an a0.dev MVP before paid traffic (2026)

A 2026 wrap-in-place playbook for founders still shipping from a0.dev chat: rank the blast (keys in prompts and git, web preview or QR as the ad origin, Convex or Supabase data gaps, unreviewed Generate & Submit, no CI, no store or OTA rollback), prove the doors before ads, then decide stay-harden vs leave.

Engineering

14 min

Secrets
Host vault

Not chat or git

Origin
Store build

Not preview QR

Ads
After

Proof first

Citation-ready definition: a0.dev is an Expo / React Native chat agent. You prompt screens. A web preview runs react-native-web beside the chat. View on your Phone prints a QR for the a0 app or Expo Go. That is a lab. Deployment can Generate & Submit an IPA to App Store Connect, or push an Over the Air update from New Update. A key in chat, a committed `.env`, or a Firebase service account in git is a live key. A new chat keeps files and builds. It does not undo a live OTA. Ads wait until org store seats, host-injected secrets, and a stranger test on a native build hold.

This note is from CodeCross (Austin registration, Pakistan engineering on a US Central overlap). Cousin tools sit on vibe coding. Buying help is the Austin app development company page. If nobody can name a store or OTA rollback tonight, use book a conversation.

Money leaves when the campaign still lists a shared web-preview link, a View on your Phone QR, or a key that lived in a0 chat. A stranger can read a Convex row because the generated function never asked who you are. Anyone with the project can hit Generate & Submit. The only undo is “open a0 and prompt it back.” A green react-native-web panel is not a stranger test on the binary you would put on a billboard.

This essay is the pre-ads wrap while the app still depends on a0-assisted generation. It expands Harden a public a0.dev app before campaigns. It is not the first useful ship on a0.dev to production, not the runtime exit on get off a0, not the extract on migrate from a0, not the overlap week on transition from a0. Cousin wraps: Windsurf, Bubble, Framer, Softgen, Lovable, Replit, v0, Bolt. Those pages are not this Expo week. The question here is narrower: can you buy a click while a0 still owns preview and the agent still writes the tree? When chat secrets, the public origin, or the off switch is still red, book.

The punchy lists live on the landers. a0.dev MVP hardening is the clipboard for this week. a0.dev to production is preview-is-not-a-ship-path. Get off a0 is the runtime exit. Migrate from a0 is extract. Transition from a0 is the overlap week. The vibe coding hub maps cousins. This essay is the pre-ads proof on an a0-built Expo tree.

Stay in a0. Close the doors first.

a0 is paid to make the chat finish a screen tonight. Paid traffic is paid to send strangers at a public binary or URL. Those jobs collide. A green web preview can still leave a key in chat, a QR as the public origin, or a Generate & Submit from an open project seat.

a0’s own docs draw the line. Writing prompts is how the agent edits the tree. One goal per message. The files stay in the project. New chat resets only the talk. It keeps app files, builds, App Store Connect setup, Supabase connections, and published versions. That is a workshop, not a host. It stays a lab until ads, mail, Auth, and store listings print the name you mean to keep.

Testing overview splits four methods. Web preview is instant and has no native features. The a0 mobile app is iOS UI with no payments. Expo Go is Android UI with no payments. Native IPA or APK is the only path where payments work. You do not need a new builder this week. You do need to name who can Generate & Submit, who holds secrets, and which origin ads will hit.

Rank the blast. Ads make a small leak big.

Start with the blast, not a prettier chat restyle. A stranger who dumps a Convex table, burns a paid API from a public function, or clones a Firebase service account from git will cost more than a new landing screen. Rank those doors. Close the worst one tonight.

Blast rank — close the a0.dev top layer first

  1. Off switch and restore

    A prior TestFlight or OTA you can republish — not a new chat on one laptop.

  2. CI absent

    Install and start only work inside an open a0 chat. No clean-checkout native build.

  3. Unreviewed agent diffs

    Anyone with the project hits Generate & Submit or New Update. No pull request. No protected main.

  4. Auth and data access on Convex or Supabase

    Demo login. Open queries. No ctx.auth check. RLS off. Admin hidden only in the UI.

  5. Web preview vs QR vs store origin

    Ads, mail, sitemap, and Auth redirects that still print a preview host, a View on your Phone QR, or Expo Go.

  6. Secrets in chat, prompts, and git

    Keys in a0 transcripts, .a0 files, a committed .env, or a Firebase service account JSON.

Ads multiply whatever is already open. A web-preview click does not seal secrets. A QR share does not retire the lab. “We will prompt a0 again” is not a store or OTA off switch.

Put six names on paper: who owns secrets, who proves login on the advertised binary, who can Generate & Submit, who watches spend and errors, who owns the public origin, and who can restore a prior store or OTA ship tonight. Two red names plus a campaign date means spend stays off. If you cannot name a human for each layer, book.

Secrets: if the chat saw it, treat it as leaked

Keys are the first thing ads will leak. The agent reads what you paste. Writing prompts asks for specific details. Founders then paste Stripe keys, Convex URLs, and Apple Team IDs into the same thread. A new chat does not wipe those words from history you already shared. Rotate anything that sat in plain text.

Android FCM setup is the vendor example to keep. `google-services.json` is public config. The Firebase service account key is not. a0 says store that JSON securely and do not commit it. Upload it under Project Settings → Build Settings → Android Credentials. A key the agent wrote into the tree is now in git history if you exported the repo.

a0 apps often sit on Convex. Convex environment variables belong on the deployment, not in a client file. Set them in the Convex dashboard or `npx convex env set`. Dev and prod can hold different values. Declare expected names in `convex/convex.config.ts` so a missing key fails at deploy. If the stack used Supabase instead, row level security is a later door. The secret door is the same: no service-role key in the app bundle.

Secret scanning will scan that history for known key shapes. Rotate first. History cleanup is extra work after the issuer is dead. Using secrets in GitHub Actions is the CI drawer you want if you stay and grow a repo. EAS environment variables is the Expo drawer if owned EAS already exists: set values on the project, not in `.env` the agent just wrote. If the only place the key still lives is an a0 thread you are afraid to open, book.

a0 gives you several addresses that look live. They are not the same job.

Three live origins — only one is the ad target

  1. 01 · Web preview

    Lab

    react-native-web beside chat. No camera, push, or payments.

  2. 02 · QR / a0 app / Expo Go

    Device lab

    View on your Phone. Hot reload. Payments still fail.

  3. 03 · Native IPA or APK

    Ads

    TestFlight, Play internal, or store listing. The only public origin.

A web preview is the lab. A leftover QR or Expo Go share is a second origin. Production is the store binary or claimed scheme you buy ads for. Mixing them is how the chat becomes the company.

Web preview is the lab: a react-native-web copy next to the chat. Console logs land in the browser. The same page lists what it cannot do: camera, biometrics, push, native modules. Some libraries will not run on web at all. That is workshop evidence. It is not a campaign URL.

Mobile app testing prints a QR. The a0 app opens on iOS. Expo Go v52 opens on Android. Hot reload stays up until you refresh the page. Payments show a UI and then fail. Ad networks fail. That is expected. Native build testing is the other door: Deployment → Create a IPA/APK. Payments only work there. Stay-harden is fine if ads, mail, sitemap, and Auth print the store or claimed scheme. It is not fine if the campaign still lists a preview link or a QR.

Search the tree for leftover preview hosts, Expo Go notes, and `myapp-dev` schemes. Deep links live in `.a0/build.yaml`. Mail, reset, and “view app” links must use the production scheme — not a personal preview URL. The pre-submission checklist still wants real-device proof and a privacy URL you own. Using `https://a0.dev/privacy` is a start. It is not your company policy.

Auth and row rules: a hidden admin screen is not a gate

Rows are the next thing ads will leak. a0 is good at wiring a sign-in screen. It is weaker at naming who may read a row after that screen. Push docs show the default backend: push notifications send from Convex. `convex/notifications.ts` is an internal action. Only server functions should call it. A query the agent left public is a read API.

Auth in Convex functions is the server gate. `ctx.auth.getUserIdentity()` returns null when no one is signed in. You must throw. Convex will not guess. Storing users is the next step: keep a users table, then use that id as a foreign key. A list query that returns every document is open to any caller who found the function name. If the agent stood up Supabase instead, row level security is that same seat list. A table without RLS is open to any role with a grant.

A demo login that only works inside web preview is a costume. The advertised binary must sign a stranger in. Logout and expiry must work after a hard refresh. Admin must be a server check, not a role the agent mixed into a client file. OAuth, magic links, and reset mail must land on the production scheme — not a preview host.

Run these four checks on the advertised binary. A preview pass with your a0 session does not count:

  1. Every Convex function or Supabase table that holds personal data or money checks identity, and public grants are named. A hidden admin route is not that proof.
  2. A stranger account cannot read another user’s row by changing an id in the URL or the API.
  3. Sign-up and sign-in work on the store or claimed scheme. Preview success is not that proof.
  4. Service-role, admin, or Firebase private keys never shipped to the client. Those keys skip row rules.

Unreviewed a0 diffs are a write API on your ship path

The agent can change many files in one prompt. Writing prompts is built for that. Two people in the same project can race. A new chat keeps the files they already shipped. That is a laptop undo. It is not branch protection.

Deploying your app is one click: Deployment → Generate & Submit. The IPA appears in App Store Connect in about ten minutes. Deploying updates is the faster click: New Update. Installed apps pick up the JavaScript when they reopen. Anyone who can open that modal can change what customers run. That is the a0-shaped leak Windsurf’s Turbo push is not.

About protected branches is the remote lock if you already have an org repo. Require reviews. Require status checks. Keep force-push off. Restrict who can push to `main`. An a0 commit from one chat is not that lock. If every collaborator can still Generate & Submit, ads wait.

Payment setup is the other write path. The agent can edit `.a0/monetization.yaml` and trigger provider sync. Apple payments do not work in the a0 app or Expo Go. Sync to Stripe or App Store Connect is live config. Restrict who can open Payments and Deployment. Keep Team ID and Play consoles under org admins.

Off switch: a new chat is not a host rollback

A bad release needs an off switch you can name tonight. New chat resets talk and keeps builds. It does not take a live TestFlight or an OTA back.

OTA overview says you can fix bugs without App Store review. Upgrading your project is the limit: OTA only works inside the runtime the binary was built on. As of 18 November 2025 the latest a0 runtime is Expo SDK 54. A runtime bump needs a new store binary. “We will open a0 and undo the prompt” waits on one laptop and one agent. It is repair. It is not an off switch.

Name the deploy owner. Prove you can restore a prior TestFlight, Play internal, or OTA. A feature flag is extra. It does not replace a version you can republish in minutes.

Watching: errors, spend, and a silent preview

Watching without an off switch is half a lock. Before ads, name three signals: auth failures on the advertised binary, 5xx or Convex errors after a New Update, and paid-API or store spend. Payment setup will not work until you sync plans. That is vendor config, not your product meter. If nobody owns the first 24 hours of spend, the campaign stays off.

A clean checkout is the other watch. Clone the org remote on a machine without a0. Install. Build a native binary with host-injected secrets. If that path fails, a0 is still the runtime. CI/CD after an AI builder is the later essay. This page only asks: does a second machine boot without an open a0 chat?

Wrap score — mark costume vs proof

Secrets

  • Costume

    Key in chat

  • Wrap

    Moved to host env

  • Proof

    Rotated + not in git

Public name

  • Costume

    Ads list a preview QR

  • Wrap

    Store build, old links live

  • Proof

    Scheme + Auth match

Auth / rows

  • Costume

    Hidden admin screen

  • Wrap

    Identity listed

  • Proof

    Stranger cannot find rows

Review

  • Costume

    Anyone can Submit

  • Wrap

    One owner named

  • Proof

    ACL + review on ship

CI

  • Costume

    Only a0 starts it

  • Wrap

    Script in repo

  • Proof

    Clean checkout boots

Off / watch

  • Costume

    “New chat” undo

  • Wrap

    Prior build known

  • Proof

    OTA or store rollback hit

A green web preview is not a wrap. A TestFlight build from Generate & Submit is still an a0 ship — and that is fine for this page if public links no longer print the lab QR.

Score each row against the advertised binary, not web preview. One red cell — a key in chat, a QR in ads, an open Convex query, an open Generate & Submit seat, a start path that needs a0, or a rollback you have never hit — is enough to hold the spend. Move that cell. Do not greenwash the matrix.

The pre-ads week

Treat the next seven days as operator time on the a0 project, not a slogan. Inventory who can Generate & Submit, who holds secrets, and which origin ads will hit. Then seal. Then prove. Leave the editor-exit pages closed until that list is honest.

Harden on a0.dev — seven operator steps

  1. 01 →

    Inventory the public path

    Who can Submit. Who is admin. Which origin ads will hit. Where a0 secrets still live.

  2. 02 →

    Seal secrets

    Drain chat, prompts, committed env, and FCM JSON. Rotate. Host-inject the new values.

  3. 03 →

    Lock auth and rows

    Stranger cannot find another user’s row. Login works on the store binary.

  4. 04 →

    Lock Deployment

    Named owners only. No silent New Update. Review before Generate & Submit.

  5. 05 →

    Fix the URL map

    Redirects, Auth callbacks, deep-link schemes. No preview or QR in ads.

  6. 06 →

    Name CI and watch

    Clean checkout builds. Who sees 5xx, auth fails, and paid-API spend.

  7. 07

    Rollback + watch, then buy

    Prior TestFlight or OTA restored once. Then spend.

Do not buy ads in step one. Do not start the builder exit while a wrap step is red. Pair with the a0.dev MVP hardening lander.

Day 0 is inventory. Write five facts. The public origin. The person who can Generate & Submit. Whether a live key still sits in a0 chat or git. Whether a stranger can read another user’s row. Whether a prior store or OTA ship can come back tonight. If the public origin is already taking leads and you cannot name those five, stop. You do not need a new screen. You need this list.

Seal secrets first. Then rows. Then review. Bots do not wait for App Review. If a public Convex function exists, prove it fails closed without a session. Then strip preview hosts and leftover QR shares. Then restore a prior TestFlight or OTA once so you know the off switch works. Then spend. The a0.dev MVP hardening clipboard is the short list. This page is the week you run it.

Illustrative operator days before an a0.dev ad buy

days

Unpriced Ads on a red list

3–5 wks

Campaign live. Doors still open. Cleanup later.

08162432Studio-observed calendar (not a bid, not a vendor SLA)Day 0–1Inventory + seats1 dayDays 1–3Secrets + vault1–3 daysDays 2–5Auth, rows, review2–5 daysDays 3–7Origin + rollback3–7 daysUnpricedAds on a red list3–5 wks

Illustrative operator days — not measured traffic, not a Source: Admin analytics series. Unpriced feature sprints on a public a0 app often cost more than the wrap when the first leak hits.

Reserve these days before paid traffic. Overlap is allowed. Skipping inventory to “buy a small test” is how the preview QR becomes the company.

Treat those bars as calendar you reserve, not a vendor promise. If you cannot name the advertised origin, who can Generate & Submit, and who can restore a prior ship, the later days will thrash. The long bar is the expensive miss: a “small” test while a preview QR or an open Convex query is still the company.

Stay-harden vs leave. Do not mix the seats.

Pick one seat for this week. Stay-harden keeps a0 as the studio, with secrets out of chat, a store binary as the origin, locked Deployment, and a rollback already proved. Leave opens get-off a0 and stops buying clicks that need that chat window. Running both seats at once is how teams rebuild screens they already had.

Stay-harden vs exit — pick one seat

Stay-harden (this page)

  1. Studio still in a0

    Chat still plans. You accept the agent and the bill.

  2. Doors closed on that path

    Secrets, origin, auth, review, CI, rollback.

  3. Ads wait for green

    A red layer pauses spend, not the product.

If the public origin must leave a0 preview and Deployment, stop this wrap and open the exit. If ads are close and the origin can stay on a store binary you control, finish the wrap first. ↓

Leave (other pages)

  1. Process leaves a0 preview

    Org Git plus EAS or CI you run. See get-off and migrate.

  2. A TestFlight build is not the exit

    Generate & Submit is still that vendor path until CI owns ship.

  3. Kill the a0-only ship

    App still answers when the chat is closed.

This article is the left column. Get off a0 and migrate from a0 are the right. To-production is the first owned ship. Do not paste them here.

If you only need a leave date, use when to leave an AI builder. A door that will not close belongs on rewrite vs harden. A personal Git remote belongs on GitHub handoff. A laptop-only ship path belongs on CI/CD after an AI builder. Cousin wraps: Windsurf, Bubble, Framer, Softgen, Lovable, Replit, v0, and Bolt. Those pages are not this Expo week.

Wrap loop — prove, then decide

  1. 01

    Prove the door

    One layer. One test on the advertised binary.

  2. 02

    Close it

    Rotate, redirect, add identity checks, lock Submit, or restore a prior ship.

  3. 03

    Re-check ads list

    If a layer is still red, spend stays off.

  4. 04 · loops

    Stay or leave

    Green wrap can stay. Red host row opens the exit.

Do not buy ads inside the loop. Do not leave a0 inside the loop. Exit the loop when the wrap is green or the ship path must move.

When the list turns red

Leave the product up. Kill the campaign if any of these are still true:

  • A live key still exists only in a0 chat, a prompt, a committed env file, or a Firebase service account in git.
  • A Convex function or table that holds personal data or money is still readable without a named identity check.
  • Ads, mail, or the sitemap still list a web-preview host, a View on your Phone QR, or Expo Go.
  • Anyone with the project can still Generate & Submit or push New Update.
  • The app will not boot from a clean checkout with host-injected secrets.
  • The off switch is “we will start a new chat,” or you have never restored a prior TestFlight or OTA.
  • Two people disagree about who can Submit or who holds admin.

A single red door is a miss, even if web preview is green. Stop adding screens until secrets, row rules, locked Deployment, and the rollback are honest. Finish that wrap. Then spend — or open get-off a0 if the chat is still the company.

Bring a second pair of hands when the founder cannot rotate a key without pasting it back into a0, when a stranger can still find another user’s row, or when nobody has restored a prior ship before the date. Hire for secrets, Convex or Supabase locks, Git seats, and the URL map — not a prettier a0 screen. Austin app development company is the studio brief. Austin mobile app development if the next door is a store binary that still points at this a0 URL.

Next steps

Walk the gates in order. Inventory the public origin, the person who can Generate & Submit, and who holds admin. Drain a0 chat and committed secrets into host env. Rotate anything that appeared there. Fail-close identity checks on every Convex function or table that holds personal data. Lock Deployment. Strip preview hosts and leftover QR shares from ads, mail, sitemap, and Auth. Prove a clean checkout. Restore a prior TestFlight or OTA once. Then buy the click — or open the exit if the process itself must leave a0.

CodeCross LLC is an Austin-registered product studio (1606 Headway Cir STE 9212, Austin, TX). The a0 week we run is chat-and-git secrets, store-binary origin, auth and row locks, locked Generate & Submit, then a store or OTA rollback. The Austin app development company page is the studio brief. Austin mobile app development is the store-binary door if a signed build still points at this a0 URL. Company-level evidence lives on proof. When the off switch, secret drawers, or the advertised origin is still red, book a conversation.

a0 is allowed to stay the studio. Ads are not allowed to treat a web-preview pass, a QR share, or an unreviewed Generate & Submit as that proof. Show a prior TestFlight or OTA you can restore, functions that fail closed for strangers, and keys that never lived in a0 chat. Most teams never need a second codebase once those three exist.

FAQ

When web preview looks good, did the store binary receive the same data?

No. Web preview opens a react-native-web copy. Native build testing builds a separate IPA or APK. Local rows, laptop env, and a warm a0 session do not move with that click. Camera, push, and payments are unsupported in preview. Prove the money path on the advertised binary with stranger-like accounts.

Does Generate & Submit finish the wrap?

No. Deploying your app puts an IPA in App Store Connect. That is a ship path, not a wrap. Stay-harden is fine if ads, mail, sitemap, and Auth redirects print the name you mean to keep. It is not fine if the campaign still lists the lab QR. Leaving a0 as the ship path is the get-off job, not this page.

If preview can find a row, does that search exist on the advertised binary for a stranger?

Not as proof. Your a0 session is not a stranger. Auth in Convex functions applies in the function, not in a hidden screen. A preview pass can look closed while a public query still returns every document. If the stack is Supabase, row level security is the same rule. Prove a private-window account on the advertised binary cannot find another user’s row.

Can I paste keys into a0 prompts and buy ads?

No. Writing prompts is how the agent sees the tree. Android FCM setup already says the service account key must not sit in the repository. Convex environment variables belong on the deployment. Rotate anything that appeared in chat or git. Do not buy ads on a red drawer.

Does hiding the admin screen stop a stranger from writing Convex rows?

Hiding a link is not a lock. Function auth and grants govern read and write. A public Convex mutation the agent wired with no identity check is a write API. A service-role or Firebase private key in the client skips those rules. Auth in functions is the seat list. A shared admin login is a miss.

Is “we will start a new chat” an off switch?

No. New chat resets conversation history and keeps files, builds, and published versions. It does not republish a host. OTA updates and a prior TestFlight are the real undo. Name the deploy owner. Hit a prior version once before ads.

Does a green web preview plus New Update mean ads are safe?

No. Testing overview says web preview has no native features. Deploying updates pushes JavaScript to every install that reopens the app. OTA limits still pin that ship to one runtime. A green preview on one machine is a lab. Lock who can New Update. Require a native stranger test. Then talk about spend.

Book a call

Thirty minutes with a senior teammate — honest next steps.

Ready to price an Austin build?

Bring the problem, the users, and a budget ceiling. We’ll tell you whether an app is the right next spend — and what the first year actually costs.

Prefer writing? Send project details on the contact page.