diff options
Diffstat (limited to 'CLAUDE.md')
| -rw-r--r-- | CLAUDE.md | 24 |
1 files changed, 14 insertions, 10 deletions
@@ -72,10 +72,13 @@ dans le bon `pyproject.toml`. - All three packages share the same version number (released together) ### Protocol versions (independent) -- MNP: `0.2` → bumped independently of package version +- MNP: `0.4` → bumped independently of package version - 0.2 added `PING`/`PONG` and backward chat paging (`before` / `has_more`). Additive, so an 0.1 peer still works: it sends no `before` and is answered with the newest page, which is what it wanted + - 0.4 added `apps_enabled`/`apps_enabled_ack` and `enabled_apps` on the + handshake ack, for the group-applications registry (`docs/apps.md`). + Additive, same reasoning - MHP: `0.1` → bumped independently of package version - Every wire message carries a `v` field - Breaking change → MAJOR bump; backward-compatible → MINOR bump @@ -699,8 +702,9 @@ SFR residential Fedora 44 → meshbay.org OVH VPS: | WebRTC transport (browser) | `meshbay_node.transport.webrtc_server` | Phase 9.3 — `aiortc` DataChannel | | WebRTC signaling (hub) | `meshbay_hub.api.signaling` | Phase 9.2 — SDP/ICE relay | | Browser transport client | `static/transport.js` | Phase 9.4 — WebRTC DataChannel | -| Web SPA | `static/app.js` | Phase 9.6 — Preact + preact-router | -| File download (large) | `static/app.js` | File System Access API (`showSaveFilePicker`) — stream to disk | +| Web SPA | `static/app.js` | Phase 9.6 — Preact + preact-router. Routing and every page except a group's — see `docs/apps.md` for the group UI's file layout (2026-08-23 split) | +| Group applications (adding one) | `docs/apps.md` | Chat/Files today, Videos/Music/Photos planned. Props contract, enablement mechanism, checklist | +| File download (large) | `static/file-utils.js` | `downloadEntry`/`_openDownloadTarget`, File System Access API (`showSaveFilePicker`) — stream to disk | | Background tasks (node) | `meshbay_node.transport.webrtc_server` | `_spawn()` — the only way to start one; a bare `ensure_future` can be collected | | Stream handover (node) | `meshbay_node.transport.webrtc_server` | `_replace_stream` + `shutdown_tasks` — one viewer, one film, and the slot comes back when they leave | | Download backpressure (node) | `meshbay_node.transport.webrtc_server` | `DOWNLOAD_BUFFER_HIGH` — 8 × 1 MB answered blind queues 8 MB on the channel | @@ -730,10 +734,10 @@ SFR residential Fedora 44 → meshbay.org OVH VPS: | Ed25519 sign (browser) | `static/keyderive.js` | `signChallenge()` — admin challenge-response | | Auth key derivation (browser) | `static/keyderive.js` | `deriveAuthKey()` — password split, hub never sees raw password | | GEK wrap AES (Python) | `meshbay_common.crypto` | Phase 10b.2 — `wrap_gek_aes()` / `unwrap_gek_aes()` | -| IndexedDB cache (browser) | `static/app.js` | Phase 10b.5 — group index caching | +| IndexedDB cache (browser) | `static/hub-client.js` | Phase 10b.5 — group index caching, moved out of app.js in the 2026-08-23 split | | Cross-group search (browser) | `static/app.js` | Phase 10b.6 — SearchPage, client-side | | MSE video streaming (node) | `meshbay_node.transport.webrtc_server` | Phase 10c — ffmpeg fMP4 remux + encrypted segments | -| MSE video streaming (browser) | `static/app.js` | Phase 10c — MediaSource + SourceBuffer progressive playback | +| MSE video streaming (browser) | `static/video-player.js` | Phase 10c — MediaSource + SourceBuffer progressive playback, moved out of app.js in the 2026-08-23 split | | Video codec detection | `meshbay_node.transport.webrtc_server` | Phase 10c — `_probe_video()` ffprobe + MSE codec strings | | Node daemon (production) | `meshbay_node.daemon` | Phase 11 — WebRTC + WS + chat + HTTP + audit all wired | | Node config | `meshbay_node.config` | `node.toml` loader, `data_dir` for chat/audit DBs | @@ -743,24 +747,24 @@ SFR residential Fedora 44 → meshbay.org OVH VPS: | Bundle store (node) | `meshbay_node.bundle_store` | SQLite P2P GEK + keypair bundles, `data_dir/bundles.db` — hub never stores crypto | | P2P bundle exchange (MNP) | `meshbay_common.protocol` | GEK + keypair bundle STORE/FETCH/RESP message types | | Bundle via DataChannel | `static/transport.js` | GEK + keypair bundle fetch during handshake, store after connect | -| Key persistence (browser) | `static/app.js` | `_bundleKey` in IndexedDB, `_sessionKeys` in sessionStorage | +| Key persistence (browser) | `static/hub-client.js` | `session.bundleKey` (renamed from the bare `_bundleKey` in the 2026-08-23 split) in IndexedDB, `_sessionKeys` in sessionStorage | | pkX from private key | `static/transport.js` | `_pkFromSk()` — JWK export to derive X25519 public key | | Group delete (hub) | `meshbay_hub.api.groups` | `DELETE /v1/groups/{group_id}` — admin only | | JWT scope enforcement | `meshbay_hub.api.deps` | `require_user_scope` — blocks node-scoped tokens from mutations | | Operator operations | `meshbay_node.ops` | **One implementation, several front doors.** The loopback API, the CLI and the signed MNP handlers all call these; they take the daemon `state`, raise `OpError`, and know nothing about HTTP. Two implementations of one operation with two authorization checks is C1/C6 one size down | | Node local admin UI | `meshbay_node.ui.app` | Dashboard, peers, groups, audit log (localhost:18000). Each operation endpoint is one `_op(...)` line — logic there is a rule the MNP path does not have | | Demo scripts | — | `QE/demo-v1/*.py`, `QE/demo-v2/*.py`, `QE/demo-v3/*.py` (not versioned) | -| Video flow control (browser) | `static/app.js` | `pump()` — the only place credit is granted. Read-ahead bounded by `BUFFER_AHEAD_S` of film, `STREAM_WINDOW` segments in flight, driven by a clock and by playback, never by arriving data | +| Video flow control (browser) | `static/video-player.js` | `pump()` — the only place credit is granted. Read-ahead bounded by `BUFFER_AHEAD_S` of film, `STREAM_WINDOW` segments in flight, driven by a clock and by playback, never by arriving data | | Player under test | `tests/harness/mse_harness.mjs` | Runs the real `pump`/`flushQueue`/`evictBehind` against a fake SourceBuffer with a ceiling. Do not write a second model of them | | Asset versioning (hub) | `meshbay_hub.api.webapp` | `_asset_version()` — content hash; whole module graph served under `/a/<hash>/` so a cache cannot mix two builds | | Stream capacity (node) | `meshbay_node.config` | `[node] max_concurrent_streams` (default 8) — a slot is held for the length of a film, so it counts simultaneous viewers | | Stream diagnosis (node) | `webrtc_server.py` | `client_diag` at DEBUG — the player's own view (`ready`, `quota`, `ranges`, `err`) in the node's log. The only window into a phone | | Stream probe (no browser) | — | `QE/deploy/stream_probe.py` — pulls a real film over real MNP, `--start` to seek. Answers "is it the node or the browser" in one run (not versioned) | -| Seeking (browser) | `static/app.js` | `requestSeek` → node restarts ffmpeg with `-ss`; `reinitAt` clears the buffer and sets `timestampOffset`. `-copyts` does *not* preserve position — measured — so the offset comes from the client | +| Seeking (browser) | `static/video-player.js` | `requestSeek` → node restarts ffmpeg with `-ss`; `reinitAt` clears the buffer and sets `timestampOffset`. `-copyts` does *not* preserve position — measured — so the offset comes from the client | | Seeking (node) | `webrtc_server.py` | `start` on `stream_req`; `-ss` **before** `-i` (index seek, not decode-and-discard), clamped away from the end, echoed in `stream_init` | -| Resume position | `static/app.js` | `readResumePosition` / `writeResumePosition` — localStorage, per file, per browser. No protocol, and nothing new learns what you watch | +| Resume position | `static/video-player.js` | `readResumePosition` / `writeResumePosition` — localStorage, per file, per browser. No protocol, and nothing new learns what you watch | | Layout, measured | `tests/harness/layout_probe.py` | Renders `style.css` in Chrome at any width and returns bounding boxes. Use it for layout, not `test_layout_responsive.py`, which only pins CSS values | -| Session renewal (browser) | `static/app.js` | `refreshAccessToken` / `ensureFreshToken` — one writer (`setAuth`), one in-flight renewal, rotated refresh token stored. `hubFetch` renews on 401 and replays | +| Session renewal (browser) | `static/hub-client.js` | `refreshAccessToken` / `ensureFreshToken` — one writer (`setAuth`), one in-flight renewal, rotated refresh token stored. `hubFetch` renews on 401 and replays. Moved out of app.js in the 2026-08-23 split | | Token lifetimes (hub) | `meshbay_hub.config` | `[jwt] access_token_ttl` 4 h, `refresh_token_ttl` 30 days. **Production sets both in `~/.config/meshbay/hub.toml`** — changing the code default alone does nothing there | ## meshbay.org server (état cible) |