Day 2 with Coding Agents: The Discipline of Operating and Refactoring Live Production Code
A few months ago, I wrote about how I used Google AI Studio, Gemini, and coding agents to build and ship the first version of Lotto Check in a matter of weeks. The narrative was simple and exhilarating: a product manager with light coding experience using LLMs to bypass the traditional mobile development bottleneck.
That was Day 1.
Day 2 is a completely different beast.
Once your app is live in the App Store, you have real users scanning tickets, paying monthly Pro subscriptions, and expecting 99.9% reliability. Suddenly, the rapid “vibe coding” habits that got you to MVP become an existential liability. When an agent hallucinates a database schema change or silently introduces a race condition on an auth callback, users can’t scan their tickets, or worse, your app gets rejected during an expedited App Store review.
Over the past ten months of running Lotto Check with an agent-first workflow (primarily Claude Code and Antigravity/Gemini), I had to construct a rigorous systems-engineering discipline around our AI tools. Here is what actually happens when you operate, refactor, and maintain a live production app with coding agents.
1. Why “Memory Banks” Rot and How Single-Owner Docs Fixed It
In the early days, I relied on the popular “Memory Bank” pattern: a collection of open-ended Markdown files (projectBrief.md, systemPatterns.md, activeContext.md) that agents were instructed to read and update on every session.
By month three, the memory bank suffered catastrophic context rot:
- Contradictory truths: One file said we supported British Columbia regional games, another said Western Canada was still in discovery.
- Agent drift: Agents spent half their token budget reading stale narrative logs from three months prior and hallucinated solutions to bugs that had already been resolved.
- Context bloat: When an agent reads 3,000 lines of obsolete status notes before writing a single line of TypeScript, its reasoning window degrades.
Context windows are precious reasoning real estate; when you force an agent to wade through historical storytelling, its ability to solve the active bug collapses.
We threw out the entire memory bank and replaced it with a strict Single Source of Truth architecture:
- Single Fact Ownership: Every architectural fact is owned by exactly one reference document in
docs/reference/(architecture.md,database.md,monetization.md,security.md). If a fact changes, only that file is updated. - Procedures as Executable Skills: Instead of asking the agent to remember how to deploy an Edge Function or backfill lottery draws, we encapsulated multi-step procedures into discrete agent skills (
.agents/skills/). The agent only loads the skill it needs for the active task. - Deletable Task Files: Active work lives in
docs/tasks/YYYY-MM-DD-feature.md. The moment the code lands and passes verification, the task file is deleted from the repo. No lingering context, no narrative bloat.
docs/
├── reference/ # Immutable facts (single owner per topic)
│ ├── database.md # Tables, RPCs, RLS rules
│ ├── monetization.md # RevenueCat entitlements, paywall flags
│ └── security.md # JWT rules, Edge Function auth
├── tasks/ # Ephemeral work orders (deleted when committed)
└── decisions.md # Single-line decision log (max 30-day window)
2. The Three-Tier Blast Radius: Never Let Agents Touch Production Directly
Early on, giving an agent terminal access to deploy Edge Functions felt like magic. Until a routine scraper change took down our primary verification endpoint.
To safely operate with autonomous agents, we established a strict three-tier deployment boundary in AGENTS.md:
| Tier | Scope | Allowed Agent Action | Production Gate |
|---|---|---|---|
| Routine | Docs, scraper tweaks, design tokens, UI bugfixes | Deploy to DEV or PROD | Automated test suite passes |
| Standard | Minor backend Edge Functions, new migrations | DEV first, verify live | Staged automated smoke tests |
| Critical Path | Ticket scanning (process-ticket), Auth, Payments (revenuecat-webhook), Push notifications | DEV only. Strictly blocked from PROD | Explicit human sign-off in chat |
Agents should have complete autonomy to experiment and break things on development, but the bridge to production requires a hard human gate.
Our custom deployment script actively enforces this. If an agent tries to deploy a Critical Path function to production, the CLI throws an error and aborts unless passed an explicit --confirm-critical flag that only human operators provide:
# Agents can run this autonomously:
npm run deploy-function -- process-ticket --env dev
# Agents CANNOT run this without explicit instruction:
npm run deploy-function -- process-ticket --env prod --confirm-critical
This simple constraint eliminates 95% of production risk. Core workflows like ticket scanning cannot afford probabilistic mistakes, which is why we also strictly isolate language perception from mathematical logic (see Deterministic Code vs. Generative AI). Agents are free to iterate, break things, and debug rapidly on DEV, but the bridge to production requires human eyes.
3. The Read-Only Adversarial Audit Pattern
One of the biggest mistakes founders make with coding agents is asking the same agent that wrote the code to review it. Agents suffer from confirmation bias: they will vigorously defend their own flawed logic and overlook glaring edge cases.
In our workflow, every significant pull request undergoes a Read-Only Adversarial Audit using an independent subagent.
The auditing agent operates under strict constraints:
- It runs with read-only tools (it cannot edit files or run git commits).
- Its sole prompt is to find vulnerabilities across security, database indexing, race conditions, and UX traps.
- It grades findings into Critical, Major, and Minor, and stops. It is explicitly banned from auto-fixing what it finds.
Separating the builder from the auditor removes confirmation bias and catches catastrophic edge cases before code ever reaches staging.
The Bug That Saved Our App
In October 2026, we launched our v1.4.0 update with an in-app banner announcing cloud sync. Within three hours of release, the banner vanished for all 1,400 active users.
An agent had implemented the client-side dismissal logic by executing a generic update query on the Supabase user_in_app_messages table. Because broadcast announcements had user_id IS NULL, one user tapping “Dismiss” updated the database row globally, marking the announcement dismissed for every user in Canada.
Our adversarial audit skill caught the root vulnerability and forced the architectural separation: broadcast dismissals must be stored locally in device MMKV (fast key-value storage), while database row mutations are restricted via row-level security (auth.uid() = user_id AND user_id IS NOT NULL).
4. App Store Guideline 2.5.19: Stripping Agent Shortcuts for Production
When building fast, agents love building “debug screens,” “mock paywalls,” and secret admin menus. They are invaluable during local iteration.
However, in October 2026, Apple cracked down hard on App Review Guideline 2.5.19: no hidden, dormant, or undocumented features in production binaries. If Apple reviewers find a multi-tap gesture that reveals an unadvertised admin menu, or if static analysis flags dead debug bundles, your submission is instantly rejected.
Don’t rely on prompt memory to keep debug tools out of release builds; let compiler rules and pre-flight bundle scanners enforce your boundaries.
To solve this, we enforced compile-time stripping:
- All debug utilities, design labs, and admin toggles live behind an explicit build-flag check:
export const IS_ADMIN_BUILD = __DEV__ || EXPO_PUBLIC_APP_VARIANT === "development"; - Metro bundler configuration (
metro.config.js) completely excludes design lab routes from release bundles. - A pre-flight CI script (
scripts/check-release-bundle.sh) scans the compiled JavaScript bundle before any EAS build. If it finds strings likeForce Pro,Design Lab, orToggle Subscription, the build aborts immediately.
Operating Playbook for Day 2 Teams
- Kill the narrative memory bank: Move to single-owner reference docs and ephemeral task files. Context windows are for reasoning, not historical storytelling.
- Implement deployment tiers: Give agents full autonomy on DEV, but require an explicit confirmation gate for anything touching auth, payments, or core data pipelines.
- Separate authors from auditors: Always spin up a fresh, read-only agent to audit completed features before staging to production.
- Enforce boundaries in the compiler, not the prompt: Don’t ask an agent to remember rules. Write an ESLint rule and a pre-flight bundle check that fails the build when it tries.
Day 2 with AI coding agents requires moving from chaotic “vibe coding” to disciplined systems engineering. In this post, we covered how single-owner reference docs prevent context rot, how a three-tier blast radius protects production endpoints, why read-only adversarial audit agents catch hidden bugs, and how compile-time bundle checks guarantee App Store compliance.


