docs: complete audit pass — server checks, upstream checks, code architecture

Server findings:
- Synapse 1.153.0 is FULLY UP TO DATE (latest as of 2026-05-19)
- MSC4140 (scheduled msgs), MSC3771 (thread receipts), MSC4133 (extended profiles)
  all CONFIRMED supported via unstable_features flags
- MSC3892 (reaction redaction), MSC3266 (room summary) BLOCKED — not supported
- MSC4306 (thread subscriptions) BLOCKED — not supported

Upstream Cinny confirms (removed from build queue):
- Back to Latest button (RoomTimeline.tsx:2180), Mark rooms as read (Home.tsx:73),
  Tombstone/upgrade banner (RoomTombstone.tsx), Speaking indicator (useCallSpeakers.ts),
  Spoiler rendering (ImageContent/VideoContent — blur+click-reveal), Report message

Architecture facts documented:
- AvatarImage child constraint (no children — wrap externally)
- Sidebar translateX blocks backdrop-filter
- EC bridge: no participant events (use m.call.member state events instead)
- No in-app toast system (must build from scratch)
- Voice player at AudioContent.tsx:44, notification sounds hardcoded in ClientNonUIFeatures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-01 13:09:57 -04:00
parent faddde65fa
commit 74cde50df7
+66 -19
View File
@@ -13,11 +13,64 @@ Legend:
- `[SERVER CHECK]` — depends on a Synapse feature or MSC that may not be enabled on `matrix.lotusguild.org`
- `[LOW PRIORITY]` — agreed to add but deprioritized; implement after everything else
- `[EXTREME COMPLEXITY]` — multi-sprint, architectural; plan separately before touching
- `[BLOCKED]` — cannot implement until a dependency (server upgrade, upstream MSC, other task) is resolved
Status: `[ ]` pending · `[~]` in progress · `[x]` completed
---
## AUDIT RESULTS — completed June 2026
### Server Status
- **Synapse version:** `1.153.0` (released 2026-05-19) — **FULLY UP TO DATE**, no upgrade needed
- **Matrix spec reported:** up to `v1.12` formally, but newer MSC features available via `unstable_features`
- **MSC feature flags confirmed ON:** `msc4140` (delayed messages) · `msc3771` (thread receipts) · `msc3440.stable` (threading) · `msc4133.stable` (extended profiles) · `simplified_msc3575` (sliding sync)
- **MSC feature flags confirmed OFF:** `msc4306` (thread subscriptions — BLOCKED) · `msc3882` · `msc3912` · `msc4155`
- **MSC3266** (room summary, v1.15): endpoint returned 404 — NOT available on this server
- **MSC3765** (rich room topics, v1.15): NOT available as stable, but client-side rendering is still worth doing
- **MSC3892** (relation redaction): not listed in flags — NOT supported, feature BLOCKED
- **MSC4260** (report user, v1.14): server at v1.12 formally — NOT available as spec endpoint; **however** report user already exists upstream in Cinny (message reporting via `reportEvent`)
- **MSC4151** (report room, v1.12): merged at exactly v1.12 — should be available ✅
### Upstream Cinny Features Confirmed (do NOT add to our codebase)
| Feature | Location in upstream |
|---|---|
| "Jump to Latest" / Back to bottom button | `RoomTimeline.tsx:2180-2192` |
| Mark rooms as read (per section) | `Home.tsx:73-102`, `DirectTab.tsx:29-61` |
| Room upgrade / tombstone banner | `RoomTombstone.tsx`, `RoomUpgrade.tsx` |
| Visual speaking indicator | `useCallSpeakers.ts:8-60`, `MemberSpeaking.tsx:1-78` |
| Image + video spoilers (blur/reveal) | `ImageContent.tsx`, `VideoContent.tsx` — CSS blur(44px), click to reveal |
| Report message (per event) | `Message.tsx:588-709``mx.reportEvent()` |
| Drag-and-drop file upload | `useFileDrop.ts` — works but has overlay dismiss bug |
### Upstream Cinny Features Confirmed MISSING (we should build these)
Quick Switcher, Sidebar filter, Favorite rooms, Invite link generator, Edit history modal,
Export history, Room preview before joining, Suggested rooms display, Server notices styling,
DM last-message preview, Media gallery, Knock-to-join full UX
### Code Architecture Facts (relevant to implementation)
| Finding | Impact |
|---|---|
| `folds AvatarImage` does NOT accept children | Avatar overlays/frames must wrap the Avatar component externally, not nest inside it |
| Sidebar `SidebarItem` has `translateX` on hover | CSS `backdrop-filter` won't work on sidebar items directly — apply to parent wrapper instead |
| Element Call bridge has NO join/leave participant events | Join/leave sounds (#89) must use `m.call.member` Matrix room state events instead |
| Element Call bridge has NO audio level events | Speaking indicator uses CSS polling of EC iframe DOM — no direct event bridge |
| No in-app toast system exists anywhere | Toast redesign (#80) must build a full `ToastProvider` + queue system from scratch |
| Voice message player: `AudioContent.tsx:44-223` | Speed control (#8): add `playbackRate` on the hidden `<audio>` element at line 217 |
| Notification sounds: 2 hardcoded `.ogg` files | Custom sounds (#22): replace file path with settingsAtom value |
| Chat backgrounds: `chatBackground.ts`, applied to `<Page>` in `RoomView.tsx` | Animated wallpapers (#77): add new entries returning CSS animation keyframe strings |
| Push rule UI: mode switcher only, no custom rule creation | Full push rule editor (#61) is a significant build from scratch |
| URL preview: `urlPreview: true` default, `encUrlPreview: false` default | Task #49: only need to change `encUrlPreview` default to `true` + add warning text |
| Private read receipts: `ReceiptType.ReadPrivate` already in SDK | Task #34: very simple — `markAsRead()` in `notifications.ts` already has `privateReceipt` param |
| Right-click room menu: 6 items (Mark read, Notifications, Invite, Copy Link, Settings, Leave) | Task #102: add Mute-with-duration submenu and consolidate |
| Glassmorphism: sidebar uses `translateX` transform | Must apply `backdrop-filter` to a parent div, not the sidebar element itself |
| JetBrains Mono: NOT bundled, relies on system fonts | Font selector (#98): must bundle fonts as `public/font/*.woff2` files |
| GIF links (Giphy/Tenor): render as generic OG preview cards, NOT auto-embedded | Task #42: inline GIF embed needs to be built |
| Composer toolbar buttons (in order): Formatting, Emoji/Sticker, GIF, Location, Voice, Send | Task #43: configurable toolbar is straightforward — buttons are a sequential array |
| Message hover toolbar: quick reactions row already exists inside Menu component | Task #92: quick reaction bar is already partially there via `MessageQuickReactions` |
---
## COMPLETED
- [x] Audit & document: who reacted hover tooltip — README + landing page
@@ -65,25 +118,20 @@ Cache the response in component state; no repeated fetches.
### [ ] P0-3 · Server notices distinct rendering (m.server_notice)
**Spec:** CS-API §13.17, stable.
**Confirmed:** Currently server notices arrive as plain DMs — indistinguishable from real messages.
**What:** Detect the `m.server_notice` event type in the timeline renderer. Render with:
- A distinct "Server Notice" header badge (server icon + label)
**Audit result:** CONFIRMED MISSING. Only `M_CANNOT_LEAVE_SERVER_NOTICE_ROOM` error code exists in `src/app/cs-errorcode.ts` — no rendering differentiation. Server notices currently arrive as plain DMs.
**What:** The `m.server_notice` room type is set in `m.room.create` content (`type: 'm.server_notice'`). Detect it via `room.getType() === 'm.server_notice'`. Render with:
- A distinct "Server Notice" header badge (server icon + label) in `RoomViewHeader.tsx`
- Slightly different background color (use `color.Warning` or neutral surface)
- Composer disabled / read-only state in the server notice DM room
- Do NOT show "Send message" input in these rooms
**Where:** `src/app/features/room/RoomTimeline.tsx` (event renderer), `src/app/features/room/RoomInput.tsx` (hide/disable composer).
**[AUDIT REQUIRED]** — Verify how matrix-js-sdk exposes `m.server_notice` — check if it's a room type (`m.server_notice` in `m.room.create`) or per-event content field.
- Composer hidden/disabled in server notice rooms (check room type in `RoomInput.tsx`)
**Where:** `src/app/features/room/RoomViewHeader.tsx` (badge), `src/app/features/room/RoomInput.tsx` (hide composer when `room.getType() === 'm.server_notice'`).
**Complexity:** Low.
---
### [ ] P0-4 · Reaction / relation redaction (MSC3892)
### [BLOCKED] P0-4 · Reaction / relation redaction (MSC3892)
**Spec:** MSC3892, in Final Comment Period.
**What:** When a user removes their reaction (un-reacts), currently a full `m.room.redaction` is sent targeting the reaction event. MSC3892 adds a cleaner relation-scoped redaction. Use the MSC3892 endpoint if the server supports it; fall back to standard redaction otherwise.
Check server capability: `GET /_matrix/client/v1/capabilities` for `m.room.redaction` capability or probe `/_matrix/client/unstable/org.matrix.msc3892/`.
**[SERVER CHECK]** — Verify `matrix.lotusguild.org` supports MSC3892. If not, no change is needed (current behavior is fine); if yes, use the cleaner endpoint.
**Where:** Wherever `onReactionToggle` sends the redaction — likely `src/app/features/room/RoomTimeline.tsx` or a hook.
**Complexity:** Low — conditional API call swap.
**Server check result:** `org.matrix.msc3892` is NOT in the server's unstable_features list — **NOT supported**. Current full-event redaction behavior is correct and should not be changed. This task is BLOCKED until the homeserver adds MSC3892 support. No action needed now.
**Complexity:** N/A — blocked.
---
@@ -173,12 +221,11 @@ If any step is broken, fix it. If all working correctly, close this task with no
---
### [ ] P0-12 · URL Preview default settings + security warning
**What:** In Settings → Privacy (or Messaging), the URL preview toggle should default to ON for both regular and encrypted rooms. Next to the encrypted-room toggle, add a one-sentence security note:
> "URL previews in encrypted rooms are fetched by your homeserver, which sees the URL but not the message context."
This matches Element's approach of informed consent rather than silent disabling.
**[AUDIT REQUIRED]** — Find where URL preview settings are stored in `settingsAtom`. Find the settings UI for URL previews. Confirm current defaults (may already be on by default for non-encrypted rooms).
**Where:** `src/app/state/settings.ts` (default values), `src/app/features/settings/` privacy/messaging panel.
**Complexity:** Low — wording + default value change.
**Audit result:** `settings.ts` line 103: `urlPreview: true` (already on by default) · line 104: `encUrlPreview: false` (encrypted rooms OFF by default).
**What:** Change `encUrlPreview` default to `true` in `src/app/state/settings.ts`. Add a one-sentence security note next to the encrypted-room toggle in the settings UI:
> "URL previews in encrypted rooms are fetched by your homeserver, which sees the URL but not the message content."
**Where:** `src/app/state/settings.ts` line 104 (change default), settings UI file for URL preview toggles (find via grep for `encUrlPreview`).
**Complexity:** Very Low — one default value change + one sentence of UI text.
---