From 079ef3e61ec240a15afe109d3554ea0a29400179 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Sun, 1 Nov 2026 18:40:42 +0100 Subject: [PATCH] docs(20-05): chat family deployed on demo.summercms.io with its own LiveKit summary Claude-Session: https://claude.ai/code/session_01BK6kckmLyJ4a91Vm9rqaDP --- .../20-05-SUMMARY.md | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 .planning/phases/20-demo-instance-with-every-shared-plugin/20-05-SUMMARY.md diff --git a/.planning/phases/20-demo-instance-with-every-shared-plugin/20-05-SUMMARY.md b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-05-SUMMARY.md new file mode 100644 index 00000000..648efde6 --- /dev/null +++ b/.planning/phases/20-demo-instance-with-every-shared-plugin/20-05-SUMMARY.md @@ -0,0 +1,162 @@ +--- +phase: 20-demo-instance-with-every-shared-plugin +plan: 05 +subsystem: sm-demo-app deploy, rome +tags: [deploy, rome, livekit, vuurmuur, nginx, centrifugo, herald, vapid, robots, check-live] + +requires: + - phase: 20-02 + provides: "chat family mounted in sm-demo-app, deploy/livekit.yaml.example, Centrifugo namespaces in the example, production livekit_url" + - phase: 20-03 + provides: "vue-chat-layer v0.1.0 pinned in vue-demo-app" + - phase: 20-04 + provides: "forum, friends and video-call layers v0.1.0 pinned in vue-demo-app, herald VAPID handling in dev.sh" +provides: + - "demo.summercms.io serves /chat, /forum, /friends and /call/{id} with the banner and register prompts; the chat-family APIs answer 401 without a JWT" + - "The demo's own LiveKit 1.13.1 on rome (supervisor program summercms-demo-livekit, 127.0.0.1:7890 behind nginx /livekit/, media 7891/tcp and 7892/udp open through Vuurmuur)" + - "Centrifugo namespaces chat, user, video on rome; herald VAPID keys in rome's .env; robots.txt disallows the new prefixes" + - "scripts/check-deploy.sh LiveKit and chat-family checks; scripts/check-live.sh chat-family checks; DEPLOY.md runbooks for LiveKit, the firewall and the chat family" +affects: [20-06] + +actuals: + tokens: 14800 # chars/4 over sm-demo-app fc23b4c..f2e35c1 without the ROADMAP snapshot and the gitlink (59224 chars) + tasks: 6 + commits: 0 # MEASURED in summercms.go: git rev-list --count 6389479..HEAD before this SUMMARY commit (docs-only plan here); sm-demo-app: 6 (git rev-list --count fc23b4c..f2e35c1) +plan_head_before: 63894799065795c54d91e40094692cf4f0cbe419 # summercms.go +plan_head_after: 63894799065795c54d91e40094692cf4f0cbe419 # summercms.go before this SUMMARY commit; sm-demo-app fc23b4c -> f2e35c1, vue-demo-app 44a5229 -> 9357711 (pushed) + +tech-stack: + added: [] + patterns: + - "Secrets generated on rome go into files through bash builtins and stdin only (printf, tee), never as a process argument" + - "Shared-host supervisor changes name the program (supervisorctl update ), so no other program restarts" + - "Admin-only settings changed unattended through rome's loopback admin API, the password read on rome into a 0700 temp dir" + +key-files: + created: + - ../sm-demo-app/deploy/supervisor/summercms-demo-livekit.conf + modified: + - ../sm-demo-app/deploy/nginx/demo.summercms.io.conf + - ../sm-demo-app/deploy/livekit.yaml.example + - ../sm-demo-app/config/env/production/golem15.chatvideo.yaml + - ../sm-demo-app/scripts/check-deploy.sh + - ../sm-demo-app/scripts/check-live.sh + - ../sm-demo-app/DEPLOY.md + - ../sm-demo-app/README.md + - ../sm-demo-app/plugins/demo/content/ROADMAP.md + - ../sm-demo-app/vue-demo-app + +key-decisions: + - "Task 3 checkpoint: deploy (push both repositories and release the chat family on rome)" + - "Task 5 checkpoint: firewall done; the user applied the Vuurmuur rule as service sm-demo-livekit (7891/tcp, 7892/udp), rule on line 1 of rules.conf" + - "Media path: ICE over the UDP mux 7892 with ICE-TCP 7891, no embedded TURN; TURN on 3478/5349 with a DNS-only host is the recorded fallback" + - "Admin stays at /smbackend with login; /backend answers 404" + - "robots.txt updated through PUT /_seo/api/v1/robots on rome's loopback (admin bearer token), not by hand" + - "VAPID subject mailto:DEMO_ADMIN_EMAIL from the build machine's secrets file" + +requirements-completed: [SC-2, SC-3, D-10, D-12, D-16, D-20, D-21] + +duration: about 5 h of work over two sessions (2026-10-31 evening to 2026-11-01 18:40), with three checkpoints and the user's own firewall change +completed: 2026-11-01 +status: complete +--- + +# Phase 20 Plan 05: chat family deployed on demo.summercms.io with its own LiveKit Summary + +**The chat family runs on the public demo: https://demo.summercms.io serves /chat, /forum, /friends and /call/{id} with the banner and register prompts, every chat-family API answers 401 without a JWT, /livekit/rtc/validate reaches the demo's own LiveKit 1.13.1 (supervisor program summercms-demo-livekit, separate from WavePath's), Centrifugo has the chat, user and video namespaces, herald has VAPID keys without a route, and Vuurmuur admits LiveKit's media on 7891/tcp and 7892/udp. `check-live.sh https://demo.summercms.io` prints `check-live: ok`.** + +## Task Commits + +| # | Repo | Commit | Message | +|---|------|--------|---------| +| 1 | sm-demo-app | b5c639e | feat: deploy files for the chat family and the demo's LiveKit | +| 2 | sm-demo-app | cf08fb5 | fix: check-live tells an unrouted /_herald by its 404, not its type | +| 3 | — | — | checkpoint: deploy | +| 4 | vue-demo-app | (push) | 44a5229..9357711 pushed to origin master | +| 4 | sm-demo-app | c399bfd | chore: bump vue-demo-app (chat, forum, friends, calls) | +| 4 | sm-demo-app | 6d726b4 | chore: sync the roadmap snapshot | +| 4 | sm-demo-app | fcd8d95 | docs: record the chat-family release on rome | +| 5 | — | — | checkpoint: firewall done (applied by the user) | +| 6 | sm-demo-app | f2e35c1 | docs: record the LiveKit firewall rule | + +**Pushed:** vue-demo-app master = 9357711 (`ls-remote` equals local HEAD, and sm-demo-app's gitlink points to it); sm-demo-app master = f2e35c1 (`ls-remote` equals local HEAD). Push order: vue-demo-app first, then the pointer bump. + +## Deploy table (Task 2, rome read-only, 2026-10-31/11-01; no secret values) + +| Item | State before the release | +|------|--------------------------| +| Listeners on 7890, 7891, 7892 | none (free); the trio was kept | +| WavePath LiveKit | `wavepath-livekit` RUNNING pid 1104; 127.0.0.1:7880, *:7881, UDP 50000-60000 | +| LiveKit binary | `/usr/local/bin/livekit-server` 1.13.1 | +| Demo programs | summercms-demo, summercms-demo-site, summercms-demo-centrifugo RUNNING; no summercms-demo-livekit, conf or livekit.yaml | +| `.env` key counts | CHATVIDEO__LIVEKIT_API_KEY 0, __LIVEKIT_API_SECRET 0, HERALD__VAPID__PUBLIC_KEY 0, __PRIVATE_KEY 0, __SUBJECT 0 | +| centrifugo.json | namespaces `["presentations"]` only (chat 0, user 0, video 0); Centrifugo v6.5.1 | +| Vuurmuur | 0.8.1, INPUT policy DROP, 62 vrmr lines, 15 rules, service Livekit unused, 0 rules for 789x | +| Unpushed | sm-demo-app 19 commits (plans 02-04) + this plan's; vue-demo-app 9 commits | + +## Ports used + +7890/tcp on 127.0.0.1 (signal and RoomService, behind nginx `location ^~ /livekit/` and `livekit_admin_url`), 7891/tcp on all addresses (ICE-TCP), 7892/udp on every interface including 54.36.173.176 (ICE UDP mux). No collision with Go 8098, Nuxt 3098, Centrifugo 8010 or WavePath's 7880/7881/50000-60000 (check-deploy asserts it). + +## What changed on rome (2026-11-01) + +- **LiveKit:** `/srv/summercms-demo/livekit.yaml` (0640 root:summercms-demo, own key pair generated on rome), the same pair in `.env` (secret line count 1), `/etc/supervisor/conf.d/summercms-demo-livekit.conf`, program started alone with `supervisorctl update summercms-demo-livekit`. `curl 127.0.0.1:7890/` answers OK, `/rtc/validate` 401. +- **Centrifugo:** namespaces `["presentations","chat","user","video"]`, `checkconfig` passed, summercms-demo-centrifugo restarted. Backup `/srv/summercms-demo/centrifugo.json.bak-2026-11-01`. +- **VAPID:** public key, private key and subject `mailto:` + DEMO_ADMIN_EMAIL appended to `.env` (count 3, values non-empty: 87 and 43 characters), generated with `bin/demo.new herald:vapid-generate --json -q`. +- **Release** `c49fabf46c88` (sm-demo-app 6d726b4): 9 migrations (the chat family's tables), demo:seed created channels and history EN/PL, the visitor's welcome DM, forum categories and threads, friends and group, the moderator group demo-moderators and the moderation lists; binary and site swapped (`bin/demo.prev` 21e6abc585e6, `site/.output.prev`), summercms-demo and summercms-demo-site restarted, `websockets:health` reports the API key set. +- **nginx:** the new vhost installed, `nginx -t` passed, reloaded. Previous vhost `/root/demo.summercms.io.nginx.bak-2026-11-01`. +- **robots.txt:** `Disallow:` /_chat, /_chatchannels, /_chatbots, /_chatvideo, /_forum, /_userfriends and /livekit appended through `PUT /_seo/api/v1/robots` on loopback (bot switches untouched); the live file shows them with the Sitemap line. Previous rules `/root/summercms-demo-seo-robots.bak-2026-11-01.json`. +- **Firewall (by the user):** service `/etc/vuurmuur/services/sm-demo-livekit` (`RANGE="6;7891*1024:65535"`, `RANGE="17;7892*1024:65535"`, no COMMENT), rule `Accept service sm-demo-livekit from any to firewall(any) options log,loglimit="30"` on line 1 of rules.conf. `iptables -S` shows NFLOG `vrmr: ACCEPT` and NEWACCEPT for `--dport 7891` and `--dport 7892` (66 vrmr lines, 62 before); `nc -zv 54.36.173.176 7891` connects. It differs from the proposal in the service name (`sm-demo-livekit`, not `summercms-demo-livekit`), the missing COMMENT and the position (first, not appended); no `rules.conf.bak-*` is in `/etc/vuurmuur/rules/` (the pre-change file was the 15-line one probed on 2026-10-31). DEPLOY.md records it and its removal commands use the applied names. +- **WavePath untouched:** `wavepath-livekit` kept pid 1104 throughout (uptime 1 day 23:53 before, 2 days 0:09 after); no other non-demo program was restarted. Nothing was added to `/etc/livekit/livekit.yaml`. + +Supervisor status after the release: summercms-demo, summercms-demo-site, summercms-demo-centrifugo and summercms-demo-livekit RUNNING. + +## Checkpoint answers + +- **Task 3:** deploy. +- **Task 5:** firewall done; the user applied the Vuurmuur rule, Claude made no firewall change and verified it read-only. + +## Verification + +- check-deploy: `check-deploy: ok`; negative copies (a /_herald location, LiveKit on another port, a UDP port range, bind 0.0.0.0, a real key, a cap mismatch, a wrong admin URL) each fail with their own line. +- Local LiveKit 1.13.1 with the example: signal on 127.0.0.1:7890 only, ICE-TCP on *:7891, UDP 7892 per interface, /rtc/validate 401. +- check-pins ok (25 modules); `build.sh release` → `build: ok release c49fabf46c88`; smoke ok; `go vet` and `go test -short ./...` green. +- check-live against the live demo after the release and again after the firewall rule: `check-live: ok` (banner, CTA, /backend 404, /smbackend, /chat /forum /friends /call/1 prompts, six chat-family 401s, /livekit/rtc/validate from LiveKit, /_herald 404, robots lines, /ws 101, Back in a browser). +- Acceptance greps: 6 chat-family locations, the program once, Vuurmuur 14+ times in DEPLOY.md. The plan's `grep -c 'location ^~ /livekit/'` prints 0 on this machine because `grep` is ugrep, which treats a mid-pattern `^` as an anchor (it also prints 0 for the existing `/_demo/` location); `grep -cF` prints 1. +- Robots state: updated, see above. Nothing left for the user from robots. + +## Deviations from Plan + +**1. [Rule 1 - Bug] check-live's /_herald check** (Task 2, cf08fb5). The first version failed on any JSON answer, but Nuxt answers its 404 as JSON to curl's `Accept: */*`. It now wants status 404 (Go would answer 401 without a JWT). + +**2. [Rule 3 - Blocking] Release build prerequisites** (Tasks 2 and 4). `build.sh release` refused in Task 2: the uncommitted vue-demo-app gitlink (the plan's Task 4 bump), the user's untracked backup file (left untouched; the user removed it) and a stale ROADMAP snapshot (phase 20 progress lines). The snapshot was synced in Task 4 just before the build (6d726b4) so it matched the framework's master at release time. + +**3. [Rule 2 - Missing critical] Runbook safety on a shared host** (Task 1). The LiveKit secret goes into the files through bash builtins and stdin only (the Centrifugo runbook's `sed` put secrets in argv); the substitution is anchored on the newline and indent so a comment holding the placeholder cannot take it; `supervisorctl update` names the program; the new Centrifugo file is created 0640 before `tee` writes it; the vhost is backed up before it is replaced (added to "Release"). + +**4. robots.txt through the loopback SEO API** (Task 4). DEPLOY.md's SEO section described a hand edit; the plan allowed an unattended path. The procedure is recorded in DEPLOY.md "Chat family". + +**5. check-live also covers /call/1 and /_chat** (Task 1), because SC-2 and SC-3 name them; the plan's list had /chat, /forum, /friends and five API prefixes. + +**Total deviations:** 5. **Impact:** none on the goal. + +## Boot-log warnings (rome and local alike) + +`golem15.chatchannels: ChannelAccessResolver is deny-all`, `golem15.forum: ForumAccessResolver is deny-all`, `golem15.chatbots: BotAuthResolver is deny-all` and `golem15.herald: PresenceGate is deny-all` appear at every boot, locally too (12 times each in the local go.log). They are logged before golem15.demo installs its resolvers in `lagoon.OnDatabase` (`plugins/demo/chat.go:68,86`); chatbots has no bot users and herald no UI (D-16). Plan 06's signed-in live checks confirm the wiring on rome. + +## Known Stubs + +None. + +## Left for the user + +Nothing required. Optional: keep a dated copy of the pre-change rules.conf if you want one next to the file (DEPLOY.md lists the 15 earlier rules). NAT'd-browser media is proven only by plan 06's live call; the TURN fallback needs its own decision. + +## Next Phase Readiness + +Plan 06 can run its live checks: the stale local demo servers from plan 04 are stopped, the live demo passes check-live, the media ports are reachable, and a signed-in member (Turnstile is closed in production, so a test account comes from the operator or the visitor account in rome's .env) can exercise chat, forum, friends and a two-browser DM call. + +## Self-Check: PASSED + +- sm-demo-app commits exist and are on origin: b5c639e, cf08fb5, c399bfd, 6d726b4, fcd8d95, f2e35c1 (remote master f2e35c1). vue-demo-app origin master 9357711. +- Files exist: deploy/supervisor/summercms-demo-livekit.conf, the modified files above. +- rome: summercms-demo-livekit RUNNING, `.env` LiveKit secret count 1, VAPID count 3, wavepath-livekit pid 1104 unchanged, check-live ok.