Docs: record internet test, tonight's connect/logging fixes, git init; correct media-path details

This commit is contained in:
foxyz committed 2026-09-12 00:16:21 +03:00
1 parent 427d851a5b
commit 3303d88a5b
4 files changed
+53 -27

No files matched your search

+29 -17
View File
@@ -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;
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).
4. Cache-exhaustion long outage via shaper --kill-after (Phase 5
5. 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.
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.
+15 -8
View File
@@ -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:<port>/…`) — 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:<port>/…`) — 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).
+2 -1
View File
@@ -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)
+7 -1
View File
@@ -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)