Roadmap
The whole new app, with all 39 live features on its own App Service, reaches UAT in 10 working days. Claude Code agents write the code, tests and docs. Three people, each on a Claude Max plan, run the agents, review their output and make the decisions.
This plan has no human build effort. Effort is measured in parallel Claude sessions: one session is one Claude Code agent working in its own git worktree on one task. People decide, review, merge and test on real phones. The feature pages on this site are the spec: their fields, rules and tables are the acceptance criteria every agent works against.
Working model
| Item | How it works |
|---|---|
| Team | 3 people, each with Claude Max and a lane: A, Mobile (the new app), B, App Service (the BFF and its links to today's services), C, Quality & data (tests, fixtures, legacy data, UAT). Nobody writes production code by hand |
| Agents per person | 3-4 Claude Code sessions in parallel, each in its own worktree and branch. About 10-12 sessions run at once across the team |
| Models | Opus for architecture, the sync engine, contracts and code review; Sonnet for feature screens, endpoints, tests and fixtures; Haiku for string files, translations and test data |
| Spec | content/data/features.json (fields, validations, when/then rules), tables.json, endpoints.json and the App Service page. Each feature task is handed to an agent as "build this feature page" |
| Definition of done | Every when/then rule on the feature page has a passing unit test. Every field validation is covered. An end-to-end flow runs on an emulator. A second agent reviews against the feature page. The lane owner merges |
| Contract first | The App Service API is written as OpenAPI on day 1. Client and server code and contract tests are generated from it, so lanes A and B never wait on each other |
| Daily rhythm | Morning: lane owners split the day's work into agent tasks (one feature or one endpoint group each). During the day: agents build; owners review and merge. Evening: lane C runs the full test suite and a device pass and files issues as next-day agent tasks |
| Stack | Jetpack Compose, KMP-ready, as recommended on Compose vs Flutter. The App Service is built in the existing urvi-app-service stack |
Day 0: before the clock starts
These are decisions and access only people can give. If any is missing on day 1, the plan slips by that much.
| Need | Owner | Why |
|---|---|---|
| Stack decision: Compose (recommended) or Flutter | Product owner | Every agent task depends on it |
| Staging access from the App Service to today's services (ctld, ptld, rtld, commons-report, portfolio, asset, assessment, sync) with a service account | Lane B | The App Service aggregates them; agents need real responses to code against |
| Test accounts for each role: cadre, Unit In-charge/FMT L1, HAN, FCCC | Lane C | Role and gate rules can't be tested without them |
An anonymised copy of a real device database (agri_db, ie_register.db, sync_ledger_db) | Lane C | Fixtures and the legacy-import test |
| Play Console internal or closed testing track; a CI runner; secrets store | Lane A | UAT builds must be signed and installable |
| Two low-end field phones (2-3 GB RAM) and one mid-range phone | Lane C | Performance, GPS walk and offline tests |
| Answers to the open questions at the bottom of this page, or acceptance of the defaults | Product owner | Removes scope arguments during the build |
Claude Code set up on each machine: repo access, this site's content, CLAUDE.md with architecture rules, lint and the definition of done | All | Agents follow the same rules from the first task |
Ten days at a glance
| Day | Goal | Lane A, Mobile (sessions) | Lane B, App Service (sessions) | Lane C, Quality & data (sessions) | Gate at end of day |
|---|---|---|---|---|---|
| 1 | Foundations | App skeleton: modules, design system, encrypted DB on the target schema, outbox, login and token refresh, startup state machine (4) | OpenAPI contract for all endpoints; service skeleton; auth, session/bootstrap, config with ETag (3) | Turn every feature page into a test catalogue; set up the end-to-end test harness; build fixtures from the anonymised DB (3) | Contract merged; app logs in on staging; test catalogue covers all 335 rules |
| 2 | Sync core | Sync worker with backoff, Pending Sync screen, file upload queue; legacy-reader spike (3) | farmers/snapshot, farmers/changes, sync/batch with idempotency and id map, files (4) | Contract tests both ways; sync torture tests (kill, reboot, airplane mode, duplicate send) (3) | A created farmer syncs once, survives a kill, and gets its server id |
| 3 | Wave 1: shell and read | Language, login, startup routing, VO selection, device registration, data download (cadre, unit), home, side menu, farmer list and search, farmer hub gates (4) | Bootstrap and snapshot wired to real staging data; geo lookups; remote actions (3) | Hub gate rules: all 26 as tests; role matrix tests; first device pass (3) | A cadre and a Unit In-charge browse real data offline |
| 4 | Wave 2: simple writes | Add/edit farmer (19 fields, duplicate checks, category freeze), farmer category, livestock, crop stock, 365 DKG (4) | Write handlers for these entities in sync/batch; server-side validation copied from the feature pages (3) | Validation tests for every field; create-offline-then-sync flows (3) | All simple writes sync with correct ids and server-side checks |
| 5 | Wave 3: land and geofencing | Land assets, leased land, disabled land, geofence capture (walk, tap, KML) with point-count and accuracy checks (4) | Land handlers; shared land-usage calculation; lessor lookup (3) | GPS walk test on a real phone; land-limit edge cases; mid-point demo (3) | Land and polygons round-trip; the land limits match on client and server |
| 6 | Wave 4: crops and models | Crop Actual (15 fields, 18 rules), PMDS and A Grade, month copy, crop harvest, ATM model (23 rules), ATM harvest (4) | Portfolio and farming-model handlers; harvest with photo and GPS actually sent; compact-block lock error (3) | Crop and ATM rule tests; land-ceiling cases; harvest date windows (3) | Crops and ATM work offline and sync; all their rules pass |
| 7 | Wave 5: Unit work | VO/SHG/farmer endorsement, farmer endorsement details, comments, KAP 2025-26 (as a form schema), compact block, FCCC geo filter, VO/SHG survey entry (4) | Endorsement state machine on the server; KAP schema in config; compact-block endpoints (3) | Endorsement order rules (SHG before VO, category frozen, KAP submitted); compact-block 5-acre rules (3) | A Unit In-charge completes an endorsement and a compact block |
| 8 | Wave 6, then freeze | Certification survey, activity tracker, analytics dashboard, notifications, settings, sync error log, program config and instructions, login history (4) | Analytics in one call per scope; notifications; assessment pass-through; telemetry without PII (3) | Telugu and Tamil strings filled and reviewed; full regression on emulators (3) | Feature freeze: all 39 features present |
| 9 | Hardening | Bug-fix tasks from the regression report; cold-start and list performance on low-end phones; R8 and Baseline Profiles (4) | Load test with anonymised data; error codes; logging and alerts; staging deploy hardened (3) | Full device pass per role; legacy import test on a real old DB; UAT test scripts generated from the feature pages (3) | Zero P1 defects; UAT candidate build signed |
| 10 | UAT release | UAT build on the testing track; in-app feedback; fix-forward tasks (3) | UAT environment live; monitoring dashboard (2) | UAT guide in English and Telugu; defect triage board; first UAT session with the programme team (3) | UAT open |
Peak load is about 10-11 parallel sessions. Crop Plan 2023-24 and AAP 2024-25 are hidden in today's app and are not rebuilt. Nothing on Set-aside code is rebuilt.
How one feature gets built
- The lane owner gives an agent the feature page (for example Land assets) and the matching contract operations.
- The agent writes the tests first. Each when/then rule and field validation becomes a test, and each test is named after its rule.
- The agent builds the screen, the view model and local storage, and the outbox operation if the feature writes.
- The lane B agent adds the server-side handler and the same validation from the same page.
- A review agent (Opus) compares the result with the feature page and lists anything missing or different.
- The lane C agent runs the end-to-end flow on an emulator and updates the test catalogue.
- The lane owner reviews the diff and the test report, then merges. Anything unclear goes into the decision log, not into a guess.
Release gates
| Gate | When | Pass criteria |
|---|---|---|
| Contract freeze | End of day 1 | OpenAPI merged; later changes go through a contract test update first |
| Sync proven | End of day 2 | Idempotent batch with no duplicates after kill, reboot and resend |
| Mid-point | End of day 5 | Waves 1-3 on a real phone; scope for days 6-8 confirmed or cut |
| Feature freeze | End of day 8 | All 39 features present; only fixes after this |
| UAT candidate | End of day 9 | All rule tests green; zero P1; cold start within budget on the low-end phone; legacy import passes on the real DB copy |
After UAT (outside the 10 days)
| Step | What happens | Driven by |
|---|---|---|
| UAT fix loop | Each UAT defect becomes an agent task with the failing scenario attached; daily builds | All lanes |
| Hygiene hotfix to today's app | Rotate the signing key and Nexus credentials, stop PII going to Firestore and sync-service/so, gate body logging (see Security). Rotating keys is a human action; the code changes are agent tasks | Lane B and C |
| Drain release of today's app | Forces sync, shows the pending count, flushes ATM harvest and KAP writes, reports "queue empty", then blocks edits after the cutover date | Lane A |
| Production rollout | Same package name and a higher versionCode; legacy import on first launch; staged rollout by district with version gating as a kill switch | Lane A and C |
| Decommission | Switch off old dataset access and Firestore sync logs; remove the Bridge libraries; archive the old repo | Lane B |
Risk register
| # | Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|---|
| 1 | Claude Max usage limits stop sessions mid-day | H | H | Use Opus only for architecture, sync and review, and Sonnet for bulk work; stagger heavy sessions across the three plans; keep a queue of small tasks for when a plan resets |
| 2 | Review becomes the bottleneck: three people can't read 10 sessions' diffs | H | H | Small tasks (one feature or one endpoint group); a review agent checks every PR against its feature page first; people review the test report and risky files (sync, auth, migrations) line by line |
| 3 | Agents invent a rule the code doesn't have, or miss one it does | M | H | Tests come from this site's rules tables before any code; the review agent diffs behaviour against the feature page; unclear cases go to the decision log |
| 4 | Today's services in staging are slow, flaky or unreachable from the App Service | M | H | Day 0 access check; record-and-replay fixtures so lanes A and C can keep working; lane B owns the integrations |
| 5 | Day 0 decisions or access arrive late | M | H | Every day of delay moves UAT by a day; defaults in the decision log apply if there is no answer |
| 6 | Geofence walking, GPS accuracy and offline maps behave differently on real phones | M | M | Real-phone GPS test on day 5, not day 9; MapLibre with tile caching decided on day 1 |
| 7 | Sync edge cases (duplicates, ordering, partial failure) surface late | M | H | Sync core is built and torture-tested on day 2, before any feature depends on it |
| 8 | Low-end phone performance | M | M | Performance check in every evening device pass; R8 and Baseline Profiles on day 9 |
| 9 | The assessment library (certification, activity tracker, surveys) has no source and is a SNAPSHOT dependency | M | M | Day 8 wraps it through the App Service; if blocked, those three screens open in UAT as read-only and are finished in the fix loop |
| 10 | UAT finds data or programme rules that changed since this site was written | M | M | The feature pages are the baseline; changes are logged and turned into agent tasks during the fix loop |
| 11 | Unsynced data on today's phones at cutover | M | H | Not a UAT risk; handled by the drain release and legacy import before production |
Decision log: open questions for the owner
Answer these by day 0. If there is no answer, the default applies.
| # | Question | Why it matters | Default if no answer |
|---|---|---|---|
| 1 | Compose or Flutter? | Every agent task depends on it | Compose, KMP-ready (stack) |
| 2 | Is an iOS (or web) field app needed, and by when? | Main Flutter or KMP flip condition | Android only |
| 3 | What does ATM stand for officially ("Anytime Money")? Same for FMT, FCCC, C5 "POP"? | Labels, help text and glossary | Keep current labels |
| 4 | Which seasons' screens still matter: Crop Plan 2023-24, AAP 2024-25, KAP 2025-26, next year's plan? | Avoids rebuilding dead seasons | Build only KAP 2025-26, as a schema |
| 5 | Keep, wrap or replace the assessment library (certification, activity tracker, surveys)? | Day 8 scope | Wrap through the App Service, native UI |
| 6 | Is the BFF built in urvi-app-service, and where is it hosted for UAT? | Lane B setup on day 1 | Yes, on the existing staging cluster |
| 7 | OIDC through an IdP now, or App Service login first? | Auth work on day 1 | App Service login first, IdP later |
| 8 | Must device binding be enforced on the server? | Auth and support flows | Server-enforced where enabled |
| 9 | Can the server return masked Aadhaar (last 4 digits) to the app? | Privacy and DB encryption scope | Full value only where needed, encrypted |
| 10 | Real counts: active users per role, farmers per VO, devices, operations per day | Page sizes and the day 9 load test | Load test at 3x a pilot district |
| 11 | Data residency and retention (India-only hosting, telemetry retention) | App Service hosting | India region, 90-day telemetry |
| 12 | Who in the programme runs UAT, and on which devices? | Day 10 session and the UAT guide | Programme team with the 3 test phones plus their own |
| 13 | Keep Firebase (Crashlytics, Remote Config) or move flags to the App Service? | Fewer moving parts | Keep Crashlytics; flags in the config bundle |
| 14 | Should family details be captured for men too, with separate father and spouse fields? | Fixes a data-model bug; needs programme sign-off | Separate fields, captured for all |