
In the previous article, I shared the personal motivation and architectural foundations behind pwE (Pray With Me) — a cross-platform digital sanctuary for daily Lectio Divina (Prayerful Reading), built inside the independent software studio JHH Solutions.
When you spend over a decade working with enterprise mission-critical systems, distributed architecture, and SRE, there is a classic mental trap when building your own 0-to-1 product: assuming that once Clean Architecture, DDD, 51 ADRs, and 931+ automated tests are in place, publishing on the Google Play Store will be a routine operational formality. Run flutter build appbundle --release, fill out the store listing, and wait a few hours.
In reality, production-ready code is not a published product.
Between submitting v1.0.0+176, officially going live in Google Play Production on November 2, 2026 (v1.0.3+179), and navigating an intense first week of live Day-2 sustainment up to v1.0.24+200, crossing that "last mile" demanded 18 brand-new ADRs dedicated to release governance, compliance, offline resilience, billing, and internationalization (ADR 0052 through ADR 0069):
Operating independently — wearing the hats of architect, mobile engineer, QA, SecOps, legal counsel, and product manager in the spare hours of a father of three young kids — teaches you quickly that the final mile to the store plays by its own rules. And the toughest one has nothing to do with a compiler.
The "14-Day Valley": the real filter for independent developers
Following Google Play Console's policy overhaul for personal developer accounts (created on or after November 2023), access to the Production track is no longer immediate. Before any everyday user can discover your app on the store, you must unlock a mandatory gate: Closed Testing.
The rule sounds straightforward in official docs, yet requires surgical coordination in practice:
Compliance & Manifest
Data Safety, AI Policies, FGS Video
Signed AAB Upload
Play App Signing + Crash Symbols
12+ Testers Opt-in
Authorized Emails & Store Link
14 Consecutive Days
Unbroken Retention + Telemetry
~72h Human Queue
Dossier + Safe Remote Config Floor
Nov 02 Go-Live
HTTP 200 in 177 Countries + Web
To unlock the Apply for Production button, Google requires at least 12 real testers (originally 20) who formally accept the invitation (opt-in), install the app on physical Android devices, and remain opted-in without interruption for 14 consecutive days.
For a large studio with an internal QA device lab, gathering a dozen phones is trivial. For an indie developer, it becomes an exercise in logistics, observability, and release engineering:
- Opt-in friction and silent Track Shadowing (
ADR 0054): In Play Console, sending a direct store link isn't enough. You must authorize the tester's email, wait for propagation, collect web opt-in consent, and ensure the Google account signed into their browser matches the active Play Store account on their phone (otherwise they hit the dreaded "Item not found" screen). Even subtler: while runninginternalalongside two closed tracks (alphaand a dedicated WhatsApp testing track), we discovered that updating one track at a time left early testers stranded on older binaries. We solved this by building atomic multi-track promotion via API and wiring aVersionGovernanceBannerpowered by Firebase Remote Config to gently prompt testers in-app whenever a newer build went live. - Recruiting with an SRE safety buffer: I approached tester recruitment like SRE capacity planning — never run at
N+0. Recruiting an intentional buffer of volunteers absorbed device swaps and life surprises without resetting our two-week clock. - Genuine daily engagement and catching bugs no emulator would ever surface: Google reviewers inspect whether testers actually exercised the app and whether you shipped updates addressing feedback. With pwE, the Daily Liturgy gave testers an organic reason to open the app every morning — uncovering subtle real-world edge cases:

Cross-Locale Leak in the Wild
A tester running Android in English received AI passage suggestions in PT-BR. That single screenshot drove our 5-layer deterministic 18-language architecture with strict English fallback (ADR 0068).

Receipt Isolation & Restore
Hands-on testing of the Benefactor flow exposed multi-account Google Play receipt edge cases on shared devices, hardening our RevenueCat identity sync (v1.0.23+).
"What initially felt like a bureaucratic toll turned out to be the best pre-production stress test the project could have asked for."
Where Senior Engineering pays dividends during store review
Surviving the 14-day window is half the journey; the other half is passing Google Play Console's automated, regulatory, and policy gauntlets. Here, upfront architectural discipline stopped being theoretical and translated directly into approval velocity:
1. Data Safety, AndroidManifest Hygiene & Generative AI Policy (ADR 0025 & ADR 0057)
Google Play's Data Safety disclosure demands surgical precision around collection, encryption, and retention. Many indie apps get trapped in rejection loops because third-party AAR libraries silently merge sensitive permissions into the final manifest.
By auditing our merged release manifest (:app:processProdReleaseMainManifest), we explicitly stripped transitive permissions (AD_ID, ACCESS_ADSERVICES_ATTRIBUTION, READ_PHONE_STATE, and legacy STORAGE) using tools:node="remove". Conversely, to keep background OTA downloads for our offline Gemma 4 E2B (~1.3 GB) model on Android 14+, we recorded and submitted a physical-device walkthrough video demonstrating visible user benefit for FOREGROUND_SERVICE_DATA_SYNC. Combined with Zero-Knowledge AES-256-GCM encryption in the Spiritual Notebook, strict explicit opt-in before any cloud AI call, an in-app "Flag this passage" button on every AI card, and first-party privacy, terms, and cryptographic delete-account endpoints, compliance review sailed through cleanly.
2. From flutter run to Zero-CI Local Deploys & Multi-Locale .aab (ADR 0049 & ADR 0068)
Every Flutter engineer learns the hard way that an app running flawlessly in debug can break silently in release. Beyond AOT compilation and R8/ProGuard shrinking, Android App Bundles (.aab) carry a classic gotcha: by default, Play Feature Delivery performs Language Splitting, stripping locale packs that don't match the phone's primary language at install time — breaking dynamic in-app switching across our 18 languages (962 ARB keys) until we disabled language splitting (enableSplit = false, < 150 KB impact) alongside locales_config.xml.
To ship rapid fixes without burning 25 minutes of GitHub Actions quota per build, I built pwe_local_deploy.dart: a custom CLI that builds the obfuscated .aab locally, uploads Crashlytics symbols, and authenticates via native RS256 JWT straight against the Google Play Android Publisher API v3 — promoting builds across internal, closed, and production in ~3 minutes at zero CI cost.
3. Pre-Launch Reports, WCAG Accessibility & 360° Production Telemetry (ADR 0050 & ADR 0066)
Every .aab uploaded to Google Play triggers automated Firebase Test Lab crawlers across dozens of physical devices, hunting for native crashes, ANRs, < 48×48dp touch targets, and contrast regressions. Alongside 1,430+ automated tests across 236 suites (enforcing 16 executable SPEC-* specs, a 6-viewport matrix up to TextScaler 2.0x, and 8.10:1 WCAG AA contrast), we built pwe_production_monitor.dart — a $0/month executive CLI unifying Android Vitals, GA4, Crashlytics, and Langfuse OTLP v4.
4. Open Web (PWA) & Ethical PPP Monetization Across 174 Regions (ADR 0056 & ADR 0058)
While the 14-day Android clock ticked (and iOS follows its own roadmap), serving our Flutter Web app (pwe.jhhsolutions.dev/app) gave iPhone and desktop users immediate zero-install access. On the sustainability front (Friends of the Mission), we caught Google Play's default FX conversion inflating prices across emerging markets while displaying subscription benefits in a single language. We wrote pwe_monetization_sync.dart to programmatically sync 54 localized store listings (3 plans × 18 languages) across 174 countries using Purchasing Power Parity (PPP) — modeling our non-renewing 30-day contribution as a native prepaidBasePlanType.
Here is how that convergence of contemplative UX and release engineering looks live on Google Play today:



The Nov 2 Go-Live & Week 1 live in production (build #179 to #200)
We submitted our Production dossier with v1.0.0+176 on October 30 (followed by v1.0.2+178 on October 31). During Google Play's ~72-hour human review queue, we spotted a subtle Remote Config trap: bumping min_supported_build_number prematurely in Firebase Remote Config would lock out reviewers and existing testers onto a binary not yet publicly downloadable. We kept min_supported_build_number = 1 unlocked until November 2, 2026, the exact moment our public Play Store listing returned HTTP 200 globally across 177 countries — promoting v1.0.3+179, enforcing floor 178, and receiving our very first spontaneous 5.0 ★ public review that same night.
Then came the real engineering baptism across our first seven days live (Nov 2–8), spanning 24 production releases (v1.0.0 through v1.0.24+200):
Blocking 84 Crawler Bots at Minute Zero
Within hours of going live on Nov 2, 84 automated crawler accounts from Firebase Test Lab hit onboarding and created synthetic profiles in RevenueCat. Same day (v1.0.4), we read native Settings.System("firebase.test.lab") to isolate 100% of bots before billing or analytics boot.
99.07% Crash-Free Across 18 Countries
In week one alone, the app welcomed 440 active users across 18 countries running on 37 distinct physical phone and tablet models (from Android 10 <= 4 GB RAM devices to Android 16/17 flagships), maintaining zero Android Vitals alerts and 17.2 min of average engaged time per user (70.0% engagement rate).
58.3% Silent Readers vs. 190 Encrypted Vaults
Aggregate telemetry revealed that 58.3% pray daily in silence (like a contemplative Missal), while 42.5% write encrypted prayers across 190 Zero-Knowledge (AES-256-GCM) vaults — driving our 0 ms True Local-First cold start and OS-level Interior Recollection Mode (Mt 6:6 DND).
4.11% of Free Tier & 100% Orthodoxy
Even with a parallel 18-locale liturgy worker and thousands of GCS Static CDN reads, daily Firestore usage stayed at just 4.11% of the free-tier read quota ($0/month infra bill), paired with native Gemma 4 token streaming and 100% theological orthodoxy in Langfuse OTLP v4.
Open architecture where it matters, protected IP where it's sacred: inside pwe-architecture-showcase (ADR 0051)
Every engineer shipping a commercial indie product faces a classic portfolio dilemma: when your production monorepo must stay private — to safeguard pastoral prompts (Zero-Public-URL / SEC-AI-10), proprietary 7 Drops curation, ingestion workers, and cloud credentials — how do you let peers, architects, and hiring managers verify your real production engineering without asking them to take your word for it?
Our answer in ADR 0051 was evslopes/pwe-architecture-showcase, continuously synchronized from the private production monorepo via our custom tool/sync_showcase.dart CLI. On every release, it exports a strict Allowlist, runs a deterministic Redaction Engine (16 sanitization rules), and enforces a post-build Security Leak Scanner (13 forbidden patterns) that aborts the push if any internal identifier survives.
Every engineering story in this article can be audited directly in real Dart production code and unit tests today:
- 20 Real Clean Code Slices Across 5 Domains (
showcase/): - Contemplative Lifecycle & Reactive State (
state_management/):recollection_bloc.dart(orchestrating Interior Recollection Mode viaZenPolicyand anti-orphaned-DND Sleep Guard) andlectio_session_bloc.dart, paired with fullbloc_testsuites. - Edge AI Bridge & Rate Limiting (
edge_ai_bridge/):llm_local_datasource.dart(Gemma 4 native token streaming overEventChannel('pwe/gemma_local_stream'), TTFT telemetry, and automaticGPU -> CPUfailover) andllm_rate_limiter.dart. - Local-First Encrypted RAG & OCR Geometry (
local_first_rag_and_ocr/):local_vector_search_datasource.dart(< 1 msL2 cosine search atopHiveAesCipher) andbiblical_ocr_layout_analyzer.dart(computational geometry reconstructing printed two-column Bibles). - Platform Security & Sacred Design System (
platform_security/&sacred_design_system/):screen_security_service.dart(dynamic runtimeFLAG_SECURE),hold_to_save_button.dart(overflow-proofCustomPainterup toTextScaler 2.0x), andadaptive_two_pane.dart. - Full Index of 69 ADRs (
docs/adr/) & 8 C4/Mermaid Architecture Specs (docs/architecture/): every architectural record from0001through0069, sequence flows, state machines, GCS CDN liturgy BFF, andAES-256-GCMsecurity topology. - 18-Agent SDD/TDD Governance (
docs/ai-governance/) &CHANGELOG.md(200+ builds): the traceableRN- -> ADR- -> SPEC-* -> Code -> Testchain, live Marionette/Dart MCP runtime validation, and sanitized SemVer history fromv0.1tov1.0.24+200.
6 practical lessons for shipping your first indie app
If you are a software engineer preparing to publish an independent project on Google Play, here is the field playbook I wish I had on Day 0:
| Critical Stage | Common Pitfall | Practical Mitigation |
|---|---|---|
| 1. Account & Identity | Waiting until code is "done" to open your Play Console account (assuming it's just a quick $25 fee). | Register and complete identity and payment verification weeks ahead; document checks take days. |
| 2. Testers & Tracks | Inviting exactly 12 friends over chat and managing multiple tracks manually in the UI. | Recruit 18–25 testers, share a 3-step visual opt-in guide, and promote the exact same versionCode across internal and closed to prevent Track Shadowing. |
| 3. Manifest & AI Policy | Blindly trusting plugin permissions and generic free privacy policy generators. | Strip unused transitive permissions via tools:node="remove", enforce explicit AI opt-in + content reporting, record a video for Foreground Services, and host privacy, terms, and delete-account on your own domain. |
4. .aab & Multi-Locale | Testing exclusively via flutter run in debug and in a single language until launch eve. | Test obfuscated release .aab builds on internal tracks from Sprint 1, set enableSplit = false for dynamic locales, and enforce deterministic English (en) fallback. |
| 5. Production Dossier | Writing vague, one-line answers on Google's final production questionnaire. | Document clearly how you recruited testers, which real field bugs were resolved across your 14-day releases, and how you monitor vitals in production. |
| 6. Review Queue & Day 1 | Raising force-update floors in Remote Config during the ~72h human review queue and ignoring bot traffic at launch. | Keep min_supported_build_number unlocked until your public listing returns HTTP 200, and detect firebase.test.lab natively on Day 1 so dozens of crawler bots don't pollute billing or analytics. |
Code on your machine is study; code in the store is responsibility
Seeing the "Available on Google Play" badge go live globally on November 2, 2026 for pwE (Pray With Me) brought home a truth that years of enterprise work can sometimes numb: when you sign your name to a product end-to-end, software architecture stops being an abstraction.
Every single one of our 69 ADRs, every Zero-CI release script, and every cryptographic privacy guard existed for one purpose alone: allowing someone on the other side of the screen to open their phone and find silence, beauty, and trust — never needing to know how much engineering had to work quietly behind the scenes to protect that moment.
pwE is live and free on the Google Play Store (177 countries) and on the Web, backed by the public pwe-architecture-showcase repository with 69 ADRs and 20 real Clean Code Slices: