The Business Reality4 min read

Thirteen code reviews passed, and the lie was in the store listing

A final branch-wide review returned two blockers. Neither was code — both were store copy I wrote, and three sentences did not match the app.

#app-store#google-play#honesty#verification#reality-check
Concept diagram: every code review passes while three store-listing sentences contradict the shipped behaviour
A diagram summarising the post.

I reviewed an app's shipping branch. Thirteen task-level reviews all passed, and my own "is this safe to ship" audit concluded: code is fine.

Then I ran one more review over the whole branch. Two blockers.

Neither was code. Both were store copy I had written myself.

When did you last check a sentence in your store listing against the code?

One: "no data is sent anywhere"

That sentence was in the store description across fifteen locales.

In the same session I had filled out a data safety declaration stating that the payments SDK sends purchase history and a device identifier to a server. I ran the actual release build to confirm: that traffic happens on every launch, whether or not anyone buys anything.

The worse part: on the first line of my own checklist for that session I had written "these four must give the same answer." One of the four was saying something different.

Two: "long-press only changes the volume"

The real code enables that behaviour only when the repeat-input count is 1 or higher. And the first event of a long press always has a count of 0.

A documented behaviour was about to ship having never once occurred.

Three: "exactly three permissions"

I opened the actual release package and counted five. One of them — the billing permission — is a permission the store surfaces to users directly.

You get the right answer by reading the built package with an analysis tool, not by counting entries in a manifest by hand.

Why thirteen reviews missed it

A task-level review sees its own diff only. When "write the copy" and "implement the behaviour" are different tasks, nobody ever puts the two side by side.

This was the third time the same shape of mistake happened.

Would you add another review layer, or change the question the review asks?

I changed the question. "Look carefully" catches nothing. The branch-wide review now carries an explicit question: does the copy match what the code actually does?

What became a rule

  • Write the source, not the number. "Three permissions" becomes false the moment a library is added. "Vibration, internet, billing check" is a list that does not age.
  • Distrust negative claims. "Sends nothing," "never does X" — highest verification cost, highest penalty when wrong, because wrong means a false representation.
  • Token rules in the script. If an app links a payments SDK and its copy never mentions the payment source, the checker warns. Cheaper than a human rereading fifteen locales every release. Running that checker across locales then exposed a regex that only worked in English.

Self-check

  • Does your listing state a number? Does that number come from code, or from memory?
  • Does it contain a negative claim? Did you check the place that would falsify it — an SDK, a network call?
  • How many surfaces state the same fact? Store description, data safety form, privacy policy, in-app copy — do all four agree?

The honest part

My audit said "code GO" because it looked at unit tests, static analysis, and bundle size. The app also had an instrumented test suite covering database migration, recovery logic, and the payment gate. The audit never ran it.

Worse: device state I had touched during the audit was making that suite fail. It only went green after I wiped the device database. The "tests are green" confirmation itself came out of a contaminated state.

Pick one negative sentence from your own listing and write down what would have to be true for it to be false. Then go check that.

Related