diff --git a/docs/deployment.md b/docs/deployment.md index a9bf1e9..50771ec 100644 --- a/docs/deployment.md +++ b/docs/deployment.md @@ -20,33 +20,37 @@ tracked coturn example remains `stun-only`; the shared host retains its older authenticated-relay daemon configuration and firewall range. The application does not pre-advertise TURN credentials to ordinary peers. -Production currently runs exact `691863e1720ebbee1b5368f29e94f05b3710ccf8` +Production currently runs exact `261e980c3a9ff2d1a6b54ce18cf3daedb491b777` on the existing shared public IP, with local/public health 200 and SQLite v3 -integrity. The 605,904-byte artifact has SHA-256 -`7e751c0bf7c97bc7d23edb1e37441fb6c55d90a0cd80647b778fdb5b1ee28bae`. -The 2026-08-21T06:00:00Z UTC cutover held the deployment lock for 3,376.021 ms; -local health returned 669.678 ms after service stop (604.174 ms after the symlink +integrity. Its immutable source artifact is 604,336 bytes with SHA-256 +`d8a100d3b06e4a566a84cd9556dafa73a6d533360f82b302c62a0f354958403e`; +the locally built dist artifact is 354,230 bytes with SHA-256 +`58b7149bd390d1a9b0179283b50fc4870433988f8037d5b46504019b8b3c3f30`. +The 2026-08-21T08:35:20Z UTC cutover held the deployment lock for 2,276.366 ms; +local health returned 703.625 ms after service stop (562.538 ms after the symlink switch). Screener, LiveKit, coturn, and nginx are active/running with observed `NRestarts=0`. SQLite v3 contains five rooms including room `1`, with the service owner/mode `screener:screener`/0600 and SHA-256 `aef724ae52c4107be8ec8791e72f8dcaa11b0ec849fb432d022e2cfb9cfe0974`. -The immutable release is `/opt/screener/releases/691863e1720e`; backup -`/opt/screener/backups/691863e1720e-precutover-20260821T060000Z` preserves the -database, environment, artifact digest, and exact previous target. Exact -`6634cb9fca8278b44d57e5fcddcbaf9f0dc9b137` is the immediate rollback target; -exact `ecc794d6f01ff8e90cc07a267d221daaac8da9e1` and -`16f6eab27bdfb1c15cdbd814a35864f4f18be767` remain secondary and tertiary. +The immutable release is `/opt/screener/releases/261e980c3a9f`; backup +`/opt/screener/backups/261e980c3a9f-precutover-20260821T083520Z` preserves the +database, environment, artifact digests, firewall snapshot, and exact previous +target. Exact `691863e1720ebbee1b5368f29e94f05b3710ccf8` is the immediate rollback +target; exact `6634cb9fca8278b44d57e5fcddcbaf9f0dc9b137` and +`ecc794d6f01ff8e90cc07a267d221daaac8da9e1` remain secondary and tertiary. This release keeps one stable SFU subscriber stream, clears unavailable SFU -video state, shows authoritative pending/P2P/SFU routes while requiring media -evidence for connected status, and labels TURN only for an actual relay. It adds -the Host local-preview pause notice and suppresses current-edge signals to a -grace-retained offline target. The shared room-entry and adjacent nickname UI, -a generation-bound Host-only P2P diagnostic, and two downstream slots for every -ordinary Web relay are deployed; a third child remains rejected. The production +video state, stays neutral until current media evidence proves P2P or SFU, and +labels TURN plus a protocol only from actual local relay stats. Routing remains +automatic across direct/peer and bounded fallback paths. P2P reapplies the +selected quality profile after each answer on the same sender; the browser still +owns degradation. The Host preview notice, shared entry/nickname UI, and two +downstream slots per Web +relay remain deployed; a third child remains rejected. Production STUN/SFU/selected-edge configuration and the database were unchanged. -Fresh exact-source acceptance passed typecheck, 32 test files/469 tests, both -builds, repository hygiene, UTF-8 archive verification, and zero cross-release -regular-file inodes. +Fresh exact-source acceptance passed typecheck, 32 test files/470 tests, both +builds, and repository hygiene. Deployment verified both artifact manifests and +hashes, one bounded production-only install, runtime imports, `node:sqlite`, +UTF-8 paths, zero cross-release regular-file inodes, and immutable permissions. This cutover triggered no browser, media, SFU, TURN, or performance canary and remains exact-source, build, configuration, and deployment evidence. A separate earlier local Screener canary using exact `16f6eab` source and the @@ -74,7 +78,7 @@ reverse proxy. A single Node process is intentional. Active participants and signaling remain in memory; an optional protected SQLite file can restore room identity after a restart, but it does not restore live WebRTC connections. -Build and validate the exact revision before starting it: +Build and validate the exact revision on a build host before starting it: ```sh npm ci @@ -82,6 +86,14 @@ npm run check npm start ``` +Do not run the repository full check, typecheck, or build on the current 960 MiB +no-swap production host. An inactive-release check before the `261e980c` cutover +temporarily starved HTTP and SSH; exact `691863e` remained current and all four +services stayed at `NRestarts=0`. The retained production path uses a locally +verified dist artifact plus one `npm ci --omit=dev` in a transient unit bounded +to 30% CPU, 160 MiB memory high, 256 MiB memory max, and 120 seconds. It then +runs only runtime imports, `node:sqlite`, and artifact/inode/permission gates. + Each immutable release must own an independent dependency tree. Never hard-link `node_modules` or another file that deployment may `chown`, `chmod`, replace, or remove: metadata changes would also mutate the rollback release. A copy or @@ -134,7 +146,7 @@ ICE. The accepted ladder is direct/peer UDP, then the revision-bound SFU/UDP virtual parent, then optional authenticated TURN for one controller-selected exceptional edge. LiveKit participants receive only revision-bound `sfu-config` URL/token messages and negotiate within LiveKit's separate ICE domain. The -selected-edge TURN config/wire is deployed in the current `691863e` release with one +selected-edge TURN config/wire is deployed in the current `261e980c` release with one UDP URL and a 120-second credential TTL. It was not exercised by a real media session during this cutover. diff --git a/docs/project-memory.md b/docs/project-memory.md index 9f76ffc..e055c7f 100644 --- a/docs/project-memory.md +++ b/docs/project-memory.md @@ -15,7 +15,7 @@ Last updated: 2026-08-21 - Site access protects room creation, Host publication, and every code-only Viewer entry. A valid room-scoped fragment grant bypasses that site gate; otherwise site access is checked before public-watch or a private room password. Persist neither raw credential; keep accounts, ACLs, users, and session tables out. - Keep decisions, snapshots, research, code, `AGENTS.md`, and `.codex/` in Git; rewrite memory/status in place. Research current primary sources before material work and reject speculative machinery. - Migrate client, server, and deployment atomically. After a canary, delete superseded config/wire/parsers/tests; do not retain compatibility layers, dual writes, or a second architecture without a current consumer. Git history owns the old implementation. -- Deploy coherent milestones after narrow tests, independent review, one local full gate, and rollback preflight. Actions are only for a necessary final main/release gate; migrations stay atomic. +- Deploy after narrow tests, independent review, one local full gate, and rollback preflight. Build/test off the 960 MiB production host; prepare audited dist with one bounded production install. Actions remain for a necessary main/release gate only. ## Current Recommendation @@ -43,8 +43,8 @@ Last updated: 2026-08-21 ## Current Implementation - The repository is one npm package using Node.js 24, React, TypeScript, Vite, native WebRTC, `ws`, Zod, Vitest, and separate coturn. -- Production is exact `691863e1720ebbee1b5368f29e94f05b3710ccf8`; artifact 605,904 bytes/SHA-256 `7e751c0bf7c97bc7d23edb1e37441fb6c55d90a0cd80647b778fdb5b1ee28bae`; cutover 3,376.021 ms lock/669.678 ms stop-health/604.174 ms switch-health; rollbacks `6634cb9`, `ecc794d`, `16f6eab`. -- Web keeps one SFU stream, clears unavailable video, shows evidence-backed P2P/SFU and actual-only TURN, labels paused preview, and drops signals to a grace-retained offline current-edge target. Shared entry/nickname UI is live; Native remains source-only. +- Production is exact `261e980c3a9ff2d1a6b54ce18cf3daedb491b777`; source/dist artifacts are 604,336/354,230 bytes, with hashes in deployment; cutover 2,276.366 ms lock/703.625 ms stop-health/562.538 ms switch-health; rollbacks `691863e`, `6634cb9`, `ecc794d`. +- Web keeps one SFU stream, clears unavailable video, exposes evidence-backed routes/transports and paused preview, and drops signals to a grace-retained offline current-edge target. Routing is automatic; entry/nickname UI is live; Native remains source-only. - Web relay is cap2 with one upstream; child3 rejects and no UA/visibility split exists. - Four services are active/running at `NRestarts=0`; local/public health are 200. SQLite v3 has five rooms, SHA-256 `aef724ae52c4107be8ec8791e72f8dcaa11b0ec849fb432d022e2cfb9cfe0974`, owner/mode `screener:screener`/0600. - Production keeps ordinary ICE STUN-only, SFU roots <=2, selected-edge UDP TTL 120, and one pending/answered `peer-selected` attempt per room excluding Host ingress. This rollout ran no browser/media/SFU/TURN/performance canary; earlier exact-`16f6eab` evidence proves active Host ingress only. diff --git a/docs/status.md b/docs/status.md index 78f8606..a6ef4e7 100644 --- a/docs/status.md +++ b/docs/status.md @@ -4,10 +4,10 @@ Last updated: 2026-08-21 ## Phase -Production at `https://share.bonfire.icu` is exact `691863e1720ebbee1b5368f29e94f05b3710ccf8`; artifact 605,904 bytes, SHA-256 `7e751c0bf7c97bc7d23edb1e37441fb6c55d90a0cd80647b778fdb5b1ee28bae`. -Cutover: 3,376.021 ms lock/669.678 ms stop-health/604.174 ms switch-health. SQLite v3/five rooms has SHA-256 `aef724ae52c4107be8ec8791e72f8dcaa11b0ec849fb432d022e2cfb9cfe0974`, owner/mode `screener:screener`/0600. Four services are active/running at `NRestarts=0`; rollbacks are `6634cb9`, then `ecc794d` and `16f6eab`. +Production at `https://share.bonfire.icu` is exact `261e980c3a9ff2d1a6b54ce18cf3daedb491b777`; immutable source/dist artifacts are 604,336/354,230 bytes, with hashes in deployment. +Cutover: 2,276.366 ms lock/703.625 ms stop-health/562.538 ms switch-health. SQLite v3/five rooms has SHA-256 `aef724ae52c4107be8ec8791e72f8dcaa11b0ec849fb432d022e2cfb9cfe0974`, owner/mode `screener:screener`/0600. Four services are active/running at `NRestarts=0`; rollbacks are `691863e`, then `6634cb9` and `ecc794d`. Ordinary ICE is STUN-only; limits are SFU roots <=2, one `peer-selected` attempt excluding Host ingress, and selected UDP TTL 120. This rollout ran no browser/media/SFU/TURN/performance canary; earlier exact-`16f6eab` Host-ingress proof remains separate. -Stable SFU stream/unavailable state, evidence-backed pending/P2P/SFU and actual-only TURN are in source with Host preview notice, entry/nickname UI and Web relay cap2. Native is source-only; Web defaults VP8. +Stable SFU state, evidence-backed route/transport labels, Host preview notice, entry/nickname UI and Web relay cap2 are live. Native is source-only; Web defaults VP8. ## Execution Principle @@ -35,11 +35,11 @@ Flagship; parallel; min run/smoke/rollback; benchmark later. Active UI/config/lo - Access protocol/config/HTTP/storage/SQLite/signaling focused tests pass, including commit-first teardown and v1 rollback. - Native wire/session tests enforce at most two authoritative children, no presence-created edge, stale-revision ignore, and one bounded unsupported-route failure per revision. - Production caps pending/answered `peer-selected` at one per room; Host ingress is independent. Focused admission/release/rollback/STUN-only tests pass; earlier Chrome proves active Host-ingress function only. -- Exact `691863e` passed fresh typecheck, builds, hygiene and 32 files/469 tests. UTF-8 archive/shared-inode/deploy gates preserved config/nft/DB hashes and four zero-restart services. +- Exact `261e980c` passed fresh typecheck, builds, hygiene and 32 files/470 tests. Bounded runtime, UTF-8 artifact, inode and deploy gates preserved config/nft/DB hashes and four zero-restart services. ## Unverified Boundaries -- The `691863e` cutover ran no browser/media/SFU/TURN/performance canary. Earlier `16f6eab` proof covers Host ingress only; audible quality, last mile, external cohorts, admission rescue, resources/performance and game blur remain open. +- The `261e980c` cutover ran no browser/media/SFU/TURN/performance canary. Earlier `16f6eab` proof covers Host ingress only; audible quality, last mile, external cohorts, admission rescue, resources/performance and game blur remain open. - Mobile is Viewer-only. Its persistent audible media element keeps media/signaling active while the page lives; iOS lock-screen, reclamation and background reconnection remain device gates. AirPlay/system mirroring is local output; live WebRTC `srcObject` has no portable in-app TV-output contract. - Silent partitions can wait 30 to 60 seconds for heartbeat detection before the default 5-second grace; this remains unverified. - Production startup blur remains open. One local Chrome synthetic same-`balanced` A/B kept route/PC/SSRC/track and coincided with 720p -> 1080p without loss/freeze, but natural ramp prevents causal, production, or SFU proof.