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) # HANDOFF — sync_relay_project (watch-together app)
Date: 2026-09-12. Phases 0–4 + presence hardening + UI redesigns done, Date: 2026-09-12 (updated late session). Phases 0–4 + presence hardening
all green (core 42, server 40, desktop 17). Black screen (§8) + UI redesigns done, all green (core 42, server 40, desktop 17).
DIAGNOSED + FIXED (avatar-texture teardown race; Visibility keep- Black screen (§8) DIAGNOSED + FIXED (avatar-texture teardown race;
mounted). Bisect flags (legacy/minimal/nosheet) still in app.dart — Visibility keep-mounted) + VERIFIED, incl. over internet. Bisect
remove once stable. Prior chat may be unreliable; this file plus flags (legacy/minimal/nosheet) still in app.dart — remove once
`docs/` is the full state. 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 ## 1. What this is
@@ -89,9 +94,9 @@ kick kills sync+video, no relay memory growth.
post-quorum). post-quorum).
- `docs/`: PROTOCOL.md (v4 + quorum + 15/30 s timeouts + isClosed note, - `docs/`: PROTOCOL.md (v4 + quorum + 15/30 s timeouts + isClosed note,
normative), ARCHITECTURE.md (+health rule), mpv-http-contract.md. normative), ARCHITECTURE.md (+health rule), mpv-http-contract.md.
- `deploy/`: systemd unit. No git repo anywhere (recommending `git - `deploy/`: systemd unit. Git repo initialized 09-12 (`git init`,
init` was never approved — ask before creating one; bisection is root `.gitignore`, initial commit 427d851 covering phases 0–4 +
currently impossible, which hurt on §8). tonight's connect/logging fixes). Bisection is possible again.
## 4. Protocol v4 + policy (see PROTOCOL.md for normative detail) ## 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. unmounted and minimal never mounted, which is why they survived.
Fix: center overlay is Visibility(visible + maintainState + Fix: center overlay is Visibility(visible + maintainState +
maintainAnimation + maintainSize) — avatars stay mounted, paint 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 RULE: never unmount GPU-textured widgets on a transport-gated
branch; keep mounted + skip paint. Bisect screens branch; keep mounted + skip paint. Bisect screens
(legacy/minimal/nosheet + SYNC_RELAY_UI switch in app.dart) (legacy/minimal/nosheet + SYNC_RELAY_UI switch in app.dart)
still wired — delete on approval. session_screen.dart may still still wired — delete on approval. session_screen.dart may still
hold the user's commented bisect lines — restore or drop. 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. 1. §8 black screen — CLOSED (fix verified incl. over internet).
2. 2-client LAN soak (manual, user-driven). 2. Remove bisect flags (legacy/minimal/nosheet) in app.dart.
3. 1.4 GB real-file media test (user resupplies Jellyfin URL; 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). 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). 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. 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, Environment: dart 3.14 beta, flutter 3.48 beta, mpv+ffmpeg present,
~/Videos/chiyo.mp4 sample. Never kill the user's Syncplay mpv ~/Videos/chiyo.mp4 sample. Never kill the user's Syncplay mpv
instance. No git repo — ask before creating one. 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. 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. - **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. - **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 1. **Links (primary, shipped):** host shares an http(s) media URL
(e.g. a Jellyfin Download URL). Viewers stream it directly; the (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. covers most sessions — proxying is usually unnecessary.
2. **File relay (secondary, local-file half shipped):** host serves 2. **File relay (secondary, local-file half shipped):** host serves
bytes from their own machine through the server's token-gated 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. logs only, never to disk.
Backends behind `MediaSource` (`packages/core/lib/src/media_source.dart`): Backends behind `MediaSource` (`packages/core/lib/src/media_source.dart`):
`FileMediaSource` (local file — SHIPPED, wired into `FileMediaSource` (local file — SHIPPED as an abstraction, but the
`mountSessionMediaRoute`); `HttpSource` (server fetches a remote URL live route serves `SessionMedia.file` directly via `file.openRead`;
and re-serves it — DEFERRED, Phase 8). `resolveMediaRequest` stays 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. framework-agnostic so both ride the same tested Range table.
## Deferred: remote-host upload tunnel (NOT active protocol) ## 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 are reserved for this. No code exists; direct-serve covers v1
(host IS the server, opens ports itself). (host IS the server, opens ports itself).
Host playback goes through loopback like everyone else's On file relay, host playback goes through loopback like everyone
(`http://127.0.0.1:<port>/…`) — same code path as remote viewers, so else's (`http://127.0.0.1:<port>/…`) — same code path as remote
server bugs surface on the host screen first. Deployment ladder, 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) → cheapest first: host's own PC (LAN, or internet with port-forward) →
same binary `--headless` on a friend's always-on box → cheap VPS same binary `--headless` on a friend's always-on box → cheap VPS
(CGNAT escape; TLS/Caddy deferred with this tier). (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 proto must equal server proto; secret is the room password; avatar
≤64 KiB; failures get `err` + close. `sid="default"`, map keyed for ≤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) ## 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), Shipped: SyncClient framing, RoomDiff (eventId diff, 0.95× latch),
media_kit wiring, Space=ready, avatars, toasts+sheet, health display, media_kit wiring, Space=ready, avatars, toasts+sheet, health display,
reconnect loop. Counts at last green: core 42, server 40, desktop 17. 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 Open exits (manual, user-driven): remove bisect flags in
`apps/desktop/lib/app.dart`; 2-client LAN soak; 1.4 GB real-file test `apps/desktop/lib/app.dart`; 2-client LAN soak; 1.4 GB real-file test
(user resupplies URL, never paste api_key into files); (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) ## Phase 5 — Resilience (PARTIAL)