11 KiB
11 KiB
Engineering Reference Manual Update Plan
Status: ✅ COMPLETE — v0.2.1 phase (2026-06-28, 9 batches) + ✅ v0.2.x phase (2026-07-08, single comprehensive pass)
Goal: bring docs/Engineering_Reference_Manual.md into alignment with the current
relationship-app codebase. Verify every claim, file path, function name,
collection name, and architectural fact. Never assume.
Phase 2 (2026-07-08) — single comprehensive pass
Triggered by the 2026-07-08 Cloud Functions v2 deploy (B0–B6d, Node 22 bump, 5 per-game part-finished triggers) + the R30 games/UX/seed round + the b99a8338 RevenueCat↔Firebase-Auth identity link. Single comprehensive pass rather than the original 9-batch plan because the changes were concentrated in three areas (Cloud Functions, Billing, Daily question) and the manual had drifted in known directions.
What changed (Phase 2)
- Cloud Functions — replaced the stale functions tree with the v2 layout (added
options.ts,log.ts, thepush.ts/quietHours.ts/idempotency.ts/pruneTokens.ts/time.tsshared infra,releaseKey/,backup/,dates/onDate*,couples/aggregateOutcomes,notifications/sendStreakReminder+sendThinkingOfYouCallable). ReplacedonGamePartFinished(single) with the four per-game part-finished triggers (onThisOrThatPartFinished,onWheelPartFinished,onHowWellPartFinished,onDesireSyncPartFinished). Added the v2-migration deploy-failure pattern landmine (FUNCTIONS-V2-DEPLOY). Webhook reliability section now states the webhook is not deployed (RevenueCat project not yet created). - Daily question lifecycle — replaced the "picks a random active free question" description with the server-authoritative, mode-aware, deterministic picker that mirrors the client's
DailyModeResolver; added a new sub-section### Server-authoritative mode-aware deterministic selectionwith the frozen DOW → mode map; noted the picker is FROZEN againstdaily_fun_mcfor HowWell/Desire Sync pool hygiene. - Billing — added the
Purchases.logIn(firebaseAuth.currentUser!!.uid)identity-link flow (commitb99a8338) and theBillingExceptiontyped error mapping; added a "Currently NOT deployed" callout on the webhook section that points to the Webhook reliability deploy steps. - iOS section — corrected the Repository layout iOS
Crypto/block (it is no longer empty; ships the R24 E2EE code) and the "pairing from iOS currently fails" claim (it does not, for the schemaVersion 2 path; schemaVersion 3 is still infrastructure-gated perIOS_E2EE_STATUS.md). - TOC + anchors — added the new sub-anchors (
server-authoritative-mode-aware-deterministic-selection,webhook-reliability,schedule,server-verified-entitlements,webhook,premium-gated-features-and-gate-pattern); fixed three pre-existing broken anchors (#foreground-game-alert-banner-r10,#ios--android-sealed-answer-bridge-wrapreleasekeycallable,#recovery-phrase-change-desync--...). - New landmines —
BANNER-LIFE-001(R30 game banner lifecycle) +FUNCTIONS-V2-DEPLOY(2nd-gen deploy / CPU-quota / Eventarc propagation pattern).
What was NOT changed (Phase 2 — deliberately)
- The Android Gradle config drift (
versionCode = 1,versionName = "0.1.0"inapp/build.gradle.ktswhile HISTORY.md describes v0.2.1) is already flagged in the manual ("build config has drifted from HISTORY; do not ship a release until they're reconciled"). Bumping the version is a release-readiness task, not a docs task. - The iOS E2EE section (sub-section "iOS E2EE gap (status as of current batch)") was already accurate after the R24 work; left unchanged.
- The "Files that must never be committed" gitignore + the iOS CryptoKit guidance section were both already correct.
Approach
- Batch-based. Each batch covers one major section or a coherent set of subsections. One agent/turn per batch.
- Evidence-first. For every factual claim in the manual, verify against the repo (grep, read file, run build/test if needed).
- Log everything. Each batch updates this plan with findings and changes made.
- Ripley coordinates. Ripley does not code unless necessary; Bishop or subagents may verify builds/docs.
Batches
Batch 1 — Front matter + System overview + Repository layout
- Read:
## How to use this documentthrough### Shared configuration. - Verify all directory paths under
app/src/main/java/app/closer/,functions/src/,functions/dist/,res/drawable-*. - Flag missing or renamed directories/files.
- Update any stale paths or naming.
Batch 2 — Authentication, pairing, couples model
- Read:
## Authentication and pairing flowthrough### Key Cloud Functions. - Verify auth files, pairing flow files,
couplescollection fields, recovery phrase implementation. - Cross-check
firestore.rulesfor the rules described. - Update if code diverges from doc.
Batch 3 — E2EE model + Firestore data model
- Read:
## End-to-end encryption modeland## Firestore data model. - Verify crypto files, encryption versions, collection schemas, field names.
- Check
firestore.rulesregex helpers and invariants. - Update data model tables if collections/fields changed.
Batch 4 — Daily question lifecycle + Cloud Functions module
- Read:
## Daily question lifecycleand## Cloud Functions. - Verify function triggers, handlers, schedules, module responsibilities.
- Cross-check
functions/src/tree. - Update if functions were added/removed/renamed.
Batch 5 — Firestore security rules
- Read:
## Firestore security rules. - Line-by-line verify against
firestore.rules. - Note any rules in the file not documented, or documented rules not in file.
Batch 6 — Billing + Notifications
- Read:
## Billingand## Notifications. - Verify RevenueCat integration files, entitlement checks, webhook handler.
- Verify notification classes, quiet hours, deep-link routing.
- Update for quiet-hours server-side suppression if doc still says local-only.
Batch 7 — iOS-specific + Build and release
- Read:
## iOS-specific notesand## Build and release. - Verify iOS project state (is it still broken? still exists?).
- Verify build commands, secrets, ProGuard, Functions deploy commands.
- Update stale commands or iOS status.
Batch 8 — Known landmines and recent fixes (cross-cutting)
- Read:
## Known landmines and recent fixes. - Verify each listed issue ID and fix matches git history and current code.
- Add any missing recent landmines (e.g., theme scanner, quiet hours server-side).
- Prune obsolete entries.
Batch 9 — Final review, TOC update, formatting
- Update
## Table of Contentsif headings changed. - Run markdown lint / build check if applicable.
- Final pass for consistency.
Status tracking
| Batch | Status | Findings | Changes made |
|---|---|---|---|
| 1 | ✅ done | core/feature/ note inaccurate (dir doesn't exist); data/questions/ listed QuestionDao but it's in data/local/ |
Corrected core/feature/ note; moved QuestionDao to data/local/; kept QuestionJsonParser in data/questions/; updated older-description note. |
| 2 | ✅ done | No anonymous sign-in or account linking in code; Android uses legacy Google Sign-In SDK (idToken), not Credential Manager; encryptionMigrationUsers field does not exist |
Removed anonymous auth and account-linking claims; corrected Google Sign-In description; removed encryptionMigrationUsers from couples model and added note that encryptionVersion is always 2. |
| 3 | ✅ done | /users/{uid} model missing sex, partnerId, plan, lastActiveAt, notification prefs, quiet-hours, fcmToken; hasPremium is not a real root field (premium lives in /entitlements/premium); /couples/{coupleId} listed non-existent encryptionMigrationUsers; date plan fields wrong; date plan preference fields wrong; bucket list fields wrong; missing /answers/{userId}/secure/{doc} for schemaVersion 2 |
Updated /users/{uid} to full allowlist; removed hasPremium root field and added note about /entitlements/premium; removed encryptionMigrationUsers; corrected date plan, preference, and bucket list fields; added secure subdoc to daily-question model. |
| 4 | ✅ done | Handler table missing functions (syncEntitlement, sendDailyQuestionProactiveReminder, sendReengagementReminder, sendChallengeDayReminders, unlockDueMemoryCapsules, sendGentleReminderCallable, onEntitlementChanged, onAnswerRevealed, onCoupleLeave, leaveCoupleCallable, submitOutcomeCallable, scheduledOutcomesReminder, onGamePartFinished, notifyOnDateMatch); still listed removed health endpoint and old name createDateMatchOnMutualLove; webhook section said 200-ack-before-process (now process-before-ack); scheduledOutcomesReminder timezone wrong |
Removed health; added all current functions and corrected notifyOnDateMatch; updated module responsibilities; corrected webhook to process-before-ack with 500-on-failure; fixed schedule timezones (only assignDailyQuestion, sendDailyQuestionProactiveReminder, sendReengagementReminder use America/Chicago). |
| 5 | ✅ done | users/{uid} section still described non-existent hasPremium root field; couples/{coupleId} section said all client writes denied (create is shape-restricted but possible); helper paragraph listed non-existent isStartingEncryptionMigration/isCompletingOwnEncryptionMigration |
Updated users/{uid} to clarify plan is client-written and premium lives in /entitlements/premium; corrected couples create/update description; removed migration-helper references. |
| 6 | ✅ done | Billing Webhook flow still said "ack 200 then process" (process-before-ack was fixed in Batch 4 but Billing section had stale duplicate); missing CouplePremiumChecker; Notifications said quiet-hours server-side suppression not implemented (it is, via recipientInQuietHours); Notifications said notification_queue reads denied for clients (Android reads it for Together feed); onEntitlementChanged handler table description said it mirrors plan (it notifies partner instead) |
Updated Billing webhook flow; added CouplePremiumChecker note; corrected quiet-hours to server-side-implemented; corrected notification_queue read claim; fixed onEntitlementChanged description. |
| 7 | ✅ done | iOS E2EE gap paragraph said iOS create invite writes an invite with null E2EE fields (server now rejects empty data, so no invite is created); ProGuard section claimed Tink reflection paths are kept (they are not in current rules) | Updated iOS create-invite consequence to "rejected by server"; clarified ProGuard does not currently keep Tink. |
| 8 | ✅ done | Theme landmine entry said C-ART-EDGE-002 still open (R13 fixed it); missing the mandatory theme-scan.sh Pass C pre-check |
Updated theme landmine to mark C-ART-EDGE-002 closed and document scripts/theme-scan.sh as mandatory pre-check. |
| 9 | ✅ done | TOC incorrectly nested Premium-gated features under Notifications; broken anchor [iOS E2EE gap](#ios-e2ee-gap); Repository layout still claimed iOS creates v0 couples |
Removed misplaced TOC nesting; fixed broken anchor; corrected iOS Repository layout claim to "pairing fails". |
Notes
- If a section is found to be mostly correct, still spot-check a few claims.
- If a section is wildly out of date, rewrite it and note the divergence.
- Commit after each batch (per Git Discipline Rules).