From 3303d88a5b2e91c47b0c8efb46899ca7da039d33 Mon Sep 17 00:00:00 2001 From: foxyz Date: Sat, 12 Sep 2026 00:16:21 +0300 Subject: [PATCH] Docs: record internet test, tonight's connect/logging fixes, git init; correct media-path details --- HANDOFF.md | 50 +++++++++++++++++++++++++++----------------- docs/ARCHITECTURE.md | 23 +++++++++++++------- docs/PROTOCOL.md | 3 ++- docs/ROADMAP.md | 8 ++++++- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/HANDOFF.md b/HANDOFF.md index 726b90f..9df53c8 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,11 +1,16 @@ # HANDOFF — sync_relay_project (watch-together app) -Date: 2026-09-12. Phases 0–4 + presence hardening + UI redesigns done, -all green (core 42, server 40, desktop 17). Black screen (§8) -DIAGNOSED + FIXED (avatar-texture teardown race; Visibility keep- -mounted). Bisect flags (legacy/minimal/nosheet) still in app.dart — -remove once stable. Prior chat may be unreliable; this file plus -`docs/` is the full state. +Date: 2026-09-12 (updated late session). Phases 0–4 + presence hardening ++ UI redesigns done, all green (core 42, server 40, desktop 17). +Black screen (§8) DIAGNOSED + FIXED (avatar-texture teardown race; +Visibility keep-mounted) + VERIFIED, incl. over internet. Bisect +flags (legacy/minimal/nosheet) still in app.dart — remove once +stable. Internet test PASSED (WAN port 6969, 09-12). Tonight's +fixes: server logging wired into app (`initLogging` + hello logs), +Cancel aborts pending connect, first-join failure no longer +retry-loops. Git repo INITIALIZED (commit 427d851, root +.gitignore). Prior chat may be unreliable; this file plus `docs/` +is the full state (`docs/ROADMAP.md` is now the phase tracker). ## 1. What this is @@ -89,9 +94,9 @@ kick kills sync+video, no relay memory growth. post-quorum). - `docs/`: PROTOCOL.md (v4 + quorum + 15/30 s timeouts + isClosed note, normative), ARCHITECTURE.md (+health rule), mpv-http-contract.md. -- `deploy/`: systemd unit. No git repo anywhere (recommending `git - init` was never approved — ask before creating one; bisection is - currently impossible, which hurt on §8). +- `deploy/`: systemd unit. Git repo initialized 09-12 (`git init`, + root `.gitignore`, initial commit 427d851 covering phases 0–4 + + tonight's connect/logging fixes). Bisection is possible again. ## 4. Protocol v4 + policy (see PROTOCOL.md for normative detail) @@ -215,24 +220,31 @@ the shared GL context fails silently ⇒ black. Legacy chips never unmounted and minimal never mounted, which is why they survived. Fix: center overlay is Visibility(visible + maintainState + maintainAnimation + maintainSize) — avatars stay mounted, paint -skipped when hidden. Verified by user with full tree. +skipped when hidden. Verified by user with full tree, and holds +over internet (WAN 2-client test, port 6969, late 09-12) — CLOSED. RULE: never unmount GPU-textured widgets on a transport-gated branch; keep mounted + skip paint. Bisect screens (legacy/minimal/nosheet + SYNC_RELAY_UI switch in app.dart) still wired — delete on approval. session_screen.dart may still hold the user's commented bisect lines — restore or drop. -## 9. Next (ordered) +## 9. Next (ordered, updated 09-12 late session) -1. §8 black screen — diagnose with user, then fix. -2. 2-client LAN soak (manual, user-driven). -3. 1.4 GB real-file media test (user resupplies Jellyfin URL; - contains api_key — NEVER paste into files). -4. Cache-exhaustion long outage via shaper --kill-after (Phase 5 - chaos assertion, never run). -5. Internet test: plain TCP works in theory; needs forwarded port - or Tailscale; expect more slowdown engagement on latency. +1. §8 black screen — CLOSED (fix verified incl. over internet). +2. Remove bisect flags (legacy/minimal/nosheet) in app.dart. +3. 2-client LAN soak (manual, user-driven; WAN test passed, LAN + still untested). +4. 1.4 GB real-file media test (user resupplies Jellyfin URL; + contains api_key — NEVER paste into files). +5. Cache-exhaustion long outage via shaper --kill-after (Phase 5 + chaos assertion, never run). 6. Sounds swap-in (§7) after audition. +7. File-join wart: welcome mediaUrl uses advertiseHost 127.0.0.1, + remote file joiners fail-open then self-heal on first room + broadcast — fix via Host header, or leave (cosmetic). +8. `/health` is unauthenticated and broadcasts the full media URL + (incl. api_key when the link carries one) — acceptable on LAN, + noted now that 6969 faces the internet. Environment: dart 3.14 beta, flutter 3.48 beta, mpv+ffmpeg present, ~/Videos/chiyo.mp4 sample. Never kill the user's Syncplay mpv instance. No git repo — ask before creating one. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index c5882d8..e868c9b 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -2,7 +2,9 @@ One binary, three modes. `packages/server` (Relic) is embedded, not a separate product. -- **Client**: GUI Join, sync WS client (`web_socket_channel` in `packages/core`) + mpv. No server code runs. +- **Client**: GUI Join, sync WS client (`web_socket_channel` in + `apps/desktop`, NOT `packages/core` — core stays Flutter-free) + + mpv. No server code runs. - **Server+Client (Host)**: GUI Host starts `packages/server` in-process, binds port, self-connects via loopback. Host opens ports, runs traffic. Clients open nothing outbound-only. - **Headless**: `--headless`, same server package, no window/player init. @@ -18,7 +20,9 @@ Two ways to watch, same sync engine, same Range endpoint: 1. **Links (primary, shipped):** host shares an http(s) media URL (e.g. a Jellyfin Download URL). Viewers stream it directly; the - server is sync-authority only (`media.url`, no `mediaUrl`). This + server is sync-authority only. The URL travels as `media.url` + in room broadcasts and as welcome `mediaUrl` (set to the shared + URL when the server holds no file). This covers most sessions — proxying is usually unnecessary. 2. **File relay (secondary, local-file half shipped):** host serves bytes from their own machine through the server's token-gated @@ -30,9 +34,11 @@ Two ways to watch, same sync engine, same Range endpoint: logs only, never to disk. Backends behind `MediaSource` (`packages/core/lib/src/media_source.dart`): -`FileMediaSource` (local file — SHIPPED, wired into -`mountSessionMediaRoute`); `HttpSource` (server fetches a remote URL -and re-serves it — DEFERRED, Phase 8). `resolveMediaRequest` stays +`FileMediaSource` (local file — SHIPPED as an abstraction, but the +live route serves `SessionMedia.file` directly via `file.openRead`; +nothing in `packages/` references `FileMediaSource` today); +`HttpSource` (server fetches a remote URL and re-serves it — +DEFERRED, Phase 8). `resolveMediaRequest` stays framework-agnostic so both ride the same tested Range table. ## Deferred: remote-host upload tunnel (NOT active protocol) @@ -48,9 +54,10 @@ chunk 256 KiB, credit window 8 (≈2 MiB in flight), max 16 concurrent are reserved for this. No code exists; direct-serve covers v1 (host IS the server, opens ports itself). -Host playback goes through loopback like everyone else's -(`http://127.0.0.1:/…`) — same code path as remote viewers, so -server bugs surface on the host screen first. Deployment ladder, +On file relay, host playback goes through loopback like everyone +else's (`http://127.0.0.1:/…`) — same code path as remote +viewers, so server bugs surface on the host screen first. (On +links the host plays the direct URL.) Deployment ladder, cheapest first: host's own PC (LAN, or internet with port-forward) → same binary `--headless` on a friend's always-on box → cheap VPS (CGNAT escape; TLS/Caddy deferred with this tier). diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md index 8a1a00c..d8f95c5 100644 --- a/docs/PROTOCOL.md +++ b/docs/PROTOCOL.md @@ -90,7 +90,8 @@ gate passes. No authority check in v1 (same trust basis as force). proto must equal server proto; secret is the room password; avatar ≤64 KiB; failures get `err` + close. `sid="default"`, map keyed for -later multi-session. mediaUrl only when the server holds bytes. +later multi-session. `mediaUrl` carries the playable URL: a built +`/m/…` URL when the server holds bytes, otherwise the shared link. ## Media endpoint (Phase 1, unchanged) diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index ff1f3ac..c2636e7 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -54,10 +54,16 @@ Follow-ups landed: NaN guards, name/chat caps, stale vs leave feed, Shipped: SyncClient framing, RoomDiff (eventId diff, 0.95× latch), media_kit wiring, Space=ready, avatars, toasts+sheet, health display, reconnect loop. Counts at last green: core 42, server 40, desktop 17. +Late 09-12 session: internet test PASSED (WAN, port 6969, 2-client); +server logging wired into app (`initLogging` in `main.dart` + hello +join/reject logs in `room_hub.dart`); Cancel aborts a pending +connect (`SyncClient.disconnect` completes the welcome future); +first-join failure shows the dialog and stops (auto-reconnect only +after an established session drops). Open exits (manual, user-driven): remove bisect flags in `apps/desktop/lib/app.dart`; 2-client LAN soak; 1.4 GB real-file test (user resupplies URL, never paste api_key into files); -cache-exhaustion long outage; internet test (forwarded port/Tailscale). +cache-exhaustion long outage. ## Phase 5 — Resilience (PARTIAL)