Skip to content

Search is only available in production builds. Try building and previewing the site to test it out locally.

Seven decisions the corpus needs and does not have: MTProto proxy, i18n, two-device conflict, session revocation, account lifecycle, notification policy, backup/export

Источник: dev/fera-research/docs/oc1/019-missing-decisions-proxy-i18n-conflict-revocation.md (read-only; сгенерировано scripts/sync-docs.mjs)

Seven decisions the corpus needs and does not have: MTProto proxy, i18n, two-device conflict, session revocation, account lifecycle, notification policy, backup/export

Section titled “Seven decisions the corpus needs and does not have: MTProto proxy, i18n, two-device conflict, session revocation, account lifecycle, notification policy, backup/export”
  • kind: question

  • area: protocol / storage / modules / ui

  • evidence — each verified by exhaustive grep across ~/dev/fera/project-design/context/*.md (excluding conversation.md):

    1. No MTProto/SOCKS proxy support anywhere. Telegram’s MTProto proxy and SOCKS5 connection types are decades-old core features. OQ.md:562-565 covers only the web proxy, explicitly deferred to v1.5+ (OQ.md:567-568). Grep for proxy/SOCKS/connection-type across ADR/TECHSPEC/QA/RFC → only the OQ-017 heading. TECHSPEC.md:85-87 specifies reconnection (backoff, health-check) but never how one connects.
    2. No i18n/localization. Zero occurrences of i18n, l10n, localization, gettext, locale in ADR/TECHSPEC/QA/RFC. The canonical tree (OQ.md:664-700) has no locale/translation directory. Yet NAMING-UX.md:96 targets Russian-speaking reviewers, NAMING-UX.md:52 requires names that “read fine across EN/RU contexts”, and Telegram’s audience is multilingual — while ADR.md:170-172 makes 1:1 pixel fidelity a goal.
    3. No two-device conflict resolution. ADR.md:333-336 notes “Multi-device read-state sync is server-authoritative” and models read-state, but nothing decides edit/delete ordering, an outbox item sent from two devices, unread races, or reconciliation when the local store (declared source of truth, ADR.md:307-311) is mutated by a second client. ADR.md:313-315 (outbox) is written as if there is one writer.
    4. No session revocation / device-replacement policy. ADR.md:849’s “key revocation” is module-signing keys only. Nothing covers “terminate other sessions”, QR login, session export/import, or what happens to locally cached content when a session is revoked. Sharpened by ADR.md:480-482 — a secret chat is per-device and history does not carry over, so device replacement has real data-loss implications.
    5. No account lifecycle. TECHSPEC.md:418 and OQ.md:692 (data/accounts/<account-id>/) assume per-account data, but nothing decides what happens on logout/remove-account (wipe? keep? re-key?), account migration to another device, or per-account encryption keys — while ADR.md:625 derives one content key from the user’s passcode (singular) and OQ.md:692’s layout is per-account.
    6. Notification policy has no ADR. RFC.md:147-153 and TECHSPEC.md:418-429 assert that a NotificationActor owns “global mute/batching/priority policy across all accounts” — a design decision asserted in two prose docs with no ADR, no OQ, and no QA gate. Undefined: per-account vs global mute precedence, batching window, DND/focus modes, suppression while focused, thread collapse. Also ambiguous ownership: TECHSPEC.md:427-429 puts delivery inside the Feature module, while ADR-028 moved the heaviest platform work to the Native axis (ADR.md:940-942).
    7. No backup/export stance. ADR.md:485 gestures at a “different backup/compaction posture” for secret chats and never returns; for the main instance, a client whose whole model is “my data is local and encrypted with a passcode-derived key” (ADR.md:307-311, ADR.md:625) has no stated answer on export, cloud backup, or loss.
    • Two more that are adjacent and cheap: message drafts / edit-delete semantics (absent; local-first editing with server-authoritative ordering), and crash-report mechanism (OQ.md:900-905 and NAMING-UX.md:80-81 ship an in-app bug report + self-hosted Sentry with no decision on what a payload contains — and since OQ.md:903-905 makes telemetry an unloadable module, a crash in or without it has no path).
  • severity: high

Every item above is something the architecture as written assumes but never decides, and each one surfaces as an architectural rewrite rather than a feature, because the corpus’s chosen patterns make them structural:

  • Proxy (1) is a grammers-fork-level concern (ADR-026 already gives us the fork, so it’s cheap now and expensive after the protocol surface hardens — connection establishment, DC routing, reconnect semantics per TECHSPEC.md:85-87, and the health-check design all assume a direct TCP path).
  • i18n (2) collides with 1:1 pixel fidelity (ADR.md goals) and with ADR-030’s decision to compile style tokens KDL→rkyv — a text-shaping pipeline (Parley) with per-script line-breaking, and a right-to-left mirroring question for every UI axis. Deciding i18n after the renderer, the style format and the Native text-input slots are built means re-deciding all three.
  • Two-device conflict (3) is the deepest one, because ADR-010 makes the local store the source of truth while Telegram’s server is authoritative for history. The corpus has single-writer assumptions baked into the outbox (ADR.md:313-315) and no reconciliation rule for mutations arriving from a second client.
  • Account lifecycle (5) is a direct consequence of my finding 007 (multi-account specified once, contradicted everywhere) and of the single-passcode key derivation: a second account either shares the content key (bad) or needs per-account key material (unowned work).
  • Notification policy (6) matters more than it looks because OQ.md:151 bakes “1 main + 1 secondary (notifications merge)” into the frozen benchmark scene — the corpus is already benchmarking a policy nobody has decided.

The pattern: ADR-level decisions leaked into prose. Six of these are architecture questions (who owns what, what is guaranteed) sitting in TECHSPEC/RFC body text or in nothing at all. Per README.md:41-45, those belong in ADR.md, and questions that block specific work belong in OQ.md. Neither happened.

Варианты решения (tradeoffs)

Section titled “Варианты решения (tradeoffs)”
  • (A) File each as an OQ now, decide the cheap ones immediately. Keeps the corpus’s own discipline; costs ~7 short OQ entries. No new concepts.
  • (B) File as ADRs directly for the ones that are clearly decisions (account lifecycle, notification policy, backup stance); OQ only for genuinely open design questions (two-device conflict, proxy policy).
  • (C) Defer all to a “v0.9 gaps” review before the scope freeze (which OQ.md:582 says is gated on OQ-019’s feature survey, still “planned, not started”). Risk: the scope freeze then includes features nobody designed for, which is exactly how the secret-chat RFC contradiction arose (my finding 011).
  • (D) Ignore. Reject.

(B) for the three that are already decisions-in-prose; (A) for the four that are genuinely open. Concretely:

  1. ADR now — Account lifecycle (fixes the passcode-singular vs per-account-layout conflict from finding 007 and gives logout a defined data disposition); Notification policy (global-vs-per-account mute precedence, batching window, focus suppression, and axis ownership — Feature vs Native); Backup/export stance (a deliberate “none in v1, export is a v1.5 feature” is a legitimate and important decision to write down, because silent data loss is otherwise the default).
  2. OQ now, with a decision date attached — MTProto proxy (recommend: design it in the fork now, ship it in v1 — it is table stakes and the fork is the cheapest moment); i18n (recommend: decide script coverage and RTL stance before the renderer/style pipeline hardens; at minimum decide whether the style format and the Native text slots need to be RTL-aware); two-device conflict (recommend: a reconciliation policy where server ordering wins for history mutations, local wins for unsent outbox, and read-state follows ADR-011’s optimistic-local model); session revocation (recommend: revoke sessions deletes the account’s decrypted caches and refuses to re-encrypt orphaned data).
  3. Crash reporting deserves an ADR too, because OQ.md:903-905’s “telemetry is an unloadable module” is false for the crash case itself — the corpus should decide that a crash always produces a local report bundle attachable to the in-app button, so removing telemetry degrades to “nothing leaves the machine”, never to “nothing is captured”. Note the interaction with finding 006: a minidump can contain decrypted message text resident in RAM.
  4. Add one line to QA.md’s gates for each of the three ADR-backed items, so they do not become the class of thing finding 014 documents.