Closer/Engineering_Reference_Manua...

9.1 KiB

Engineering Reference Manual Review Plan — Phase 3 (2026-07-08)

Status: COMPLETE — all 13 batches reviewed, 11 issues found and fixed, committed individually, and pushed to dev.

Triggered by _null after the Phase 2 sync (213cfddb) + review pass (d31b58d2). Goal: cross-check every claim in the manual against the live repo + firestore.rules

  • functions/src/ + iOS source + Android source, batch by batch. No skipped sections.

Approach

  • 13 batches, each scoped to one major section of the manual.
  • Evidence-first. For every factual claim (file path, function name, collection name, cron expression, preference field, threshold, AAD string), verify against the live source.
  • One commit per batch per the standing git discipline (one batch = one commit = one push).
  • Log findings to this file as each batch completes.
  • Anchors + TOC verified at the end (Batch 13), not per-batch, to avoid churn.

Batches

Batch 1 — Front matter + System overview + Repository layout (Android + iOS + Cloud Functions + Shared configuration)

  • Read: ## How to use this document through ### Shared configuration (lines ~1-260).
  • Verify all directory paths under app/src/main/java/app/closer/, functions/src/, iphone/Closer/, res/drawable-*, Hilt module list.
  • Cross-check Android package list against the live find app/src/main/java/app/closer -maxdepth 3 -type d.
  • Cross-check iOS file list against ls iphone/Closer/....
  • Cross-check Cloud Functions tree against find functions/src -name "*.ts".
  • Flag missing or renamed directories/files.

Batch 2 — Authentication + pairing + couples doc model + rate limit + recovery

  • Read: ## Authentication and pairing flow (lines ~270-370).
  • Verify auth files in data/remote/FirebaseAuthDataSource.kt, data/repository/FirebaseAuthRepositoryImpl.kt, domain/repository/AuthRepository.kt.
  • Verify couples/{coupleId} field list against acceptInviteCallable.ts + the domain Couple.kt model.
  • Verify rate-limit env values against AuthRateLimiter.kt.
  • Verify recovery phrase flow against RecoveryKeyManager.kt + CoupleEncryptionManager.kt.

Batch 3 — E2EE model (versions, Argon2id, Tink, sealed-answer, ECIES, single-device, iOS bridge)

  • Read: ## End-to-end encryption model (lines ~370-475).
  • Verify each Encryption versions row against firestore.rules regex helpers.
  • Verify the Argon2id v1.3 parameter names + the AAD strings against the actual Kotlin/Swift code.
  • Verify the keybox:v1: wire format against Keybox.swift + ReleaseKeyEncryptor.kt.
  • Verify the wrapReleaseKeyCallable path against the function source.

Batch 4 — Daily question lifecycle + Reveal flow + Thread questions

  • Read: ## Daily question lifecycle (lines ~480-575).
  • Verify assignDailyQuestion schedule + the deterministic picker (DOW → mode map, daily_fun_mc exclusion) against functions/src/questions/assignDailyQuestion.ts + DailyModeResolver.kt.
  • Verify the schemaVersion 2 reveal flow + the read-gated secure/payload subdoc against firestore.rules (the isCoupleAnswerCreate + isEncryptedPayloadUpdate helpers).
  • Verify schemaVersion 3 sealed flow against SealedAnswerEncryptor.kt + isSealedAnswerCreate rules.
  • Verify thread questions path against isSealedThreadAnswerCreate + the model.

Batch 5 — Firestore security rules

  • Read: ## Firestore security rules (lines ~720-810).
  • Line-by-line verify every per-collection note in the manual against firestore.rules.
  • Cross-check helper-function names (coupleEncryptionEnabled, isCiphertext, isUpdatingCoupleRhythm, isUpdatingRecoveryWrap, isCoupleAnswerCreate, isEncryptedPayloadUpdate, isSealedAnswerCreate, isSealedAnswerUpdate, isSealedThreadAnswerCreate, isSealedThreadAnswerUpdate).
  • Note any rules in the file not documented, or documented rules not in file.

Batch 6 — Cloud Functions

  • Read: ## Cloud Functions (lines ~815-845).
  • Verify function triggers, handlers, schedules, module responsibilities.
  • Cross-check functions/src/ tree (already done in Batch 1 but verify exports).
  • Cross-check Schedule table against each function's source.

Batch 7 — Billing

  • Read: ## Billing (lines ~850-920).
  • Verify RevenueCat integration files, entitlement checkers, webhook handler, Purchases.logIn identity link.
  • Cross-check the "Gated features" list against the actual ViewModels that inject CouplePremiumChecker / EntitlementChecker.

Batch 8 — Notifications

  • Read: ## Notifications (lines ~925-1020).
  • Verify FCM setup + tokenRegistrar + quiet hours.
  • Verify each reminder callable's actual schedule + dedupe.
  • Verify game-push semantics against onGameSessionUpdate.ts + the part-finished triggers.
  • Verify the foreground banner surface + the deep-link routing table against PartnerNotificationManager.kt.

Batch 9 — iOS-specific notes

  • Read: ## iOS-specific notes (lines ~1023-1080).
  • Verify Architecture, CloserTheme tokens, XcodeGen setup, build commands, E2EE gap status, CryptoKit guidance.
  • Cross-check iphone/Closer/Theme/CloserTheme.swift for the actual color values.

Batch 10 — Build and release

  • Read: ## Build and release (lines ~1080-1200).
  • Verify Android module/package, biometric recovery phrase reveal, required build secrets, Gradle config, ProGuard rules.
  • Cross-check the iOS build commands against the actual XcodeGen spec.

Batch 11 — Engineering conventions

  • Read: ## Engineering conventions (lines ~1200-1280).
  • Verify the architectural rules (Clean layers, package boundaries, what lives where) against the actual code.
  • Verify the "what NOT to do" list (e.g. raw Firestore listeners, no FirebaseAuth.getInstance() in VMs) is still accurate.
  • Check the version drift (build.gradle vs HISTORY.md) and ProGuard note.

Batch 12 — Known landmines and recent fixes

  • Read: ## Known landmines and recent fixes (lines ~1280-1450).
  • Verify EVERY landmine still applies:
    • Does the file/component it cites still exist?
    • Is the fix still in place?
    • Is the "Re-introduction risk" description still accurate?
  • Look for any landmine whose fix is now in a different file.

Batch 13 — Where to look first

  • Read: ## Where to look first (lines ~1450-end).
  • Verify every file path still exists.
  • Verify the "what to read first for a new area" list still applies to the current code.

Final pass

  • TOC integrity + every anchor resolves.
  • One final commit if any TOC/anchor cleanup is needed.

Phase 3 results (2026-07-08)

Batch Section Issues found Commit
1 Front matter + System overview + Repository layout iOS platform row said "E2EE cross-compatibility not yet implemented" (contradicts the iOS E2EE section below) ef5a2331
2 Auth + pairing + couples doc model + rate limit + recovery Recovery phrase "256-word list" - actual list is 248 entries (WORDLIST array has 248; iOS wordlist is 247 lines = 248 entries with no trailing newline) 1b36eba6
3 E2EE model (versions, Argon2id, Tink, sealed-answer, ECIES) Argon2id memory "46080 KiB" - actual constant is 46 * 1024 = 47104 KiB; iOS-side docstring was already correct 0af6f24a
4 Daily question lifecycle + Reveal flow + Thread questions DOW mode table was partial (missed Saturday mode_weekend_side_quest - Side Quest Saturday) 5e292e66
5 Firestore security rules Missing 3 helper functions (otherCoupleMember, partnerReflectedDate, isPublicKey); wrong regex for isPublicKey; releaseKeys per-collection enforcement said "readable only by recipient" but the rule also allows the sender (for the idempotency existence-check) 5f7c785f
6 Cloud Functions Handler types table mixed onDocumentCreated / onDocumentUpdated / onDocumentWritten into one row; onEntitlementChanged was in a separate "Firestore onUpdate" row but is actually onDocumentWritten aa356148
7 Billing iOS "DefaultEntitlementChecker actor" doesn't exist (the real class is BillingService); gated-features list was wrong (4 of 7 items were not actually gated; chat-media gate was missing) ceb98f4a
8 Notifications "How to gate a new feature" sub-section got merged into the previous paragraph by Batch 7; game-push flag claim was wrong (no notificationsSent map - 4 separate Timestamp fields) 29cc39aa
9 iOS-specific notes Tink template name "SHA128" was a typo - actual is ECIES_P256_HKDF_HMAC_SHA256_AES128_GCM 9330c0c4
10 Build and release RevenueCat version 8.20.0 (stale from v0.2.1) - actual is 10.12.0; iOS purchases-ios 5.x; Glance 1.1.1 missing from the Gradle dependency list 22c816ad
11 Engineering conventions (no issues - every claim verified) b3725463
12 Known landmines and recent fixes A-201 landmine heading (### A-201 - ...) got dropped during the Phase 2 sync - the body content was there but visually merged with the previous landmine's tail 80751f82
13 Where to look first (no issues - all 16 file paths resolve, acceptInviteCallable encryptionVersion=2 verified) c5ead4cb
Final TOC + anchor integrity 30/30 anchors resolve, 0 broken TOC links (this commit)