Skip to content
Ritesh FirodiyaGet in touch

Work / Chitragupt / Wiki / Decisions

2026-10-02-play-screenshots-come-from-a-sample-build

Decisioncanonicalverified 2026-10-02

DECISION.2026-10-02.PLAY-SCREENSHOTS-COME-FROM-A-SAMPLE-BUILD

Play screenshots are photographed from a build that serves a sample tax year

Decision

The Play screenshots are captured from the running Android app by goldie, from a Release build with EXPO_PUBLIC_SCREENSHOT_MODE compiled in. That build opens signed in as the meera demo persona, on one fixed day, with Firestore offline and answering from a sample written into its own cache.

Three things follow, and each is part of the decision:

  1. The tax figures are the engine's. The sample is a ledger, not a result: the review on screen is what runMode1ForAY computes from it with the verified AY 2026-27 table. A refund or a regime comparison on the store page is a number the product would give that filer.
  2. A scene shows only what the Android app does today. Three are captured: Home, the tax summary with its regime comparison, and transactions. Upload and the CA handoff packet are not, because the app cannot do either — see Why.
  3. A capture build cannot ship. The flag is set by scripts/build-screenshot-apk.mjs and nowhere else, a test fails if it appears in eas.json, app.json, any .env* or any workflow, and the APK is signed with the debug keystore, which Play refuses.

Why

The set in the Play Console was made by hand and was never committed, so nothing could regenerate it and nothing tied it to the app. tier-self prices and the tax position on a screenshot are exactly the things that drift.

goldie reinstalls the app with cleared data before every flow, and the app opens on a sign-in screen that needs a password. The alternative to a compiled-in sample was pointing the capture build at the emulators and the seeded personas. That needs pnpm dev running for every capture, signs in by typing — which argent's keyboard tool does unreliably — and dates everything from the day of the run.

Why offline Firestore rather than a branch per listener: the app reads Firestore from eighteen files. Taking the client offline and writing the sample into its cache makes every listener answer through its own code, with one branch in getFirebaseFirestore. tests/lib/screenshot-firestore.test.ts runs that against the real SDK.

Why no upload scene: apps/mobile/src/app/(app)/(tabs)/inbox/upload.tsx was deleted in 915a827d and nothing replaced it. Inbox still draws "Tap to upload" and a + button, and both lead to a route that does not exist. The Inbox screen is therefore not photographed at all — the frame would show the button.

Why no handoff scene: the Tax screen's "Generate CA handoff packet" button answers "Not available" since 2026-07-28-remove-ca-handoff-surface. The Tax frame is not scrolled, which keeps that card below it.

Why Transactions rather than the Expense overview: the overview labels its total "May burn" whatever month the data is from.

Consequences

  • .context/listing/listing.md still says "Upload what you have" and promises a handoff packet. Both are true of the website and false of the Android app. The listing text has to change, or the app has to gain the two screens, before the listing is sent for review (tasks.md T013).
  • The sample cannot use the persona's own ₹12 lakh salary: under the new regime that owes no tax, so there is no comparison to show. It uses ₹18 lakh.
  • Anything a scene shows must keep working with the network off, or the frame goes blank on the next capture rather than on a user.

Every project of mine is written down like this.

Read the résumé