From 186b40546b5a00eaf0a39fa911227da2f9dedbcc Mon Sep 17 00:00:00 2001 From: null Date: Sun, 28 Jun 2026 11:14:37 -0500 Subject: [PATCH] =?UTF-8?q?docs(manual):=20Batch=209=20=E2=80=94=20fix=20T?= =?UTF-8?q?OC=20nesting,=20broken=20anchor,=20and=20stale=20iOS=20claim=20?= =?UTF-8?q?in=20repository=20layout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Engineering_Reference_Manual_Plan.md | 4 ++-- docs/Engineering_Reference_Manual.md | 3 +-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/Engineering_Reference_Manual_Plan.md b/Engineering_Reference_Manual_Plan.md index 934d7ea1..0056611a 100644 --- a/Engineering_Reference_Manual_Plan.md +++ b/Engineering_Reference_Manual_Plan.md @@ -82,8 +82,8 @@ collection name, and architectural fact. Never assume. | 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 | in_progress | | | -| 9 | todo | | | +| 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 diff --git a/docs/Engineering_Reference_Manual.md b/docs/Engineering_Reference_Manual.md index bb571bc8..b7e594b7 100644 --- a/docs/Engineering_Reference_Manual.md +++ b/docs/Engineering_Reference_Manual.md @@ -33,7 +33,6 @@ This is the source of truth for Closer's architecture, security model, data mode - [Game session push semantics](#game-session-push-semantics-idempotent-flag-claim) - [Foreground game-alert banner](#foreground-game-alert-banner-r10) - [Notification deep-link routing](#notification-deep-link-routing) - - [Premium-gated features and gate pattern](#premium-gated-features-and-gate-pattern) (under Billing) 11. [iOS-specific notes](#ios-specific-notes) 12. [Build and release](#build-and-release) 13. [Engineering conventions](#engineering-conventions) @@ -171,7 +170,7 @@ iphone/ └── Resources/ # Illustrations, assets ``` -The iOS `Crypto/` folder is **intentionally empty** today. The Swift port defers E2EE parity to a follow-up batch. The current iOS path creates `encryptionVersion = 0` couples and uses the plaintext answer path. See [iOS E2EE gap](#ios-e2ee-gap) for the precise scope and risk. +The iOS `Crypto/` folder is **intentionally empty** today. The Swift port defers E2EE parity to a follow-up batch. Because `createInviteCallable` and `acceptInviteCallable` require E2EE key material, pairing from iOS currently fails. See [iOS E2EE gap](#ios-e2ee-gap-pairing-is-broken-from-ios-today) for the precise scope and risk. `Paywall/` is currently a placeholder; the actual paywall screen is rendered from `Settings/SettingsViews.swift`. A dedicated paywall view is a future cleanup.