nudgey.
Build · 05

How V1 actually
gets shipped.

A solo build across three tracks. A foundation phase that gated everything. An ADR ledger. A sub-project cadence — brainstorm → spec → plan → build → review — with a Devil's-Advocate pass on every PR. Mobile is through SB18; the backoffice is live behind Clerk auth.

Three tracks

Marketing, mobile, backoffice.

A solo build across three tracks. Mobile sub-projects are mostly sequential; the backoffice opened after the cloud + privacy boundary landed. Track ownership is one person — Nick — throughout.

TRACK A · MARKETING

Marketing

Next.js · Tailwind · Vercel
  • SAthenudgey.com landing + waitlist + privacy/ToS — also the direct-download hedge against Play Store SMS-permission review
TRACK B · MOBILE

Mobile

Flutter · Riverpod · Drift · Firebase
  • SB1–2Scaffold + theme + local data layer (Drift)
  • SB3Cloud + privacy boundary · unlocked the backoffice
  • SB4On-device intake + parsers + institution taxonomy
  • SB5–6Pattern engine · insights engine + clusters
  • SB7Voice layer (voice-lint infra + content)
  • SB8Talk to Nudgey (cloud chat)
  • SB9Onboarding + Reveal (+ SB9.5 email capture/OTP)
  • SB10–11Daily surface · periodic screens + Sunday Drop
  • SB12–13Polish + ship-ready · financial detail screens
  • SB14Savings ledger (the moat)
  • SB15Bill radar + discreet reminders
  • SB16Account recovery + encrypted backup
  • SB18Day-one truth + the Money Map · LiteRT-LM engine
TRACK C · BACKOFFICE

Backoffice

Next.js · App Router · Vercel · Clerk auth
  • SC1Scaffold + Clerk RBAC (owner / ops / engineering / readonly)
  • SC2Sender + merchant triage · template editor · DSAR · feature flags
  • SC3Analytics + ops dashboard · cost bands · error budgets

The backoffice is live behind Clerk

The internal ops console at admin.thenudgey.com gates every /admin/* route behind Clerk auth — separate dev and prod instances, roles via publicMetadata.role (owner / ops / engineering / readonly). It carries sender + merchant triage, the template editor, DSAR processing, feature flags, and the analytics/ops dashboard. An authenticated Lighthouse + axe-a11y suite runs as a CI gate on every PR (all six admin routes score ≥ 0.9). The mobile app does not use Clerk — it stays on Firebase phone auth.

Convergence + Play Store sequencing

S∞1 · End-to-end dogfood + bug bash (the on-device "amazed by day 3–5" test on a real line). S∞2 · Play Store internal track release + ODPC sign-off. The SMS (READ_SMS) permission is the hard approval gate, so V1 submits SMS-only first; background location lands as a post-approval update, and thenudgey.com direct-download is the rejection hedge.

Foundation · S0

The phase that gates everything.

S0 is documentation and configuration only. No application code. It establishes the conventions, ADRs, and codegen so every downstream sub-project reads the same source of truth.

What S0 produces

DOCS

CLAUDE.md per area

Root + mobile + apps/marketing + apps/backoffice. Each ≤800 lines. Tells a Claude Code session in that area what conventions and constraints apply.

ADRS

11 architectural decisions

Stack · privacy boundary · monorepo+Vercel · Firestore region · AI roadmap · conversation memory · generative discipline · installed-apps · institution taxonomy · ODPC registration · brand-token codegen.

CODEGEN

Brand-token sync

TS source of truth → generated Dart for Flutter. Husky pre-commit + CI both enforce. Drift becomes structurally impossible.

CI

Branch protection + PR template

Typecheck + lint + format + token-sync + test on every PR. CODEOWNERS. PR template carries the DA review checklist.

Verification gates

.
The ADR ledger

Decisions that gate code.

Each lives in docs/decisions/NNNN-slug.md with required sections: Status, Context, Decision, Consequences, Alternatives Considered. The foundation set below is ADR-0001 through 0011; later decisions (e.g. ADR-0017, at-rest DB encryption) were written as their sub-projects landed.

ADR-0001

Stack

Flutter + Riverpod + Drift on mobile · Next.js 16 + Tailwind on web · Firebase (Auth + Firestore + FCM + Crashlytics + Remote Config) · pnpm + Turbo monorepo.

accepted
ADR-0002

Privacy boundary as a type-system rule

Local-only types lint-blocked from RemoteRepository. Single anonymize() is the audit point. The type system carries the privacy claim, not promises.

accepted
ADR-0003

Monorepo + Vercel + Cloudflare DNS

Two repos collapsed to one. Apps deploy to Vercel (matches Sweeton's apps layer, free tier covers V1, simpler Next.js DX). DNS at Cloudflare (existing Nick account, at-cost pricing). Names what was overridden vs the playbook.

accepted
ADR-0004

Firestore region

Confirmed at Firebase project creation. africa-south1 if GA for all required services, else eur3 for V1 with documented migration plan.

accepted
ADR-0005

AI roadmap

Two cloud LLM use cases ship in V1, both via LlmGateway: Talk to Nudgey (5 turns/day free, 30-day full trial) and the period-story narrative (premium only). On-device extraction is a separate engine (LiteRT-LM). V1.5: swap NudgeGenerator to LlmNudgeGenerator. V2: ML for clustering + anomaly detection. Orchestration is the moat.

accepted
ADR-0006

Conversation memory on-device

Chat history + parsed intent tokens stored locally only. Cloud LLM calls stateless. Optional encrypted cloud backup keyed to user passphrase (not auto-sync).

accepted
ADR-0007

Generative vs templated UI

V1 commits to agentic Levels 0–3. Levels 4–5 forbidden in V1 and V1.5. Brand consistency, accessibility, predictability are protected values.

accepted
ADR-0008

Installed-apps detection

Android <queries> element only — never QUERY_ALL_PACKAGES. Registry is a fixed KnownFinanceApp enum. List stays on-device; only aggregate telemetry leaves. iOS does not get this.

accepted
ADR-0009

Finance institution taxonomy

Replaces hardcoded 5-bank parser with registry-driven model. Sender-ID-first resolution, heuristic fallback, ops-triage long tail. Six categories. Three V1 coverage tiers.

accepted
ADR-0010

ODPC registration & data-controller status

Tracking ID + filing date for Kenya's Data Protection Act. Annual renewal. Riverbank Solutions Ltd (Kenya) — operating company behind the Nudgey trade name — as Data Controller; backoffice ops as Data Processor handlers.

accepted
ADR-0011

Brand-token codegen direction

Catalogue is human source of truth → TS is machine source of truth → Dart is generated and committed → husky/CI enforce no drift. Typography uses catalogue numbers verbatim for Flutter; web ladder in fontSizes is Tailwind-only.

accepted

Since the foundation set: ADR-0017 (on-device DB at-rest encryption posture) is accepted — presence-gating / dual-master-key rejected, StrongBox + TEE + Android FBE adopted with an accepted rooted-live-device residual. Backoffice auth resolved to Clerk (dev + prod instances, roles via publicMetadata). The on-device extraction LLM migrated to LiteRT-LM (Gemma 3 1B int4) off the deprecated MediaPipe runtime. Still open as sub-project decisions: V2 bank API, africa-south1 migration, iOS launch criteria.

14-prompt playbook

Build order, mapped.

The playbook (docs/Nudgey_Claude_Code_Playbook_v1.1.docx) defined the original 14-prompt build sequence. Each prompt became a sub-project with its own brainstorm → spec → plan → implementation cycle, plus a Devil's-Advocate review before merge. The sequence has since extended past it — SB13 financial detail, SB14 savings ledger, SB15 bill radar, SB16 recovery, and SB18 the Money Map are follow-on sub-projects that kept the same cadence.

#PromptMaps toTrack
01FoundationS0FOUNDATION
02Scaffold + theme systemSB1MOBILE
03Local data layer (Drift)SB2MOBILE
04Cloud + privacy boundarySB3MOBILE
05On-device intake + parsers + institution taxonomySB4 (expanded)MOBILE
06Pattern engineSB5MOBILE
Insights engineSB6 · added in S0MOBILE
07Voice layer (category-aware)SB7MOBILE
Talk to Nudgey (cloud chat)SB8 · added in S0MOBILE
08Onboarding + Reveal (expanded)SB9MOBILE
09Daily-use screens + journeysSB10 (expanded)MOBILE
10Periodic screens + Sunday DropSB11 (expanded)MOBILE
11Polish + ship-readySB12MOBILE
12Backoffice scaffold + RBACSC1BACKOFFICE
13Core admin screens (with sender-triage)SC2BACKOFFICE
14Analytics + operations dashboardSC3BACKOFFICE
SAMarketing landing + waitlistSA · separateMARKETING
Devil's Advocate workflow

Every sub-project ends with a DA review.

Fresh Claude Code session, no prior context. Reviews the spec or the merged implementation. Findings save to docs/da-reviews/PROMPT-{n}-{branch}.md. Severity ladder: Blocker · Serious · Minor · Nit.

STEP 01

Brainstorm

Brainstorm the sub-project with the user. Decisions captured.

STEP 02

Spec + plan

Write the design spec. Then the implementation plan.

STEP 03

Build

Implement on a feature branch. PR opened against main.

STEP 04

DA review

Fresh-session review. Blockers + Serious must be fixed or formally waived. Then merge.

Severity ladder

Blocker

Cannot ship as-is. Must be fixed before merge.

Serious

Significant risk. Must be fixed or formally waived with rationale.

Minor

Worth noting. Can be deferred to a follow-up.

Nit

Stylistic / preference. Optional fix.

S0 runs two DA passes

Conventions

The rules that keep three tracks consistent.

Branching

main is protected. Every sub-project lives on a feature branch named <track>/<sub>-<slug>.

mobile/SB1-scaffold-theme marketing/SA-landing backoffice/SC1-rbac

Commits

Conventional Commits — feat: · fix: · chore: · docs: · refactor: · test:. Scope encouraged.

feat(mobile): introduce SmsSource interface fix(SB2-da-blocker-1): money is int cents

ADR format

Markdown, numbered sequentially in docs/decisions/NNNN-slug.md. Required sections: Status, Context, Decision, Consequences, Alternatives Considered.

Brand-token sync

One-way: catalogue → TS → generated Dart (committed). Husky pre-commit regenerates on staged brand changes. CI re-runs and fails on diff. Drift structurally impossible.

CLAUDE.md per area

Each area has its own CLAUDE.md (root + mobile + marketing + backoffice). A session reads root + the per-area file for its working scope. Hard cap ≤800 lines per file.

PR checklist

Tests run · DA review link · voice check · privacy boundary check · brand-token sync check · linked spec reference. Lives in .github/PULL_REQUEST_TEMPLATE.md.