openvibers/openvibe.network Commits
Hazard H15: 6 Media objects without a verified good copy (4 corrupt B2 copies, 2 missing local files)
Changes
@@@ -20,8 +20,8 @@ Deliverable 1: runtimes, ports, units, env files and repository state.| Repo | HEAD | origin/main | Source files | LOC | Test files | CI | Routes | Tables | WS servers | Timers/jobs | TODO(contract) ||---|---|---|---|---|---|---|---|---|---|---|---|--| OpenVibe.Live | c9af780 | e266060 | 167 | 69945 | 58 | yes | 537 | 125 | 8 | 48 | 15 |--| OpenVibe.Network | 06e4a6b | 06e4a6b | 52 | 12043 | 15 | yes | 207 | 39 | 0 | 6 | 0 |++| OpenVibe.Live | e266060 | e266060 | 167 | 69978 | 58 | yes | 537 | 125 | 8 | 48 | 15 |++| OpenVibe.Network | 33156ef | 06e4a6b | 52 | 12043 | 15 | yes | 207 | 39 | 0 | 6 | 0 || OpenVibe.Shared | 9b53beb | 9b53beb | 35 | 9484 | 11 | yes | 1 | 0 | 0 | 5 | 0 || OpenVibe.Media | cced10f | cced10f | 34 | 10436 | 9 | yes | 90 | 18 | 0 | 9 | 0 || OpenVibe.Tools | 4773f7b | fd5d318 | 117 | 20013 | 2 | no | 99 | 4 | 0 | 12 | 0 |@@@ -38,10 +38,10 @@ Deliverable 2: every table declared in code or present in production, with curre| ai_usage | server/db/database.js:1258 | live.db | OpenVibe.AI | extract | W13 || ai_viewer_log | server/db/database.js:1891 | live.db | OpenVibe.AI | extract | W13 || ai_viewer_threads | server/db/database.js:1877 | live.db | OpenVibe.AI | extract | W13 |--| analytics_daily | node_modules/openvibe-shared/analytics.js:116 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |--| analytics_events | node_modules/openvibe-shared/analytics.js:74 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |--| analytics_hourly | node_modules/openvibe-shared/analytics.js:98 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |--| analytics_rate_tracking | node_modules/openvibe-shared/analytics.js:137 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |++| analytics_daily | vendor/openvibe-shared/analytics.js:116 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |++| analytics_events | vendor/openvibe-shared/analytics.js:74 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |++| analytics_hourly | vendor/openvibe-shared/analytics.js:98 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |++| analytics_rate_tracking | vendor/openvibe-shared/analytics.js:137 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 || analytics_snapshots | (prod only) | rs-companion.db | OpenVibe.Games (import source) | frozen-legacy | W12 || anon_ip_mappings | server/db/database.js:940 | live.db | OpenVibe.Network (policy) | extract | W1 || api_keys | server/db/schema.sql:391 | live.db | OpenVibe.Network (principals) / OpenVibe.Codes | extract | W1/W20 |@@@ -32,10 +32,10 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| POST | /api/admin/ai/viewers/:userId/:action | server/admin/routes.js:522 || GET | /api/admin/ai/viewers/:userId/log | server/admin/routes.js:532 || GET | /api/admin/ai/viewers/status | server/admin/routes.js:504 |--| GET | /api/admin/analytics | server/index.js:675 |--| GET | /api/admin/analytics/bots | server/index.js:684 |++| GET | /api/admin/analytics | server/index.js:708 |++| GET | /api/admin/analytics/bots | server/index.js:717 || GET | /api/admin/bans | server/admin/routes.js:429 |--| POST | /api/admin/broadcast | server/index.js:793 |++| POST | /api/admin/broadcast | server/index.js:826 || PUT | /api/admin/channels/:id/force-nsfw | server/admin/routes.js:359 || GET | /api/admin/diagnostics | server/admin/routes.js:51 || DELETE | /api/admin/media-tools/cookies | server/admin/routes.js:1214 |@@@ -232,7 +232,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| POST | /api/cosmetics/internal-unlock | server/monetization/cosmetics-routes.js:95 || GET | /api/cosmetics/inventory | server/monetization/cosmetics-routes.js:32 || POST | /api/cosmetics/unequip | server/monetization/cosmetics-routes.js:55 |--| POST | /api/csp-report | server/index.js:814 |++| POST | /api/csp-report | server/index.js:847 || GET | /api/dm/blocks | server/chat/dm-routes.js:401 || DELETE | /api/dm/blocks/:userId | server/chat/dm-routes.js:389 || POST | /api/dm/blocks/:userId | server/chat/dm-routes.js:374 |@@@ -282,7 +282,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| GET | /api/funds/leaderboard/:streamId | server/monetization/routes.js:198 || POST | /api/funds/purchase | server/monetization/routes.js:34 || POST | /api/funds/recycle | server/monetization/routes.js:181 |--| GET | /api/health | server/index.js:694 |++| GET | /api/health | server/index.js:727 || GET | /api/home/digest | server/home/routes.js:457 || GET | /api/home/discover | server/home/routes.js:507 || GET | /api/home/featured | server/home/routes.js:247 |@@@ -297,7 +297,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| GET | /api/img-proxy | server/media/external-image-proxy.js:31 || GET | /api/kiosk/favicon | server/kiosk/routes.js:122 || GET | /api/kiosk/site | server/kiosk/routes.js:77 |--| GET | /api/live-events | server/index.js:622 |++| GET | /api/live-events | server/index.js:655 || POST | /api/media/advance | server/media/routes.js:262 || GET | /api/media/channel/:username | server/media/routes.js:52 || GET | /api/media/downloader/status | server/media/routes.js:413 |@@@ -401,7 +401,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| POST | /api/powerchat/test-tip | server/integrations/powerchat-routes.js:350 || GET | /api/powerchat/tip-link | server/integrations/powerchat-routes.js:291 || POST | /api/powerchat/webhook | server/integrations/powerchat-routes.js:442 |--| GET | /api/ready | server/index.js:717 |++| GET | /api/ready | server/index.js:750 || GET | /api/recap/:streamId | server/recap/routes.js:21 || POST | /api/recap/:streamId/regenerate | server/recap/routes.js:43 || GET | /api/recap/channel/:username | server/recap/routes.js:14 |@@@ -503,7 +503,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| GET | /api/tts/audio/:file | server/chat/tts-routes.js:125 || GET | /api/tts/settings | server/chat/tts-routes.js:43 || GET | /api/tts/voices | server/chat/tts-routes.js:33 |--| GET | /api/updates | server/index.js:780 |++| GET | /api/updates | server/index.js:813 || GET | /api/vibe-coding/channel/:username/:slotIdOrSlug/events | server/vibe-coding/routes.js:17 || GET | /api/vibe-coding/managed/:managedStreamId/events | server/vibe-coding/routes.js:47 || GET | /api/vibe-coding/managed/:managedStreamId/settings | server/vibe-coding/routes.js:74 |@@@ -527,37 +527,37 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t| POST | /api/vods/stream/:streamId/finalize | server/media-proxy/vods.js:208 || GET | /api/vods/stream/:streamId/live | server/media-proxy/vods.js:228 || POST | /api/vods/upload | server/media-proxy/vods.js:578 |--| GET | /banned | server/index.js:948 |--| POST | /banned/continue | server/index.js:918 |--| GET | /canvas | server/index.js:650 |--| GET | /data/pastes/screenshots/:filename | server/index.js:573 |--| GET | /dmca | server/index.js:857 |++| GET | /banned | server/index.js:981 |++| POST | /banned/continue | server/index.js:951 |++| GET | /canvas | server/index.js:683 |++| GET | /data/pastes/screenshots/:filename | server/index.js:606 |++| GET | /dmca | server/index.js:890 || GET | /docs | server/docs/routes.js:304 || GET | /docs/:name | server/docs/routes.js:306 || GET | /docs/:name.md | server/docs/routes.js:305 |--| GET | /game | server/index.js:649 |++| GET | /game | server/index.js:682 || POST | /internal/ai/site-copy | server/internal/routes.js:25 |--| GET | /internal/analytics-summary | server/index.js:545 |--| POST | /internal/media-webhook | server/index.js:540 |++| GET | /internal/analytics-summary | server/index.js:578 |++| POST | /internal/media-webhook | server/index.js:573 || POST | /internal/url-registry/refresh | server/internal/routes.js:49 || POST | /internal/user-avatar | server/internal/routes.js:67 || POST | /internal/user-role | server/internal/routes.js:91 |--| GET | /media/:username | server/index.js:852 |--| GET | /obs/chat/:username | server/index.js:840 |--| GET | /openvibe-sw.js | server/index.js:446 |--| GET | /overlay/chat/:username | server/index.js:848 |--| GET | /overlay/chat/:username/:slotIdOrSlug | server/index.js:845 |--| GET | /p/:slug | server/index.js:591 |--| GET | /p/:slug/raw | server/index.js:602 |--| GET | /p/:slug/screenshot | server/index.js:598 |--| GET | /pastes | server/index.js:592 |--| GET | /privacy | server/index.js:866 |++| GET | /media/:username | server/index.js:885 |++| GET | /obs/chat/:username | server/index.js:873 |++| GET | /openvibe-sw.js | server/index.js:474 |++| GET | /overlay/chat/:username | server/index.js:881 |++| GET | /overlay/chat/:username/:slotIdOrSlug | server/index.js:878 |++| GET | /p/:slug | server/index.js:624 |++| GET | /p/:slug/raw | server/index.js:635 |++| GET | /p/:slug/screenshot | server/index.js:631 |++| GET | /pastes | server/index.js:625 |++| GET | /privacy | server/index.js:899 || GET | /sitemap.xml | server/seo/seo.js:594 |--| GET | /terms | server/index.js:863 |--| GET | /tos | server/index.js:860 |--| POST | /whip/:streamId | server/index.js:875 |--| DELETE | /whip/:streamId/:resourceId | server/index.js:877 |--| PATCH | /whip/:streamId/:resourceId | server/index.js:876 |++| GET | /terms | server/index.js:896 |++| GET | /tos | server/index.js:893 |++| POST | /whip/:streamId | server/index.js:908 |++| DELETE | /whip/:streamId/:resourceId | server/index.js:910 |++| PATCH | /whip/:streamId/:resourceId | server/index.js:909 |## OpenVibe.Network@@@ -23,15 +23,15 @@ Deliverable 4, plus the background-job half of the exit criteria.| Repo | Path | Referenced at ||---|---|---|--| OpenVibe.Live | /ws/ | server/index.js:418, server/index.js:428, server/index.js:969 |--| OpenVibe.Live | /ws/broadcast | server/index.js:1011, server/streaming/broadcast-server.js:187 |--| OpenVibe.Live | /ws/call | server/index.js:1015, server/streaming/call-server.js:98 |--| OpenVibe.Live | /ws/canvas | server/index.js:1017 |--| OpenVibe.Live | /ws/chat | server/chat/chat-server.js:294, server/index.js:1007 |--| OpenVibe.Live | /ws/control | server/controls/control-server.js:46, server/index.js:1013 |--| OpenVibe.Live | /ws/game | server/index.js:1017 |--| OpenVibe.Live | /ws/robotstreamer-publish | server/index.js:1019, server/integrations/robotstreamer-service.js:807 |--| OpenVibe.Live | /ws/vibe-coding/publish | server/index.js:1009, server/vibe-coding/publish-server.js:31 |++| OpenVibe.Live | /ws/ | server/index.js:418, server/index.js:428, server/index.js:1002 |++| OpenVibe.Live | /ws/broadcast | server/index.js:1044, server/streaming/broadcast-server.js:187 |++| OpenVibe.Live | /ws/call | server/index.js:1048, server/streaming/call-server.js:98 |++| OpenVibe.Live | /ws/canvas | server/index.js:1050 |++| OpenVibe.Live | /ws/chat | server/chat/chat-server.js:294, server/index.js:1040 |++| OpenVibe.Live | /ws/control | server/controls/control-server.js:46, server/index.js:1046 |++| OpenVibe.Live | /ws/game | server/index.js:1050 |++| OpenVibe.Live | /ws/robotstreamer-publish | server/index.js:1052, server/integrations/robotstreamer-service.js:807 |++| OpenVibe.Live | /ws/vibe-coding/publish | server/index.js:1042, server/vibe-coding/publish-server.js:31 || OpenVibe.Network | /ws/ | server/deploy/nginx-generator.js:151 || OpenVibe.Games | /ws | apps/server/src/main.ts:129 |@@@ -70,10 +70,10 @@ Deliverable 4, plus the background-job half of the exit criteria.| OpenVibe.Live | setInterval | | ? | server/diagnostics.js:18 || OpenVibe.Live | setInterval | | 5 min | server/home/routes.js:583 || OpenVibe.Live | setInterval | | ? | server/home/star-job.js:130 |--| OpenVibe.Live | setInterval | | 360 min | server/index.js:1289 |--| OpenVibe.Live | setInterval | | 45 s | server/index.js:1306 |--| OpenVibe.Live | setInterval | | ? | server/index.js:1330 |--| OpenVibe.Live | setInterval | | ? | server/index.js:1341 |++| OpenVibe.Live | setInterval | | 360 min | server/index.js:1322 |++| OpenVibe.Live | setInterval | | 45 s | server/index.js:1339 |++| OpenVibe.Live | setInterval | | ? | server/index.js:1363 |++| OpenVibe.Live | setInterval | | ? | server/index.js:1374 || OpenVibe.Live | setInterval | | ? | server/integrations/chat-relay-service.js:615 || OpenVibe.Live | setInterval | | 1 s | server/integrations/powerchat-platform.js:296 || OpenVibe.Live | setInterval | | ? | server/integrations/powerchat-platform.js:430 |@@@ -94,7 +94,7 @@ Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-22 23:36 UTC compared w| low | schema | OpenVibe.Live:user_voice_selection | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) || low | schema | OpenVibe.Live:user_voices | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) || low | schema | OpenVibe.Live:woodcut_profile | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |--| info | checkout | OpenVibe.Live | local checkout c9af780 differs from origin/main e266060; scan reflects the checkout |++| info | checkout | OpenVibe.Network | local checkout 33156ef differs from origin/main 06e4a6b; scan reflects the checkout || info | checkout | OpenVibe.Sites | local checkout b689b41 differs from origin/main 7b7c917; scan reflects the checkout || info | checkout | OpenVibe.Tools | local checkout 4773f7b differs from origin/main fd5d318; scan reflects the checkout || info | env | OpenVibe.Games:NODE_ENV | set in games.env but not referenced by scanned code (may be read by a dependency or stale) |@@@ -23,7 +23,7 @@ Deliverable 8. Family-level status from roadmap 3.2. Evidence paths are checked| D39 | Mods | absent | missing | W12, W21 | - | - || D40 | Open developer services | absent | missing | W20, W21 | Live/server/integrations/powerchat-routes.js | 28 of 61 call sites authenticate with the shared internal key || D41 | Independent runtime lifecycle | partial | partial | W7, W21 | Live/deploy | hazard H1; hazard H3 |--| D42 | Shared component architecture | partial | partial | W2, Track R | Shared/files.js; Network/package.json | 4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0; 2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared) |++| D42 | Shared component architecture | partial | partial | W2, Track R | Shared/files.js; Network/package.json | 3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0; 3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared) || D43 | Safe active-client updates | absent | missing | Track R | Live/server/chat/deploy-notice.js; Live/server/web/assets.js | - || D44 | Crawlable component rendering | built | already-present-and-verified | Track R (preserve) | Community/server/seo.js; Sites/build.js | - || D45 | Release compatibility and recovery | absent | missing | Track R, W22 | - | 5 service(s) not running origin/main |@@@ -20,6 +20,7 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr| H12 | No Cloudflare cache-purge step after deploys | low | open | Platform operator | W21 / Track I | Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets. | - || H13 | Production drifts from main | medium | open | Platform operator | W0 (checklist) / W21 (release manifests) | Deploy or record why each lagging service is held back. | media: deployed ddfefcf is 1 commit(s) behind origin/main cced10f; network: deployed 1b79576 is 8 commit(s) behind origin/main 06e4a6b; sites: deployed 185014f is 1 commit(s) behind origin/main 7b7c917; tools: deployed 0346edc is 1 commit(s) behind origin/main fd5d318; games: deployed 43c11f0 has the same file tree as origin/main 5710287 but a different SHA (pre-rewrite history); reset the checkout so later pulls fast-forward || H14 | Dead and backup database files on the production host | low | open | Live maintainers | W0 | Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date. | live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db |++| H15 | Media objects with no good copy | medium | open | Media maintainers | W4 (repair) / W22 (DR drills) | Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings. | 2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt). |## Constraints@@@ -37,3 +38,4 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr- **H12** (roadmap 2.7.5): A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.- **H13** (this baseline (prod-snapshot.json)): A service running an older commit than main means repo-based reasoning does not describe production.- **H14** (this baseline (prod-snapshot.json)): Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.++- **H15** (OpenVibe.Media reconcile-objects.js --verify, 2026-09-23): The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy. _Evidence: 2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt)._@@@ -2,7 +2,7 @@The audit baseline from the OpenVibe development roadmap (Wave 0; section 12 items 1-3): what exists across the estate, who owns each piece of data today and who should, what production looks like next to the repos, and which hazards constrain later waves. Every file here except `data/*.json` is generated.--Source commits: Live `c9af780`, Network `06e4a6b`, Shared `9b53beb`, Media `cced10f`, Tools `4773f7b`, Community `d7c6e60`, Games `5710287`, Sites `b689b41`. Production snapshot: openvibe-oregon, 2026-09-22.++Source commits: Live `e266060`, Network `33156ef`, Shared `9b53beb`, Media `cced10f`, Tools `4773f7b`, Community `d7c6e60`, Games `5710287`, Sites `b689b41`. Production snapshot: openvibe-oregon, 2026-09-22.## Deliverables@@@ -16,7 +16,7 @@ Source commits: Live `c9af780`, Network `06e4a6b`, Shared `9b53beb`, Media `cced| 6 | [07-ownership.md](07-ownership.md) | current vs target data ownership || 7 | [08-discrepancies.md](08-discrepancies.md) | 133 production-vs-repo items || 8 | [09-d-status.md](09-d-status.md) | D01-D46 family status from evidence |--| 9 | [10-hazards.md](10-hazards.md) | 14 hazards with owners, mitigations and waves |++| 9 | [10-hazards.md](10-hazards.md) | 15 hazards with owners, mitigations and waves || - | [inventory.json](inventory.json) | everything above, machine-readable |## Exit criteria@@@ -3,118 +3,180 @@"reviewedBy": null,"hazards": [{-- "id": "H1", "title": "Restarting Live drops active RTMP streams",-- "source": "claude-context deploy-live", "severity": "high",++ "id": "H1",++ "title": "Restarting Live drops active RTMP streams",++ "source": "claude-context deploy-live",++ "severity": "high","constraint": "RTMP ingest is owned by the Live Node process; a restart disconnects every RTMP broadcaster.",-- "owner": "Live maintainers", "wave": "W7 (OpenRe extraction removes the class); W21 encodes the rule in deploy tooling",++ "owner": "Live maintainers",++ "wave": "W7 (OpenRe extraction removes the class); W21 encodes the rule in deploy tooling","mitigation": "Deploy Live with deploy.sh --wait-idle after checking /api/streams; never restart mid-broadcast for UI-only changes (static deploys need no restart).","status": "open"},{-- "id": "H2", "title": "Stopping the Live socket unit causes 502s",-- "source": "claude-context deploy-zero-downtime", "severity": "medium",++ "id": "H2",++ "title": "Stopping the Live socket unit causes 502s",++ "source": "claude-context deploy-zero-downtime",++ "severity": "medium","constraint": "Live uses systemd socket activation; stopping openvibe-live.socket drops the listening socket.",-- "owner": "Platform operator", "wave": "W21",++ "owner": "Platform operator",++ "wave": "W21","mitigation": "Restart only openvibe-live.service; poll /api/ready (boot ~6s).",-- "status": "open", "check": "live-socket-unit"++ "status": "open",++ "check": "live-socket-unit"},{-- "id": "H3", "title": "Media restart during a recording orphans finalisation",-- "source": "claude-context media-vod-offload; roadmap 2.7.6", "severity": "high",++ "id": "H3",++ "title": "Media restart during a recording orphans finalisation",++ "source": "claude-context media-vod-offload; roadmap 2.7.6",++ "severity": "high","constraint": "Recording/finalisation runs inside the Media process. 55 objects / 14.50 GB already sit under B2 vods-orphans/ (21 Sep 2026).",-- "owner": "Media maintainers", "wave": "W4 (reconciliation + duration repair) / W7 (recording ownership to OpenRe)",++ "owner": "Media maintainers",++ "wave": "W4 (reconciliation + duration repair) / W7 (recording ownership to OpenRe)","mitigation": "Do not restart Media while a recording is active; reconcile vods-orphans/ before any retention change.","status": "open"},{-- "id": "H4", "title": "managed_streams.stream_key values still need rotation after a past leak",-- "source": "claude-context seadragon-engineering-pass", "severity": "high",++ "id": "H4",++ "title": "managed_streams.stream_key values still need rotation after a past leak",++ "source": "claude-context seadragon-engineering-pass",++ "severity": "high","constraint": "Leaked keys remain valid until rotated; a rotation tool was declined earlier.",-- "owner": "Live maintainers (security track S)", "wave": "W7 (openre.key.rotate) - or earlier as a standalone rotation",++ "owner": "Live maintainers (security track S)",++ "wave": "W7 (openre.key.rotate) - or earlier as a standalone rotation","mitigation": "Ship per-stream key regeneration and rotate every key; notify affected streamers.","status": "open"},{-- "id": "H5", "title": "Multilingual Whisper model missing breaks non-English captions",-- "source": "claude-context japaneseoldguy-i18n", "severity": "medium",++ "id": "H5",++ "title": "Multilingual Whisper model missing breaks non-English captions",++ "source": "claude-context japaneseoldguy-i18n",++ "severity": "medium","constraint": "Without WHISPER_MODEL_MULTI transcribe.js falls back to the English model.",-- "owner": "Live maintainers", "wave": "-",++ "owner": "Live maintainers",++ "wave": "-","mitigation": "Install the model and set WHISPER_MODEL_MULTI in live.env.",-- "status": "mitigated", "evidence": "2026-09-22: WHISPER_MODEL_MULTI is set in /etc/openvibe/live.env and the file it names exists on openvibe-oregon (checked with test -f; path not recorded).",++ "status": "mitigated",++ "evidence": "2026-09-22: WHISPER_MODEL_MULTI is set in /etc/openvibe/live.env and the file it names exists on openvibe-oregon (checked with test -f; path not recorded).","check": "env:live.env:WHISPER_MODEL_MULTI"},{-- "id": "H6", "title": "YouTube refuses the server IP; the yt tool needs a proxy",-- "source": "claude-context tools-registry-domains", "severity": "low",++ "id": "H6",++ "title": "YouTube refuses the server IP; the yt tool needs a proxy",++ "source": "claude-context tools-registry-domains",++ "severity": "low","constraint": "Environment problem, not code: yt downloads fail from the host address.",-- "owner": "Platform operator", "wave": "W11",++ "owner": "Platform operator",++ "wave": "W11","mitigation": "Set YT_PROXY and/or YT_COOKIES_FILE for openvibe-tools-yt.",-- "status": "open", "evidence": "2026-09-22: neither YT_PROXY nor YT_COOKIES_FILE is set in /etc/openvibe/tools.env.",++ "status": "open",++ "evidence": "2026-09-22: neither YT_PROXY nor YT_COOKIES_FILE is set in /etc/openvibe/tools.env.","check": "env-absent:tools.env:YT_PROXY"},{-- "id": "H7", "title": "Workstation root disk near full; headless Chrome can hit ENOSPC",-- "source": "claude-context seadragon-engineering-pass", "severity": "low",++ "id": "H7",++ "title": "Workstation root disk near full; headless Chrome can hit ENOSPC",++ "source": "claude-context seadragon-engineering-pass",++ "severity": "low","constraint": "Browser acceptance runs on the workstation fail when the disk fills.",-- "owner": "Workstation owner", "wave": "Track Q",++ "owner": "Workstation owner",++ "wave": "Track Q","mitigation": "Browser harness must support a remote/containerised runner; prune ~/.claude transcripts (~1.2 GB).",-- "status": "open", "check": "workstation-disk"++ "status": "open",++ "check": "workstation-disk"},{-- "id": "H8", "title": "A hardcoded internal secret was previously public",-- "source": "claude-context", "severity": "high",++ "id": "H8",++ "title": "A hardcoded internal secret was previously public",++ "source": "claude-context",++ "severity": "high","constraint": "Any surviving openvibe-internal-* value and the Cloudflare token must be treated as exposed.",-- "owner": "Platform operator (security track S)", "wave": "W1 (scoped service principals) / Track S",++ "owner": "Platform operator (security track S)",++ "wave": "W1 (scoped service principals) / Track S","mitigation": "Rotate INTERNAL_API_KEY per service and the Cloudflare token; move to scoped service tokens.","status": "open"},{-- "id": "H9", "title": "Removed features and copy rules must not be undone",-- "source": "claude-context rs-promo, network-shared-systems, afresume-site, currency-model", "severity": "medium",++ "id": "H9",++ "title": "Removed features and copy rules must not be undone",++ "source": "claude-context rs-promo, network-shared-systems, afresume-site, currency-model",++ "severity": "medium","constraint": "No RobotStreamer promo campaign, no 'free/$0/no ads' copy, never 'Earn Vibes', never call the old theme 'classic'.",-- "owner": "Every product wave", "wave": "all",++ "owner": "Every product wave",++ "wave": "all","mitigation": "Product waves check the prohibitions list (roadmap 9.1) before adding copy or campaigns.","status": "standing-rule"},{-- "id": "H10", "title": "Commit identity",-- "source": "claude-context commit-identity", "severity": "medium",++ "id": "H10",++ "title": "Commit identity",++ "source": "claude-context commit-identity",++ "severity": "medium","constraint": "Commits must be OpenVibers <[email protected]> with no assistant trailers or co-author lines.",-- "owner": "Every contributor", "wave": "all",++ "owner": "Every contributor",++ "wave": "all","mitigation": "Per-repo git config user.email = [email protected]; review history before push.",-- "status": "open", "check": "commit-identity"++ "status": "open",++ "check": "commit-identity"},{-- "id": "H11", "title": "analytics_events grows without pruning",-- "source": "roadmap 2.7.2", "severity": "medium",++ "id": "H11",++ "title": "analytics_events grows without pruning",++ "source": "roadmap 2.7.2",++ "severity": "medium","constraint": "Raw analytics_events is never pruned although hourly/daily rollups exist; Live analytics.db and network.db are the estate's largest stores.",-- "owner": "OpenVibe.Shared maintainers (openvibe-shared/analytics.js)", "wave": "Track O / ADR-021 - before any schema wave touching Live or Network",++ "owner": "OpenVibe.Shared maintainers (openvibe-shared/analytics.js)",++ "wave": "Track O / ADR-021 - before any schema wave touching Live or Network","mitigation": "Add a retention job that deletes raw rows older than the rollup window, then VACUUM in a maintenance window.",-- "status": "open", "check": "db-size"++ "status": "open",++ "check": "db-size"},{-- "id": "H12", "title": "No Cloudflare cache-purge step after deploys",-- "source": "roadmap 2.7.5", "severity": "low",++ "id": "H12",++ "title": "No Cloudflare cache-purge step after deploys",++ "source": "roadmap 2.7.5",++ "severity": "low","constraint": "A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.",-- "owner": "Platform operator", "wave": "W21 / Track I",++ "owner": "Platform operator",++ "wave": "W21 / Track I","mitigation": "Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets.","status": "open"},{-- "id": "H13", "title": "Production drifts from main",-- "source": "this baseline (prod-snapshot.json)", "severity": "medium",++ "id": "H13",++ "title": "Production drifts from main",++ "source": "this baseline (prod-snapshot.json)",++ "severity": "medium","constraint": "A service running an older commit than main means repo-based reasoning does not describe production.",-- "owner": "Platform operator", "wave": "W0 (checklist) / W21 (release manifests)",++ "owner": "Platform operator",++ "wave": "W0 (checklist) / W21 (release manifests)","mitigation": "Deploy or record why each lagging service is held back.",-- "status": "open", "check": "deploy-drift"++ "status": "open",++ "check": "deploy-drift"},{-- "id": "H14", "title": "Dead and backup database files on the production host",-- "source": "this baseline (prod-snapshot.json)", "severity": "low",++ "id": "H14",++ "title": "Dead and backup database files on the production host",++ "source": "this baseline (prod-snapshot.json)",++ "severity": "low","constraint": "Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.",-- "owner": "Live maintainers", "wave": "W0",++ "owner": "Live maintainers",++ "wave": "W0","mitigation": "Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date.",-- "status": "open", "check": "dead-dbs"++ "status": "open",++ "check": "dead-dbs"++ },++ {++ "id": "H15",++ "title": "Media objects with no good copy",++ "source": "OpenVibe.Media reconcile-objects.js --verify, 2026-09-23",++ "severity": "medium",++ "constraint": "The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy.",++ "owner": "Media maintainers",++ "wave": "W4 (repair) / W22 (DR drills)",++ "mitigation": "Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings.",++ "status": "open",++ "evidence": "2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt)."}]}@@@ -1,7 +1,7 @@{"generatedFrom": {-- "OpenVibe.Live": "c9af7800c4a528791b2e870dc7099a3d926b2733",-- "OpenVibe.Network": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",++ "OpenVibe.Live": "e26606082958f8cf6bb7c4587c225ca09335b5fe",++ "OpenVibe.Network": "33156ef5686d5e8636e2fb411b55d999cfe14953","OpenVibe.Shared": "9b53bebe7dee7884a440d620ad099631e962fd77","OpenVibe.Media": "cced10f81e529c76346d6578c8b26a5350f744be","OpenVibe.Tools": "4773f7b1098e98743be03095e44afeac1928bdf5",@@@ -19,13 +19,13 @@"service": "live","present": true,"git": {-- "head": "c9af7800c4a528791b2e870dc7099a3d926b2733",-- "branch": "seadragon",++ "head": "e26606082958f8cf6bb7c4587c225ca09335b5fe",++ "branch": "main","originMain": "e26606082958f8cf6bb7c4587c225ca09335b5fe",-- "committedAt": "2026-09-22T18:03:10-07:00"++ "committedAt": "2026-09-22T16:28:23-07:00"},"sourceFiles": 167,-- "loc": 69945,++ "loc": 69978,"tables": [{"table": "arena_profiles",@@@ -863,25 +863,25 @@},{"table": "analytics_events",-- "file": "node_modules/openvibe-shared/analytics.js",++ "file": "vendor/openvibe-shared/analytics.js","line": 74,"via": "openvibe-shared"},{"table": "analytics_hourly",-- "file": "node_modules/openvibe-shared/analytics.js",++ "file": "vendor/openvibe-shared/analytics.js","line": 98,"via": "openvibe-shared"},{"table": "analytics_daily",-- "file": "node_modules/openvibe-shared/analytics.js",++ "file": "vendor/openvibe-shared/analytics.js","line": 116,"via": "openvibe-shared"},{"table": "analytics_rate_tracking",-- "file": "node_modules/openvibe-shared/analytics.js",++ "file": "vendor/openvibe-shared/analytics.js","line": 137,"via": "openvibe-shared"}@@@ -957,13 +957,13 @@"method": "GET","path": "/api/admin/analytics","file": "server/index.js",-- "line": 675++ "line": 708},{"method": "GET","path": "/api/admin/analytics/bots","file": "server/index.js",-- "line": 684++ "line": 717},{"method": "GET",@@@ -975,7 +975,7 @@"method": "POST","path": "/api/admin/broadcast","file": "server/index.js",-- "line": 793++ "line": 826},{"method": "PUT",@@@ -2157,7 +2157,7 @@"method": "POST","path": "/api/csp-report","file": "server/index.js",-- "line": 814++ "line": 847},{"method": "GET",@@@ -2457,7 +2457,7 @@"method": "GET","path": "/api/health","file": "server/index.js",-- "line": 694++ "line": 727},{"method": "GET",@@@ -2547,7 +2547,7 @@"method": "GET","path": "/api/live-events","file": "server/index.js",-- "line": 622++ "line": 655},{"method": "POST",@@@ -3171,7 +3171,7 @@"method": "GET","path": "/api/ready","file": "server/index.js",-- "line": 717++ "line": 750},{"method": "GET",@@@ -3783,7 +3783,7 @@"method": "GET","path": "/api/updates","file": "server/index.js",-- "line": 780++ "line": 813},{"method": "GET",@@@ -3927,31 +3927,31 @@"method": "GET","path": "/banned","file": "server/index.js",-- "line": 948++ "line": 981},{"method": "POST","path": "/banned/continue","file": "server/index.js",-- "line": 918++ "line": 951},{"method": "GET","path": "/canvas","file": "server/index.js",-- "line": 650++ "line": 683},{"method": "GET","path": "/data/pastes/screenshots/:filename","file": "server/index.js",-- "line": 573++ "line": 606},{"method": "GET","path": "/dmca","file": "server/index.js",-- "line": 857++ "line": 890},{"method": "GET",@@@ -3975,7 +3975,7 @@"method": "GET","path": "/game","file": "server/index.js",-- "line": 649++ "line": 682},{"method": "POST",@@@ -3987,13 +3987,13 @@"method": "GET","path": "/internal/analytics-summary","file": "server/index.js",-- "line": 545++ "line": 578},{"method": "POST","path": "/internal/media-webhook","file": "server/index.js",-- "line": 540++ "line": 573},{"method": "POST",@@@ -4017,61 +4017,61 @@"method": "GET","path": "/media/:username","file": "server/index.js",-- "line": 852++ "line": 885},{"method": "GET","path": "/obs/chat/:username","file": "server/index.js",-- "line": 840++ "line": 873},{"method": "GET","path": "/openvibe-sw.js","file": "server/index.js",-- "line": 446++ "line": 474},{"method": "GET","path": "/overlay/chat/:username","file": "server/index.js",-- "line": 848++ "line": 881},{"method": "GET","path": "/overlay/chat/:username/:slotIdOrSlug","file": "server/index.js",-- "line": 845++ "line": 878},{"method": "GET","path": "/p/:slug","file": "server/index.js",-- "line": 591++ "line": 624},{"method": "GET","path": "/p/:slug/raw","file": "server/index.js",-- "line": 602++ "line": 635},{"method": "GET","path": "/p/:slug/screenshot","file": "server/index.js",-- "line": 598++ "line": 631},{"method": "GET","path": "/pastes","file": "server/index.js",-- "line": 592++ "line": 625},{"method": "GET","path": "/privacy","file": "server/index.js",-- "line": 866++ "line": 899},{"method": "GET",@@@ -4083,31 +4083,31 @@"method": "GET","path": "/terms","file": "server/index.js",-- "line": 863++ "line": 896},{"method": "GET","path": "/tos","file": "server/index.js",-- "line": 860++ "line": 893},{"method": "POST","path": "/whip/:streamId","file": "server/index.js",-- "line": 875++ "line": 908},{"method": "DELETE","path": "/whip/:streamId/:resourceId","file": "server/index.js",-- "line": 877++ "line": 910},{"method": "PATCH","path": "/whip/:streamId/:resourceId","file": "server/index.js",-- "line": 876++ "line": 909}],"ws": {@@@ -4169,47 +4169,47 @@{"path": "/ws/","file": "server/index.js",-- "line": 969++ "line": 1002},{"path": "/ws/chat","file": "server/index.js",-- "line": 1007++ "line": 1040},{"path": "/ws/vibe-coding/publish","file": "server/index.js",-- "line": 1009++ "line": 1042},{"path": "/ws/broadcast","file": "server/index.js",-- "line": 1011++ "line": 1044},{"path": "/ws/control","file": "server/index.js",-- "line": 1013++ "line": 1046},{"path": "/ws/call","file": "server/index.js",-- "line": 1015++ "line": 1048},{"path": "/ws/game","file": "server/index.js",-- "line": 1017++ "line": 1050},{"path": "/ws/canvas","file": "server/index.js",-- "line": 1017++ "line": 1050},{"path": "/ws/robotstreamer-publish","file": "server/index.js",-- "line": 1019++ "line": 1052},{"path": "/ws/robotstreamer-publish",@@@ -5116,28 +5116,28 @@"kind": "setInterval","name": null,"intervalMs": 21600000,-- "line": 1289,++ "line": 1322,"file": "server/index.js"},{"kind": "setInterval","name": null,"intervalMs": 45000,-- "line": 1306,++ "line": 1339,"file": "server/index.js"},{"kind": "setInterval","name": null,"intervalMs": null,-- "line": 1330,++ "line": 1363,"file": "server/index.js"},{"kind": "setInterval","name": null,"intervalMs": null,-- "line": 1341,++ "line": 1374,"file": "server/index.js"},{@@@ -5319,10 +5319,10 @@"service": "network","present": true,"git": {-- "head": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",++ "head": "33156ef5686d5e8636e2fb411b55d999cfe14953","branch": "main","originMain": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",-- "committedAt": "2026-09-22T17:55:21-07:00"++ "committedAt": "2026-09-22T18:05:33-07:00"},"sourceFiles": 52,"loc": 12043,@@@ -11174,8 +11174,8 @@{"repo": "OpenVibe.Live","manifest": "package.json",-- "spec": "v1.0.0",-- "state": "current"++ "spec": "file:./vendor/openvibe-shared",++ "state": "unpinned"},{"repo": "OpenVibe.Media",@@@ -11752,7 +11752,7 @@"repo": "OpenVibe.Live","table": "analytics_daily","declaredAt": [-- "node_modules/openvibe-shared/analytics.js:116"++ "vendor/openvibe-shared/analytics.js:116"],"prodDbs": ["analytics.db"@@@ -11768,7 +11768,7 @@"repo": "OpenVibe.Live","table": "analytics_events","declaredAt": [-- "node_modules/openvibe-shared/analytics.js:74"++ "vendor/openvibe-shared/analytics.js:74"],"prodDbs": ["analytics.db"@@@ -11784,7 +11784,7 @@"repo": "OpenVibe.Live","table": "analytics_hourly","declaredAt": [-- "node_modules/openvibe-shared/analytics.js:98"++ "vendor/openvibe-shared/analytics.js:98"],"prodDbs": ["analytics.db"@@@ -11800,7 +11800,7 @@"repo": "OpenVibe.Live","table": "analytics_rate_tracking","declaredAt": [-- "node_modules/openvibe-shared/analytics.js:137"++ "vendor/openvibe-shared/analytics.js:137"],"prodDbs": ["analytics.db"@@@ -19566,8 +19566,8 @@{"severity": "info","area": "checkout",-- "subject": "OpenVibe.Live",-- "detail": "local checkout c9af780 differs from origin/main e266060; scan reflects the checkout"++ "subject": "OpenVibe.Network",++ "detail": "local checkout 33156ef differs from origin/main 06e4a6b; scan reflects the checkout"},{"severity": "info",@@@ -19841,8 +19841,8 @@"outbound.internal-key": "28 of 61 call sites authenticate with the shared internal key","ws.servers": "10 WebSocket server constructions","tables.analytics-copies": "3 repos carry their own analytics_events",-- "shared.pins": "4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0",-- "shared.drift": "2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)",++ "shared.pins": "3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0",++ "shared.drift": "3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)","ci.repos": "5 of 8 scanned repos have .github/workflows","deploy.drift": "5 service(s) not running origin/main","tests.OpenVibe.Live": "58 test files",@@@ -20322,11 +20322,11 @@"metrics": [{"key": "shared.pins",-- "value": "4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0"++ "value": "3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0"},{"key": "shared.drift",-- "value": "2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)"++ "value": "3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)"}],"verified": true@@@ -20586,6 +20586,19 @@"status": "open","check": "dead-dbs","checkResult": "live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db"++ },++ {++ "id": "H15",++ "title": "Media objects with no good copy",++ "source": "OpenVibe.Media reconcile-objects.js --verify, 2026-09-23",++ "severity": "medium",++ "constraint": "The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy.",++ "owner": "Media maintainers",++ "wave": "W4 (repair) / W22 (DR drills)",++ "mitigation": "Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings.",++ "status": "open",++ "evidence": "2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt).",++ "checkResult": null}],"criteria": [
@@ -20,8 +20,8 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
@@ -20,8 +20,8 @@ Deliverable 1: runtimes, ports, units, env files and repository state.
| Repo | HEAD | origin/main | Source files | LOC | Test files | CI | Routes | Tables | WS servers | Timers/jobs | TODO(contract) |
| Repo | HEAD | origin/main | Source files | LOC | Test files | CI | Routes | Tables | WS servers | Timers/jobs | TODO(contract) |
|---|---|---|---|---|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|---|---|---|---|---|
-| OpenVibe.Live | c9af780 | e266060 | 167 | 69945 | 58 | yes | 537 | 125 | 8 | 48 | 15 |
-| OpenVibe.Network | 06e4a6b | 06e4a6b | 52 | 12043 | 15 | yes | 207 | 39 | 0 | 6 | 0 |
+| OpenVibe.Live | e266060 | e266060 | 167 | 69978 | 58 | yes | 537 | 125 | 8 | 48 | 15 |
+| OpenVibe.Network | 33156ef | 06e4a6b | 52 | 12043 | 15 | yes | 207 | 39 | 0 | 6 | 0 |
| OpenVibe.Shared | 9b53beb | 9b53beb | 35 | 9484 | 11 | yes | 1 | 0 | 0 | 5 | 0 |
| OpenVibe.Shared | 9b53beb | 9b53beb | 35 | 9484 | 11 | yes | 1 | 0 | 0 | 5 | 0 |
| OpenVibe.Media | cced10f | cced10f | 34 | 10436 | 9 | yes | 90 | 18 | 0 | 9 | 0 |
| OpenVibe.Media | cced10f | cced10f | 34 | 10436 | 9 | yes | 90 | 18 | 0 | 9 | 0 |
| OpenVibe.Tools | 4773f7b | fd5d318 | 117 | 20013 | 2 | no | 99 | 4 | 0 | 12 | 0 |
| OpenVibe.Tools | 4773f7b | fd5d318 | 117 | 20013 | 2 | no | 99 | 4 | 0 | 12 | 0 |
@@ -38,10 +38,10 @@ Deliverable 2: every table declared in code or present in production, with curre
@@ -38,10 +38,10 @@ Deliverable 2: every table declared in code or present in production, with curre
| ai_usage | server/db/database.js:1258 | live.db | OpenVibe.AI | extract | W13 |
| ai_usage | server/db/database.js:1258 | live.db | OpenVibe.AI | extract | W13 |
| ai_viewer_log | server/db/database.js:1891 | live.db | OpenVibe.AI | extract | W13 |
| ai_viewer_log | server/db/database.js:1891 | live.db | OpenVibe.AI | extract | W13 |
| ai_viewer_threads | server/db/database.js:1877 | live.db | OpenVibe.AI | extract | W13 |
| ai_viewer_threads | server/db/database.js:1877 | live.db | OpenVibe.AI | extract | W13 |
-| analytics_daily | node_modules/openvibe-shared/analytics.js:116 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
-| analytics_events | node_modules/openvibe-shared/analytics.js:74 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
-| analytics_hourly | node_modules/openvibe-shared/analytics.js:98 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
-| analytics_rate_tracking | node_modules/openvibe-shared/analytics.js:137 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
+| analytics_daily | vendor/openvibe-shared/analytics.js:116 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
+| analytics_events | vendor/openvibe-shared/analytics.js:74 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
+| analytics_hourly | vendor/openvibe-shared/analytics.js:98 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
+| analytics_rate_tracking | vendor/openvibe-shared/analytics.js:137 | analytics.db | OpenVibe.Live | keep | Track O / ADR-021 |
| analytics_snapshots | (prod only) | rs-companion.db | OpenVibe.Games (import source) | frozen-legacy | W12 |
| analytics_snapshots | (prod only) | rs-companion.db | OpenVibe.Games (import source) | frozen-legacy | W12 |
| anon_ip_mappings | server/db/database.js:940 | live.db | OpenVibe.Network (policy) | extract | W1 |
| anon_ip_mappings | server/db/database.js:940 | live.db | OpenVibe.Network (policy) | extract | W1 |
| api_keys | server/db/schema.sql:391 | live.db | OpenVibe.Network (principals) / OpenVibe.Codes | extract | W1/W20 |
| api_keys | server/db/schema.sql:391 | live.db | OpenVibe.Network (principals) / OpenVibe.Codes | extract | W1/W20 |
@@ -32,10 +32,10 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -32,10 +32,10 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| POST | /api/admin/ai/viewers/:userId/:action | server/admin/routes.js:522 |
| POST | /api/admin/ai/viewers/:userId/:action | server/admin/routes.js:522 |
| GET | /api/admin/ai/viewers/:userId/log | server/admin/routes.js:532 |
| GET | /api/admin/ai/viewers/:userId/log | server/admin/routes.js:532 |
| GET | /api/admin/ai/viewers/status | server/admin/routes.js:504 |
| GET | /api/admin/ai/viewers/status | server/admin/routes.js:504 |
-| GET | /api/admin/analytics | server/index.js:675 |
-| GET | /api/admin/analytics/bots | server/index.js:684 |
+| GET | /api/admin/analytics | server/index.js:708 |
+| GET | /api/admin/analytics/bots | server/index.js:717 |
| GET | /api/admin/bans | server/admin/routes.js:429 |
| GET | /api/admin/bans | server/admin/routes.js:429 |
-| POST | /api/admin/broadcast | server/index.js:793 |
+| POST | /api/admin/broadcast | server/index.js:826 |
| PUT | /api/admin/channels/:id/force-nsfw | server/admin/routes.js:359 |
| PUT | /api/admin/channels/:id/force-nsfw | server/admin/routes.js:359 |
| GET | /api/admin/diagnostics | server/admin/routes.js:51 |
| GET | /api/admin/diagnostics | server/admin/routes.js:51 |
| DELETE | /api/admin/media-tools/cookies | server/admin/routes.js:1214 |
| DELETE | /api/admin/media-tools/cookies | server/admin/routes.js:1214 |
@@ -232,7 +232,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -232,7 +232,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| POST | /api/cosmetics/internal-unlock | server/monetization/cosmetics-routes.js:95 |
| POST | /api/cosmetics/internal-unlock | server/monetization/cosmetics-routes.js:95 |
| GET | /api/cosmetics/inventory | server/monetization/cosmetics-routes.js:32 |
| GET | /api/cosmetics/inventory | server/monetization/cosmetics-routes.js:32 |
| POST | /api/cosmetics/unequip | server/monetization/cosmetics-routes.js:55 |
| POST | /api/cosmetics/unequip | server/monetization/cosmetics-routes.js:55 |
-| POST | /api/csp-report | server/index.js:814 |
+| POST | /api/csp-report | server/index.js:847 |
| GET | /api/dm/blocks | server/chat/dm-routes.js:401 |
| GET | /api/dm/blocks | server/chat/dm-routes.js:401 |
| DELETE | /api/dm/blocks/:userId | server/chat/dm-routes.js:389 |
| DELETE | /api/dm/blocks/:userId | server/chat/dm-routes.js:389 |
| POST | /api/dm/blocks/:userId | server/chat/dm-routes.js:374 |
| POST | /api/dm/blocks/:userId | server/chat/dm-routes.js:374 |
@@ -282,7 +282,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -282,7 +282,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| GET | /api/funds/leaderboard/:streamId | server/monetization/routes.js:198 |
| GET | /api/funds/leaderboard/:streamId | server/monetization/routes.js:198 |
| POST | /api/funds/purchase | server/monetization/routes.js:34 |
| POST | /api/funds/purchase | server/monetization/routes.js:34 |
| POST | /api/funds/recycle | server/monetization/routes.js:181 |
| POST | /api/funds/recycle | server/monetization/routes.js:181 |
-| GET | /api/health | server/index.js:694 |
+| GET | /api/health | server/index.js:727 |
| GET | /api/home/digest | server/home/routes.js:457 |
| GET | /api/home/digest | server/home/routes.js:457 |
| GET | /api/home/discover | server/home/routes.js:507 |
| GET | /api/home/discover | server/home/routes.js:507 |
| GET | /api/home/featured | server/home/routes.js:247 |
| GET | /api/home/featured | server/home/routes.js:247 |
@@ -297,7 +297,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -297,7 +297,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| GET | /api/img-proxy | server/media/external-image-proxy.js:31 |
| GET | /api/img-proxy | server/media/external-image-proxy.js:31 |
| GET | /api/kiosk/favicon | server/kiosk/routes.js:122 |
| GET | /api/kiosk/favicon | server/kiosk/routes.js:122 |
| GET | /api/kiosk/site | server/kiosk/routes.js:77 |
| GET | /api/kiosk/site | server/kiosk/routes.js:77 |
-| GET | /api/live-events | server/index.js:622 |
+| GET | /api/live-events | server/index.js:655 |
| POST | /api/media/advance | server/media/routes.js:262 |
| POST | /api/media/advance | server/media/routes.js:262 |
| GET | /api/media/channel/:username | server/media/routes.js:52 |
| GET | /api/media/channel/:username | server/media/routes.js:52 |
| GET | /api/media/downloader/status | server/media/routes.js:413 |
| GET | /api/media/downloader/status | server/media/routes.js:413 |
@@ -401,7 +401,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -401,7 +401,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| POST | /api/powerchat/test-tip | server/integrations/powerchat-routes.js:350 |
| POST | /api/powerchat/test-tip | server/integrations/powerchat-routes.js:350 |
| GET | /api/powerchat/tip-link | server/integrations/powerchat-routes.js:291 |
| GET | /api/powerchat/tip-link | server/integrations/powerchat-routes.js:291 |
| POST | /api/powerchat/webhook | server/integrations/powerchat-routes.js:442 |
| POST | /api/powerchat/webhook | server/integrations/powerchat-routes.js:442 |
-| GET | /api/ready | server/index.js:717 |
+| GET | /api/ready | server/index.js:750 |
| GET | /api/recap/:streamId | server/recap/routes.js:21 |
| GET | /api/recap/:streamId | server/recap/routes.js:21 |
| POST | /api/recap/:streamId/regenerate | server/recap/routes.js:43 |
| POST | /api/recap/:streamId/regenerate | server/recap/routes.js:43 |
| GET | /api/recap/channel/:username | server/recap/routes.js:14 |
| GET | /api/recap/channel/:username | server/recap/routes.js:14 |
@@ -503,7 +503,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -503,7 +503,7 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| GET | /api/tts/audio/:file | server/chat/tts-routes.js:125 |
| GET | /api/tts/audio/:file | server/chat/tts-routes.js:125 |
| GET | /api/tts/settings | server/chat/tts-routes.js:43 |
| GET | /api/tts/settings | server/chat/tts-routes.js:43 |
| GET | /api/tts/voices | server/chat/tts-routes.js:33 |
| GET | /api/tts/voices | server/chat/tts-routes.js:33 |
-| GET | /api/updates | server/index.js:780 |
+| GET | /api/updates | server/index.js:813 |
| GET | /api/vibe-coding/channel/:username/:slotIdOrSlug/events | server/vibe-coding/routes.js:17 |
| GET | /api/vibe-coding/channel/:username/:slotIdOrSlug/events | server/vibe-coding/routes.js:17 |
| GET | /api/vibe-coding/managed/:managedStreamId/events | server/vibe-coding/routes.js:47 |
| GET | /api/vibe-coding/managed/:managedStreamId/events | server/vibe-coding/routes.js:47 |
| GET | /api/vibe-coding/managed/:managedStreamId/settings | server/vibe-coding/routes.js:74 |
| GET | /api/vibe-coding/managed/:managedStreamId/settings | server/vibe-coding/routes.js:74 |
@@ -527,37 +527,37 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
@@ -527,37 +527,37 @@ Deliverable 3 (routes half). Paths include the prefix of the `app.use()` mount t
| POST | /api/vods/stream/:streamId/finalize | server/media-proxy/vods.js:208 |
| POST | /api/vods/stream/:streamId/finalize | server/media-proxy/vods.js:208 |
| GET | /api/vods/stream/:streamId/live | server/media-proxy/vods.js:228 |
| GET | /api/vods/stream/:streamId/live | server/media-proxy/vods.js:228 |
| POST | /api/vods/upload | server/media-proxy/vods.js:578 |
| POST | /api/vods/upload | server/media-proxy/vods.js:578 |
-| GET | /banned | server/index.js:948 |
-| POST | /banned/continue | server/index.js:918 |
-| GET | /canvas | server/index.js:650 |
-| GET | /data/pastes/screenshots/:filename | server/index.js:573 |
-| GET | /dmca | server/index.js:857 |
+| GET | /banned | server/index.js:981 |
+| POST | /banned/continue | server/index.js:951 |
+| GET | /canvas | server/index.js:683 |
+| GET | /data/pastes/screenshots/:filename | server/index.js:606 |
+| GET | /dmca | server/index.js:890 |
| GET | /docs | server/docs/routes.js:304 |
| GET | /docs | server/docs/routes.js:304 |
| GET | /docs/:name | server/docs/routes.js:306 |
| GET | /docs/:name | server/docs/routes.js:306 |
| GET | /docs/:name.md | server/docs/routes.js:305 |
| GET | /docs/:name.md | server/docs/routes.js:305 |
-| GET | /game | server/index.js:649 |
+| GET | /game | server/index.js:682 |
| POST | /internal/ai/site-copy | server/internal/routes.js:25 |
| POST | /internal/ai/site-copy | server/internal/routes.js:25 |
-| GET | /internal/analytics-summary | server/index.js:545 |
-| POST | /internal/media-webhook | server/index.js:540 |
+| GET | /internal/analytics-summary | server/index.js:578 |
+| POST | /internal/media-webhook | server/index.js:573 |
| POST | /internal/url-registry/refresh | server/internal/routes.js:49 |
| POST | /internal/url-registry/refresh | server/internal/routes.js:49 |
| POST | /internal/user-avatar | server/internal/routes.js:67 |
| POST | /internal/user-avatar | server/internal/routes.js:67 |
| POST | /internal/user-role | server/internal/routes.js:91 |
| POST | /internal/user-role | server/internal/routes.js:91 |
-| GET | /media/:username | server/index.js:852 |
-| GET | /obs/chat/:username | server/index.js:840 |
-| GET | /openvibe-sw.js | server/index.js:446 |
-| GET | /overlay/chat/:username | server/index.js:848 |
-| GET | /overlay/chat/:username/:slotIdOrSlug | server/index.js:845 |
-| GET | /p/:slug | server/index.js:591 |
-| GET | /p/:slug/raw | server/index.js:602 |
-| GET | /p/:slug/screenshot | server/index.js:598 |
-| GET | /pastes | server/index.js:592 |
-| GET | /privacy | server/index.js:866 |
+| GET | /media/:username | server/index.js:885 |
+| GET | /obs/chat/:username | server/index.js:873 |
+| GET | /openvibe-sw.js | server/index.js:474 |
+| GET | /overlay/chat/:username | server/index.js:881 |
+| GET | /overlay/chat/:username/:slotIdOrSlug | server/index.js:878 |
+| GET | /p/:slug | server/index.js:624 |
+| GET | /p/:slug/raw | server/index.js:635 |
+| GET | /p/:slug/screenshot | server/index.js:631 |
+| GET | /pastes | server/index.js:625 |
+| GET | /privacy | server/index.js:899 |
| GET | /sitemap.xml | server/seo/seo.js:594 |
| GET | /sitemap.xml | server/seo/seo.js:594 |
-| GET | /terms | server/index.js:863 |
-| GET | /tos | server/index.js:860 |
-| POST | /whip/:streamId | server/index.js:875 |
-| DELETE | /whip/:streamId/:resourceId | server/index.js:877 |
-| PATCH | /whip/:streamId/:resourceId | server/index.js:876 |
+| GET | /terms | server/index.js:896 |
+| GET | /tos | server/index.js:893 |
+| POST | /whip/:streamId | server/index.js:908 |
+| DELETE | /whip/:streamId/:resourceId | server/index.js:910 |
+| PATCH | /whip/:streamId/:resourceId | server/index.js:909 |
## OpenVibe.Network
## OpenVibe.Network
@@ -23,15 +23,15 @@ Deliverable 4, plus the background-job half of the exit criteria.
@@ -23,15 +23,15 @@ Deliverable 4, plus the background-job half of the exit criteria.
| Repo | Path | Referenced at |
| Repo | Path | Referenced at |
|---|---|---|
|---|---|---|
-| OpenVibe.Live | /ws/ | server/index.js:418, server/index.js:428, server/index.js:969 |
-| OpenVibe.Live | /ws/broadcast | server/index.js:1011, server/streaming/broadcast-server.js:187 |
-| OpenVibe.Live | /ws/call | server/index.js:1015, server/streaming/call-server.js:98 |
-| OpenVibe.Live | /ws/canvas | server/index.js:1017 |
-| OpenVibe.Live | /ws/chat | server/chat/chat-server.js:294, server/index.js:1007 |
-| OpenVibe.Live | /ws/control | server/controls/control-server.js:46, server/index.js:1013 |
-| OpenVibe.Live | /ws/game | server/index.js:1017 |
-| OpenVibe.Live | /ws/robotstreamer-publish | server/index.js:1019, server/integrations/robotstreamer-service.js:807 |
-| OpenVibe.Live | /ws/vibe-coding/publish | server/index.js:1009, server/vibe-coding/publish-server.js:31 |
+| OpenVibe.Live | /ws/ | server/index.js:418, server/index.js:428, server/index.js:1002 |
+| OpenVibe.Live | /ws/broadcast | server/index.js:1044, server/streaming/broadcast-server.js:187 |
+| OpenVibe.Live | /ws/call | server/index.js:1048, server/streaming/call-server.js:98 |
+| OpenVibe.Live | /ws/canvas | server/index.js:1050 |
+| OpenVibe.Live | /ws/chat | server/chat/chat-server.js:294, server/index.js:1040 |
+| OpenVibe.Live | /ws/control | server/controls/control-server.js:46, server/index.js:1046 |
+| OpenVibe.Live | /ws/game | server/index.js:1050 |
+| OpenVibe.Live | /ws/robotstreamer-publish | server/index.js:1052, server/integrations/robotstreamer-service.js:807 |
+| OpenVibe.Live | /ws/vibe-coding/publish | server/index.js:1042, server/vibe-coding/publish-server.js:31 |
| OpenVibe.Network | /ws/ | server/deploy/nginx-generator.js:151 |
| OpenVibe.Network | /ws/ | server/deploy/nginx-generator.js:151 |
| OpenVibe.Games | /ws | apps/server/src/main.ts:129 |
| OpenVibe.Games | /ws | apps/server/src/main.ts:129 |
@@ -70,10 +70,10 @@ Deliverable 4, plus the background-job half of the exit criteria.
@@ -70,10 +70,10 @@ Deliverable 4, plus the background-job half of the exit criteria.
| OpenVibe.Live | setInterval | | ? | server/diagnostics.js:18 |
| OpenVibe.Live | setInterval | | ? | server/diagnostics.js:18 |
| OpenVibe.Live | setInterval | | 5 min | server/home/routes.js:583 |
| OpenVibe.Live | setInterval | | 5 min | server/home/routes.js:583 |
| OpenVibe.Live | setInterval | | ? | server/home/star-job.js:130 |
| OpenVibe.Live | setInterval | | ? | server/home/star-job.js:130 |
-| OpenVibe.Live | setInterval | | 360 min | server/index.js:1289 |
-| OpenVibe.Live | setInterval | | 45 s | server/index.js:1306 |
-| OpenVibe.Live | setInterval | | ? | server/index.js:1330 |
-| OpenVibe.Live | setInterval | | ? | server/index.js:1341 |
+| OpenVibe.Live | setInterval | | 360 min | server/index.js:1322 |
+| OpenVibe.Live | setInterval | | 45 s | server/index.js:1339 |
+| OpenVibe.Live | setInterval | | ? | server/index.js:1363 |
+| OpenVibe.Live | setInterval | | ? | server/index.js:1374 |
| OpenVibe.Live | setInterval | | ? | server/integrations/chat-relay-service.js:615 |
| OpenVibe.Live | setInterval | | ? | server/integrations/chat-relay-service.js:615 |
| OpenVibe.Live | setInterval | | 1 s | server/integrations/powerchat-platform.js:296 |
| OpenVibe.Live | setInterval | | 1 s | server/integrations/powerchat-platform.js:296 |
| OpenVibe.Live | setInterval | | ? | server/integrations/powerchat-platform.js:430 |
| OpenVibe.Live | setInterval | | ? | server/integrations/powerchat-platform.js:430 |
@@ -94,7 +94,7 @@ Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-22 23:36 UTC compared w
@@ -94,7 +94,7 @@ Deliverable 7. Snapshot of openvibe-oregon taken 2026-09-22 23:36 UTC compared w
| low | schema | OpenVibe.Live:user_voice_selection | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
| low | schema | OpenVibe.Live:user_voice_selection | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
| low | schema | OpenVibe.Live:user_voices | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
| low | schema | OpenVibe.Live:user_voices | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
| low | schema | OpenVibe.Live:woodcut_profile | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
| low | schema | OpenVibe.Live:woodcut_profile | in production (rs-companion.db) but no CREATE TABLE in the repo; classified frozen-legacy -> OpenVibe.Games (import source) |
-| info | checkout | OpenVibe.Live | local checkout c9af780 differs from origin/main e266060; scan reflects the checkout |
+| info | checkout | OpenVibe.Network | local checkout 33156ef differs from origin/main 06e4a6b; scan reflects the checkout |
| info | checkout | OpenVibe.Sites | local checkout b689b41 differs from origin/main 7b7c917; scan reflects the checkout |
| info | checkout | OpenVibe.Sites | local checkout b689b41 differs from origin/main 7b7c917; scan reflects the checkout |
| info | checkout | OpenVibe.Tools | local checkout 4773f7b differs from origin/main fd5d318; scan reflects the checkout |
| info | checkout | OpenVibe.Tools | local checkout 4773f7b differs from origin/main fd5d318; scan reflects the checkout |
| info | env | OpenVibe.Games:NODE_ENV | set in games.env but not referenced by scanned code (may be read by a dependency or stale) |
| info | env | OpenVibe.Games:NODE_ENV | set in games.env but not referenced by scanned code (may be read by a dependency or stale) |
@@ -23,7 +23,7 @@ Deliverable 8. Family-level status from roadmap 3.2. Evidence paths are checked
@@ -23,7 +23,7 @@ Deliverable 8. Family-level status from roadmap 3.2. Evidence paths are checked
| D39 | Mods | absent | missing | W12, W21 | - | - |
| D39 | Mods | absent | missing | W12, W21 | - | - |
| D40 | Open developer services | absent | missing | W20, W21 | Live/server/integrations/powerchat-routes.js | 28 of 61 call sites authenticate with the shared internal key |
| D40 | Open developer services | absent | missing | W20, W21 | Live/server/integrations/powerchat-routes.js | 28 of 61 call sites authenticate with the shared internal key |
| D41 | Independent runtime lifecycle | partial | partial | W7, W21 | Live/deploy | hazard H1; hazard H3 |
| D41 | Independent runtime lifecycle | partial | partial | W7, W21 | Live/deploy | hazard H1; hazard H3 |
-| D42 | Shared component architecture | partial | partial | W2, Track R | Shared/files.js; Network/package.json | 4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0; 2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared) |
+| D42 | Shared component architecture | partial | partial | W2, Track R | Shared/files.js; Network/package.json | 3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0; 3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared) |
| D43 | Safe active-client updates | absent | missing | Track R | Live/server/chat/deploy-notice.js; Live/server/web/assets.js | - |
| D43 | Safe active-client updates | absent | missing | Track R | Live/server/chat/deploy-notice.js; Live/server/web/assets.js | - |
| D44 | Crawlable component rendering | built | already-present-and-verified | Track R (preserve) | Community/server/seo.js; Sites/build.js | - |
| D44 | Crawlable component rendering | built | already-present-and-verified | Track R (preserve) | Community/server/seo.js; Sites/build.js | - |
| D45 | Release compatibility and recovery | absent | missing | Track R, W22 | - | 5 service(s) not running origin/main |
| D45 | Release compatibility and recovery | absent | missing | Track R, W22 | - | 5 service(s) not running origin/main |
@@ -20,6 +20,7 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr
@@ -20,6 +20,7 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr
| H12 | No Cloudflare cache-purge step after deploys | low | open | Platform operator | W21 / Track I | Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets. | - |
| H12 | No Cloudflare cache-purge step after deploys | low | open | Platform operator | W21 / Track I | Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets. | - |
| H13 | Production drifts from main | medium | open | Platform operator | W0 (checklist) / W21 (release manifests) | Deploy or record why each lagging service is held back. | media: deployed ddfefcf is 1 commit(s) behind origin/main cced10f; network: deployed 1b79576 is 8 commit(s) behind origin/main 06e4a6b; sites: deployed 185014f is 1 commit(s) behind origin/main 7b7c917; tools: deployed 0346edc is 1 commit(s) behind origin/main fd5d318; games: deployed 43c11f0 has the same file tree as origin/main 5710287 but a different SHA (pre-rewrite history); reset the checkout so later pulls fast-forward |
| H13 | Production drifts from main | medium | open | Platform operator | W0 (checklist) / W21 (release manifests) | Deploy or record why each lagging service is held back. | media: deployed ddfefcf is 1 commit(s) behind origin/main cced10f; network: deployed 1b79576 is 8 commit(s) behind origin/main 06e4a6b; sites: deployed 185014f is 1 commit(s) behind origin/main 7b7c917; tools: deployed 0346edc is 1 commit(s) behind origin/main fd5d318; games: deployed 43c11f0 has the same file tree as origin/main 5710287 but a different SHA (pre-rewrite history); reset the checkout so later pulls fast-forward |
| H14 | Dead and backup database files on the production host | low | open | Live maintainers | W0 | Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date. | live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db |
| H14 | Dead and backup database files on the production host | low | open | Live maintainers | W0 | Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date. | live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db |
+| H15 | Media objects with no good copy | medium | open | Media maintainers | W4 (repair) / W22 (DR drills) | Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings. | 2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt). |
## Constraints
## Constraints
@@ -37,3 +38,4 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr
@@ -37,3 +38,4 @@ Deliverable 9. **Not yet reviewed by the production-host owner** (Wave 0 exit cr
- **H12** (roadmap 2.7.5): A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.
- **H12** (roadmap 2.7.5): A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.
- **H13** (this baseline (prod-snapshot.json)): A service running an older commit than main means repo-based reasoning does not describe production.
- **H13** (this baseline (prod-snapshot.json)): A service running an older commit than main means repo-based reasoning does not describe production.
- **H14** (this baseline (prod-snapshot.json)): Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.
- **H14** (this baseline (prod-snapshot.json)): Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.
+- **H15** (OpenVibe.Media reconcile-objects.js --verify, 2026-09-23): The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy. _Evidence: 2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt)._
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
The audit baseline from the OpenVibe development roadmap (Wave 0; section 12 items 1-3): what exists across the estate, who owns each piece of data today and who should, what production looks like next to the repos, and which hazards constrain later waves. Every file here except `data/*.json` is generated.
The audit baseline from the OpenVibe development roadmap (Wave 0; section 12 items 1-3): what exists across the estate, who owns each piece of data today and who should, what production looks like next to the repos, and which hazards constrain later waves. Every file here except `data/*.json` is generated.
-Source commits: Live `c9af780`, Network `06e4a6b`, Shared `9b53beb`, Media `cced10f`, Tools `4773f7b`, Community `d7c6e60`, Games `5710287`, Sites `b689b41`. Production snapshot: openvibe-oregon, 2026-09-22.
+Source commits: Live `e266060`, Network `33156ef`, Shared `9b53beb`, Media `cced10f`, Tools `4773f7b`, Community `d7c6e60`, Games `5710287`, Sites `b689b41`. Production snapshot: openvibe-oregon, 2026-09-22.
## Deliverables
## Deliverables
@@ -16,7 +16,7 @@ Source commits: Live `c9af780`, Network `06e4a6b`, Shared `9b53beb`, Media `cced
@@ -16,7 +16,7 @@ Source commits: Live `c9af780`, Network `06e4a6b`, Shared `9b53beb`, Media `cced
| 6 | [07-ownership.md](07-ownership.md) | current vs target data ownership |
| 6 | [07-ownership.md](07-ownership.md) | current vs target data ownership |
| 7 | [08-discrepancies.md](08-discrepancies.md) | 133 production-vs-repo items |
| 7 | [08-discrepancies.md](08-discrepancies.md) | 133 production-vs-repo items |
| 8 | [09-d-status.md](09-d-status.md) | D01-D46 family status from evidence |
| 8 | [09-d-status.md](09-d-status.md) | D01-D46 family status from evidence |
-| 9 | [10-hazards.md](10-hazards.md) | 14 hazards with owners, mitigations and waves |
+| 9 | [10-hazards.md](10-hazards.md) | 15 hazards with owners, mitigations and waves |
| - | [inventory.json](inventory.json) | everything above, machine-readable |
| - | [inventory.json](inventory.json) | everything above, machine-readable |
## Exit criteria
## Exit criteria
@@ -3,118 +3,180 @@
@@ -3,118 +3,180 @@
"reviewedBy": null,
"reviewedBy": null,
"hazards": [
"hazards": [
{
{
- "id": "H1", "title": "Restarting Live drops active RTMP streams",
- "source": "claude-context deploy-live", "severity": "high",
+ "id": "H1",
+ "title": "Restarting Live drops active RTMP streams",
+ "source": "claude-context deploy-live",
+ "severity": "high",
"constraint": "RTMP ingest is owned by the Live Node process; a restart disconnects every RTMP broadcaster.",
"constraint": "RTMP ingest is owned by the Live Node process; a restart disconnects every RTMP broadcaster.",
- "owner": "Live maintainers", "wave": "W7 (OpenRe extraction removes the class); W21 encodes the rule in deploy tooling",
+ "owner": "Live maintainers",
+ "wave": "W7 (OpenRe extraction removes the class); W21 encodes the rule in deploy tooling",
"mitigation": "Deploy Live with deploy.sh --wait-idle after checking /api/streams; never restart mid-broadcast for UI-only changes (static deploys need no restart).",
"mitigation": "Deploy Live with deploy.sh --wait-idle after checking /api/streams; never restart mid-broadcast for UI-only changes (static deploys need no restart).",
"status": "open"
"status": "open"
},
},
{
{
- "id": "H2", "title": "Stopping the Live socket unit causes 502s",
- "source": "claude-context deploy-zero-downtime", "severity": "medium",
+ "id": "H2",
+ "title": "Stopping the Live socket unit causes 502s",
+ "source": "claude-context deploy-zero-downtime",
+ "severity": "medium",
"constraint": "Live uses systemd socket activation; stopping openvibe-live.socket drops the listening socket.",
"constraint": "Live uses systemd socket activation; stopping openvibe-live.socket drops the listening socket.",
- "owner": "Platform operator", "wave": "W21",
+ "owner": "Platform operator",
+ "wave": "W21",
"mitigation": "Restart only openvibe-live.service; poll /api/ready (boot ~6s).",
"mitigation": "Restart only openvibe-live.service; poll /api/ready (boot ~6s).",
- "status": "open", "check": "live-socket-unit"
+ "status": "open",
+ "check": "live-socket-unit"
},
},
{
{
- "id": "H3", "title": "Media restart during a recording orphans finalisation",
- "source": "claude-context media-vod-offload; roadmap 2.7.6", "severity": "high",
+ "id": "H3",
+ "title": "Media restart during a recording orphans finalisation",
+ "source": "claude-context media-vod-offload; roadmap 2.7.6",
+ "severity": "high",
"constraint": "Recording/finalisation runs inside the Media process. 55 objects / 14.50 GB already sit under B2 vods-orphans/ (21 Sep 2026).",
"constraint": "Recording/finalisation runs inside the Media process. 55 objects / 14.50 GB already sit under B2 vods-orphans/ (21 Sep 2026).",
- "owner": "Media maintainers", "wave": "W4 (reconciliation + duration repair) / W7 (recording ownership to OpenRe)",
+ "owner": "Media maintainers",
+ "wave": "W4 (reconciliation + duration repair) / W7 (recording ownership to OpenRe)",
"mitigation": "Do not restart Media while a recording is active; reconcile vods-orphans/ before any retention change.",
"mitigation": "Do not restart Media while a recording is active; reconcile vods-orphans/ before any retention change.",
"status": "open"
"status": "open"
},
},
{
{
- "id": "H4", "title": "managed_streams.stream_key values still need rotation after a past leak",
- "source": "claude-context seadragon-engineering-pass", "severity": "high",
+ "id": "H4",
+ "title": "managed_streams.stream_key values still need rotation after a past leak",
+ "source": "claude-context seadragon-engineering-pass",
+ "severity": "high",
"constraint": "Leaked keys remain valid until rotated; a rotation tool was declined earlier.",
"constraint": "Leaked keys remain valid until rotated; a rotation tool was declined earlier.",
- "owner": "Live maintainers (security track S)", "wave": "W7 (openre.key.rotate) - or earlier as a standalone rotation",
+ "owner": "Live maintainers (security track S)",
+ "wave": "W7 (openre.key.rotate) - or earlier as a standalone rotation",
"mitigation": "Ship per-stream key regeneration and rotate every key; notify affected streamers.",
"mitigation": "Ship per-stream key regeneration and rotate every key; notify affected streamers.",
"status": "open"
"status": "open"
},
},
{
{
- "id": "H5", "title": "Multilingual Whisper model missing breaks non-English captions",
- "source": "claude-context japaneseoldguy-i18n", "severity": "medium",
+ "id": "H5",
+ "title": "Multilingual Whisper model missing breaks non-English captions",
+ "source": "claude-context japaneseoldguy-i18n",
+ "severity": "medium",
"constraint": "Without WHISPER_MODEL_MULTI transcribe.js falls back to the English model.",
"constraint": "Without WHISPER_MODEL_MULTI transcribe.js falls back to the English model.",
- "owner": "Live maintainers", "wave": "-",
+ "owner": "Live maintainers",
+ "wave": "-",
"mitigation": "Install the model and set WHISPER_MODEL_MULTI in live.env.",
"mitigation": "Install the model and set WHISPER_MODEL_MULTI in live.env.",
- "status": "mitigated", "evidence": "2026-09-22: WHISPER_MODEL_MULTI is set in /etc/openvibe/live.env and the file it names exists on openvibe-oregon (checked with test -f; path not recorded).",
+ "status": "mitigated",
+ "evidence": "2026-09-22: WHISPER_MODEL_MULTI is set in /etc/openvibe/live.env and the file it names exists on openvibe-oregon (checked with test -f; path not recorded).",
"check": "env:live.env:WHISPER_MODEL_MULTI"
"check": "env:live.env:WHISPER_MODEL_MULTI"
},
},
{
{
- "id": "H6", "title": "YouTube refuses the server IP; the yt tool needs a proxy",
- "source": "claude-context tools-registry-domains", "severity": "low",
+ "id": "H6",
+ "title": "YouTube refuses the server IP; the yt tool needs a proxy",
+ "source": "claude-context tools-registry-domains",
+ "severity": "low",
"constraint": "Environment problem, not code: yt downloads fail from the host address.",
"constraint": "Environment problem, not code: yt downloads fail from the host address.",
- "owner": "Platform operator", "wave": "W11",
+ "owner": "Platform operator",
+ "wave": "W11",
"mitigation": "Set YT_PROXY and/or YT_COOKIES_FILE for openvibe-tools-yt.",
"mitigation": "Set YT_PROXY and/or YT_COOKIES_FILE for openvibe-tools-yt.",
- "status": "open", "evidence": "2026-09-22: neither YT_PROXY nor YT_COOKIES_FILE is set in /etc/openvibe/tools.env.",
+ "status": "open",
+ "evidence": "2026-09-22: neither YT_PROXY nor YT_COOKIES_FILE is set in /etc/openvibe/tools.env.",
"check": "env-absent:tools.env:YT_PROXY"
"check": "env-absent:tools.env:YT_PROXY"
},
},
{
{
- "id": "H7", "title": "Workstation root disk near full; headless Chrome can hit ENOSPC",
- "source": "claude-context seadragon-engineering-pass", "severity": "low",
+ "id": "H7",
+ "title": "Workstation root disk near full; headless Chrome can hit ENOSPC",
+ "source": "claude-context seadragon-engineering-pass",
+ "severity": "low",
"constraint": "Browser acceptance runs on the workstation fail when the disk fills.",
"constraint": "Browser acceptance runs on the workstation fail when the disk fills.",
- "owner": "Workstation owner", "wave": "Track Q",
+ "owner": "Workstation owner",
+ "wave": "Track Q",
"mitigation": "Browser harness must support a remote/containerised runner; prune ~/.claude transcripts (~1.2 GB).",
"mitigation": "Browser harness must support a remote/containerised runner; prune ~/.claude transcripts (~1.2 GB).",
- "status": "open", "check": "workstation-disk"
+ "status": "open",
+ "check": "workstation-disk"
},
},
{
{
- "id": "H8", "title": "A hardcoded internal secret was previously public",
- "source": "claude-context", "severity": "high",
+ "id": "H8",
+ "title": "A hardcoded internal secret was previously public",
+ "source": "claude-context",
+ "severity": "high",
"constraint": "Any surviving openvibe-internal-* value and the Cloudflare token must be treated as exposed.",
"constraint": "Any surviving openvibe-internal-* value and the Cloudflare token must be treated as exposed.",
- "owner": "Platform operator (security track S)", "wave": "W1 (scoped service principals) / Track S",
+ "owner": "Platform operator (security track S)",
+ "wave": "W1 (scoped service principals) / Track S",
"mitigation": "Rotate INTERNAL_API_KEY per service and the Cloudflare token; move to scoped service tokens.",
"mitigation": "Rotate INTERNAL_API_KEY per service and the Cloudflare token; move to scoped service tokens.",
"status": "open"
"status": "open"
},
},
{
{
- "id": "H9", "title": "Removed features and copy rules must not be undone",
- "source": "claude-context rs-promo, network-shared-systems, afresume-site, currency-model", "severity": "medium",
+ "id": "H9",
+ "title": "Removed features and copy rules must not be undone",
+ "source": "claude-context rs-promo, network-shared-systems, afresume-site, currency-model",
+ "severity": "medium",
"constraint": "No RobotStreamer promo campaign, no 'free/$0/no ads' copy, never 'Earn Vibes', never call the old theme 'classic'.",
"constraint": "No RobotStreamer promo campaign, no 'free/$0/no ads' copy, never 'Earn Vibes', never call the old theme 'classic'.",
- "owner": "Every product wave", "wave": "all",
+ "owner": "Every product wave",
+ "wave": "all",
"mitigation": "Product waves check the prohibitions list (roadmap 9.1) before adding copy or campaigns.",
"mitigation": "Product waves check the prohibitions list (roadmap 9.1) before adding copy or campaigns.",
"status": "standing-rule"
"status": "standing-rule"
},
},
{
{
- "id": "H10", "title": "Commit identity",
- "source": "claude-context commit-identity", "severity": "medium",
+ "id": "H10",
+ "title": "Commit identity",
+ "source": "claude-context commit-identity",
+ "severity": "medium",
"constraint": "Commits must be OpenVibers <[email protected]> with no assistant trailers or co-author lines.",
"constraint": "Commits must be OpenVibers <[email protected]> with no assistant trailers or co-author lines.",
- "owner": "Every contributor", "wave": "all",
+ "owner": "Every contributor",
+ "wave": "all",
"mitigation": "Per-repo git config user.email = [email protected]; review history before push.",
"mitigation": "Per-repo git config user.email = [email protected]; review history before push.",
- "status": "open", "check": "commit-identity"
+ "status": "open",
+ "check": "commit-identity"
},
},
{
{
- "id": "H11", "title": "analytics_events grows without pruning",
- "source": "roadmap 2.7.2", "severity": "medium",
+ "id": "H11",
+ "title": "analytics_events grows without pruning",
+ "source": "roadmap 2.7.2",
+ "severity": "medium",
"constraint": "Raw analytics_events is never pruned although hourly/daily rollups exist; Live analytics.db and network.db are the estate's largest stores.",
"constraint": "Raw analytics_events is never pruned although hourly/daily rollups exist; Live analytics.db and network.db are the estate's largest stores.",
- "owner": "OpenVibe.Shared maintainers (openvibe-shared/analytics.js)", "wave": "Track O / ADR-021 - before any schema wave touching Live or Network",
+ "owner": "OpenVibe.Shared maintainers (openvibe-shared/analytics.js)",
+ "wave": "Track O / ADR-021 - before any schema wave touching Live or Network",
"mitigation": "Add a retention job that deletes raw rows older than the rollup window, then VACUUM in a maintenance window.",
"mitigation": "Add a retention job that deletes raw rows older than the rollup window, then VACUUM in a maintenance window.",
- "status": "open", "check": "db-size"
+ "status": "open",
+ "check": "db-size"
},
},
{
{
- "id": "H12", "title": "No Cloudflare cache-purge step after deploys",
- "source": "roadmap 2.7.5", "severity": "low",
+ "id": "H12",
+ "title": "No Cloudflare cache-purge step after deploys",
+ "source": "roadmap 2.7.5",
+ "severity": "low",
"constraint": "A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.",
"constraint": "A cacheable static asset stays stale at some edges until max-age expires; the only Cloudflare token is DNS-01 scoped.",
- "owner": "Platform operator", "wave": "W21 / Track I",
+ "owner": "Platform operator",
+ "wave": "W21 / Track I",
"mitigation": "Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets.",
"mitigation": "Add a purge-scoped token and a purge step, or short max-age + stale-while-revalidate on non-hashed assets.",
"status": "open"
"status": "open"
},
},
{
{
- "id": "H13", "title": "Production drifts from main",
- "source": "this baseline (prod-snapshot.json)", "severity": "medium",
+ "id": "H13",
+ "title": "Production drifts from main",
+ "source": "this baseline (prod-snapshot.json)",
+ "severity": "medium",
"constraint": "A service running an older commit than main means repo-based reasoning does not describe production.",
"constraint": "A service running an older commit than main means repo-based reasoning does not describe production.",
- "owner": "Platform operator", "wave": "W0 (checklist) / W21 (release manifests)",
+ "owner": "Platform operator",
+ "wave": "W0 (checklist) / W21 (release manifests)",
"mitigation": "Deploy or record why each lagging service is held back.",
"mitigation": "Deploy or record why each lagging service is held back.",
- "status": "open", "check": "deploy-drift"
+ "status": "open",
+ "check": "deploy-drift"
},
},
{
{
- "id": "H14", "title": "Dead and backup database files on the production host",
- "source": "this baseline (prod-snapshot.json)", "severity": "low",
+ "id": "H14",
+ "title": "Dead and backup database files on the production host",
+ "source": "this baseline (prod-snapshot.json)",
+ "severity": "low",
"constraint": "Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.",
"constraint": "Zero-table openvibe.db/hobo.db and a 260 MB pre-migration backup sit in /opt/openvibe.live/data; nothing records whether they are needed.",
- "owner": "Live maintainers", "wave": "W0",
+ "owner": "Live maintainers",
+ "wave": "W0",
"mitigation": "Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date.",
"mitigation": "Confirm no code opens them, then delete the empty files and move the backup to /opt/backups with a retention date.",
- "status": "open", "check": "dead-dbs"
+ "status": "open",
+ "check": "dead-dbs"
+ },
+ {
+ "id": "H15",
+ "title": "Media objects with no good copy",
+ "source": "OpenVibe.Media reconcile-objects.js --verify, 2026-09-23",
+ "severity": "medium",
+ "constraint": "The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy.",
+ "owner": "Media maintainers",
+ "wave": "W4 (repair) / W22 (DR drills)",
+ "mitigation": "Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings.",
+ "status": "open",
+ "evidence": "2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt)."
}
}
]
]
}
}
@@ -1,7 +1,7 @@
@@ -1,7 +1,7 @@
{
{
"generatedFrom": {
"generatedFrom": {
- "OpenVibe.Live": "c9af7800c4a528791b2e870dc7099a3d926b2733",
- "OpenVibe.Network": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",
+ "OpenVibe.Live": "e26606082958f8cf6bb7c4587c225ca09335b5fe",
+ "OpenVibe.Network": "33156ef5686d5e8636e2fb411b55d999cfe14953",
"OpenVibe.Shared": "9b53bebe7dee7884a440d620ad099631e962fd77",
"OpenVibe.Shared": "9b53bebe7dee7884a440d620ad099631e962fd77",
"OpenVibe.Media": "cced10f81e529c76346d6578c8b26a5350f744be",
"OpenVibe.Media": "cced10f81e529c76346d6578c8b26a5350f744be",
"OpenVibe.Tools": "4773f7b1098e98743be03095e44afeac1928bdf5",
"OpenVibe.Tools": "4773f7b1098e98743be03095e44afeac1928bdf5",
@@ -19,13 +19,13 @@
@@ -19,13 +19,13 @@
"service": "live",
"service": "live",
"present": true,
"present": true,
"git": {
"git": {
- "head": "c9af7800c4a528791b2e870dc7099a3d926b2733",
- "branch": "seadragon",
+ "head": "e26606082958f8cf6bb7c4587c225ca09335b5fe",
+ "branch": "main",
"originMain": "e26606082958f8cf6bb7c4587c225ca09335b5fe",
"originMain": "e26606082958f8cf6bb7c4587c225ca09335b5fe",
- "committedAt": "2026-09-22T18:03:10-07:00"
+ "committedAt": "2026-09-22T16:28:23-07:00"
},
},
"sourceFiles": 167,
"sourceFiles": 167,
- "loc": 69945,
+ "loc": 69978,
"tables": [
"tables": [
{
{
"table": "arena_profiles",
"table": "arena_profiles",
@@ -863,25 +863,25 @@
@@ -863,25 +863,25 @@
},
},
{
{
"table": "analytics_events",
"table": "analytics_events",
- "file": "node_modules/openvibe-shared/analytics.js",
+ "file": "vendor/openvibe-shared/analytics.js",
"line": 74,
"line": 74,
"via": "openvibe-shared"
"via": "openvibe-shared"
},
},
{
{
"table": "analytics_hourly",
"table": "analytics_hourly",
- "file": "node_modules/openvibe-shared/analytics.js",
+ "file": "vendor/openvibe-shared/analytics.js",
"line": 98,
"line": 98,
"via": "openvibe-shared"
"via": "openvibe-shared"
},
},
{
{
"table": "analytics_daily",
"table": "analytics_daily",
- "file": "node_modules/openvibe-shared/analytics.js",
+ "file": "vendor/openvibe-shared/analytics.js",
"line": 116,
"line": 116,
"via": "openvibe-shared"
"via": "openvibe-shared"
},
},
{
{
"table": "analytics_rate_tracking",
"table": "analytics_rate_tracking",
- "file": "node_modules/openvibe-shared/analytics.js",
+ "file": "vendor/openvibe-shared/analytics.js",
"line": 137,
"line": 137,
"via": "openvibe-shared"
"via": "openvibe-shared"
}
}
@@ -957,13 +957,13 @@
@@ -957,13 +957,13 @@
"method": "GET",
"method": "GET",
"path": "/api/admin/analytics",
"path": "/api/admin/analytics",
"file": "server/index.js",
"file": "server/index.js",
- "line": 675
+ "line": 708
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/api/admin/analytics/bots",
"path": "/api/admin/analytics/bots",
"file": "server/index.js",
"file": "server/index.js",
- "line": 684
+ "line": 717
},
},
{
{
"method": "GET",
"method": "GET",
@@ -975,7 +975,7 @@
@@ -975,7 +975,7 @@
"method": "POST",
"method": "POST",
"path": "/api/admin/broadcast",
"path": "/api/admin/broadcast",
"file": "server/index.js",
"file": "server/index.js",
- "line": 793
+ "line": 826
},
},
{
{
"method": "PUT",
"method": "PUT",
@@ -2157,7 +2157,7 @@
@@ -2157,7 +2157,7 @@
"method": "POST",
"method": "POST",
"path": "/api/csp-report",
"path": "/api/csp-report",
"file": "server/index.js",
"file": "server/index.js",
- "line": 814
+ "line": 847
},
},
{
{
"method": "GET",
"method": "GET",
@@ -2457,7 +2457,7 @@
@@ -2457,7 +2457,7 @@
"method": "GET",
"method": "GET",
"path": "/api/health",
"path": "/api/health",
"file": "server/index.js",
"file": "server/index.js",
- "line": 694
+ "line": 727
},
},
{
{
"method": "GET",
"method": "GET",
@@ -2547,7 +2547,7 @@
@@ -2547,7 +2547,7 @@
"method": "GET",
"method": "GET",
"path": "/api/live-events",
"path": "/api/live-events",
"file": "server/index.js",
"file": "server/index.js",
- "line": 622
+ "line": 655
},
},
{
{
"method": "POST",
"method": "POST",
@@ -3171,7 +3171,7 @@
@@ -3171,7 +3171,7 @@
"method": "GET",
"method": "GET",
"path": "/api/ready",
"path": "/api/ready",
"file": "server/index.js",
"file": "server/index.js",
- "line": 717
+ "line": 750
},
},
{
{
"method": "GET",
"method": "GET",
@@ -3783,7 +3783,7 @@
@@ -3783,7 +3783,7 @@
"method": "GET",
"method": "GET",
"path": "/api/updates",
"path": "/api/updates",
"file": "server/index.js",
"file": "server/index.js",
- "line": 780
+ "line": 813
},
},
{
{
"method": "GET",
"method": "GET",
@@ -3927,31 +3927,31 @@
@@ -3927,31 +3927,31 @@
"method": "GET",
"method": "GET",
"path": "/banned",
"path": "/banned",
"file": "server/index.js",
"file": "server/index.js",
- "line": 948
+ "line": 981
},
},
{
{
"method": "POST",
"method": "POST",
"path": "/banned/continue",
"path": "/banned/continue",
"file": "server/index.js",
"file": "server/index.js",
- "line": 918
+ "line": 951
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/canvas",
"path": "/canvas",
"file": "server/index.js",
"file": "server/index.js",
- "line": 650
+ "line": 683
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/data/pastes/screenshots/:filename",
"path": "/data/pastes/screenshots/:filename",
"file": "server/index.js",
"file": "server/index.js",
- "line": 573
+ "line": 606
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/dmca",
"path": "/dmca",
"file": "server/index.js",
"file": "server/index.js",
- "line": 857
+ "line": 890
},
},
{
{
"method": "GET",
"method": "GET",
@@ -3975,7 +3975,7 @@
@@ -3975,7 +3975,7 @@
"method": "GET",
"method": "GET",
"path": "/game",
"path": "/game",
"file": "server/index.js",
"file": "server/index.js",
- "line": 649
+ "line": 682
},
},
{
{
"method": "POST",
"method": "POST",
@@ -3987,13 +3987,13 @@
@@ -3987,13 +3987,13 @@
"method": "GET",
"method": "GET",
"path": "/internal/analytics-summary",
"path": "/internal/analytics-summary",
"file": "server/index.js",
"file": "server/index.js",
- "line": 545
+ "line": 578
},
},
{
{
"method": "POST",
"method": "POST",
"path": "/internal/media-webhook",
"path": "/internal/media-webhook",
"file": "server/index.js",
"file": "server/index.js",
- "line": 540
+ "line": 573
},
},
{
{
"method": "POST",
"method": "POST",
@@ -4017,61 +4017,61 @@
@@ -4017,61 +4017,61 @@
"method": "GET",
"method": "GET",
"path": "/media/:username",
"path": "/media/:username",
"file": "server/index.js",
"file": "server/index.js",
- "line": 852
+ "line": 885
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/obs/chat/:username",
"path": "/obs/chat/:username",
"file": "server/index.js",
"file": "server/index.js",
- "line": 840
+ "line": 873
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/openvibe-sw.js",
"path": "/openvibe-sw.js",
"file": "server/index.js",
"file": "server/index.js",
- "line": 446
+ "line": 474
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/overlay/chat/:username",
"path": "/overlay/chat/:username",
"file": "server/index.js",
"file": "server/index.js",
- "line": 848
+ "line": 881
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/overlay/chat/:username/:slotIdOrSlug",
"path": "/overlay/chat/:username/:slotIdOrSlug",
"file": "server/index.js",
"file": "server/index.js",
- "line": 845
+ "line": 878
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/p/:slug",
"path": "/p/:slug",
"file": "server/index.js",
"file": "server/index.js",
- "line": 591
+ "line": 624
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/p/:slug/raw",
"path": "/p/:slug/raw",
"file": "server/index.js",
"file": "server/index.js",
- "line": 602
+ "line": 635
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/p/:slug/screenshot",
"path": "/p/:slug/screenshot",
"file": "server/index.js",
"file": "server/index.js",
- "line": 598
+ "line": 631
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/pastes",
"path": "/pastes",
"file": "server/index.js",
"file": "server/index.js",
- "line": 592
+ "line": 625
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/privacy",
"path": "/privacy",
"file": "server/index.js",
"file": "server/index.js",
- "line": 866
+ "line": 899
},
},
{
{
"method": "GET",
"method": "GET",
@@ -4083,31 +4083,31 @@
@@ -4083,31 +4083,31 @@
"method": "GET",
"method": "GET",
"path": "/terms",
"path": "/terms",
"file": "server/index.js",
"file": "server/index.js",
- "line": 863
+ "line": 896
},
},
{
{
"method": "GET",
"method": "GET",
"path": "/tos",
"path": "/tos",
"file": "server/index.js",
"file": "server/index.js",
- "line": 860
+ "line": 893
},
},
{
{
"method": "POST",
"method": "POST",
"path": "/whip/:streamId",
"path": "/whip/:streamId",
"file": "server/index.js",
"file": "server/index.js",
- "line": 875
+ "line": 908
},
},
{
{
"method": "DELETE",
"method": "DELETE",
"path": "/whip/:streamId/:resourceId",
"path": "/whip/:streamId/:resourceId",
"file": "server/index.js",
"file": "server/index.js",
- "line": 877
+ "line": 910
},
},
{
{
"method": "PATCH",
"method": "PATCH",
"path": "/whip/:streamId/:resourceId",
"path": "/whip/:streamId/:resourceId",
"file": "server/index.js",
"file": "server/index.js",
- "line": 876
+ "line": 909
}
}
],
],
"ws": {
"ws": {
@@ -4169,47 +4169,47 @@
@@ -4169,47 +4169,47 @@
{
{
"path": "/ws/",
"path": "/ws/",
"file": "server/index.js",
"file": "server/index.js",
- "line": 969
+ "line": 1002
},
},
{
{
"path": "/ws/chat",
"path": "/ws/chat",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1007
+ "line": 1040
},
},
{
{
"path": "/ws/vibe-coding/publish",
"path": "/ws/vibe-coding/publish",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1009
+ "line": 1042
},
},
{
{
"path": "/ws/broadcast",
"path": "/ws/broadcast",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1011
+ "line": 1044
},
},
{
{
"path": "/ws/control",
"path": "/ws/control",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1013
+ "line": 1046
},
},
{
{
"path": "/ws/call",
"path": "/ws/call",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1015
+ "line": 1048
},
},
{
{
"path": "/ws/game",
"path": "/ws/game",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1017
+ "line": 1050
},
},
{
{
"path": "/ws/canvas",
"path": "/ws/canvas",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1017
+ "line": 1050
},
},
{
{
"path": "/ws/robotstreamer-publish",
"path": "/ws/robotstreamer-publish",
"file": "server/index.js",
"file": "server/index.js",
- "line": 1019
+ "line": 1052
},
},
{
{
"path": "/ws/robotstreamer-publish",
"path": "/ws/robotstreamer-publish",
@@ -5116,28 +5116,28 @@
@@ -5116,28 +5116,28 @@
"kind": "setInterval",
"kind": "setInterval",
"name": null,
"name": null,
"intervalMs": 21600000,
"intervalMs": 21600000,
- "line": 1289,
+ "line": 1322,
"file": "server/index.js"
"file": "server/index.js"
},
},
{
{
"kind": "setInterval",
"kind": "setInterval",
"name": null,
"name": null,
"intervalMs": 45000,
"intervalMs": 45000,
- "line": 1306,
+ "line": 1339,
"file": "server/index.js"
"file": "server/index.js"
},
},
{
{
"kind": "setInterval",
"kind": "setInterval",
"name": null,
"name": null,
"intervalMs": null,
"intervalMs": null,
- "line": 1330,
+ "line": 1363,
"file": "server/index.js"
"file": "server/index.js"
},
},
{
{
"kind": "setInterval",
"kind": "setInterval",
"name": null,
"name": null,
"intervalMs": null,
"intervalMs": null,
- "line": 1341,
+ "line": 1374,
"file": "server/index.js"
"file": "server/index.js"
},
},
{
{
@@ -5319,10 +5319,10 @@
@@ -5319,10 +5319,10 @@
"service": "network",
"service": "network",
"present": true,
"present": true,
"git": {
"git": {
- "head": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",
+ "head": "33156ef5686d5e8636e2fb411b55d999cfe14953",
"branch": "main",
"branch": "main",
"originMain": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",
"originMain": "06e4a6bd803f7dc358cbb5ee21dff888c594b07c",
- "committedAt": "2026-09-22T17:55:21-07:00"
+ "committedAt": "2026-09-22T18:05:33-07:00"
},
},
"sourceFiles": 52,
"sourceFiles": 52,
"loc": 12043,
"loc": 12043,
@@ -11174,8 +11174,8 @@
@@ -11174,8 +11174,8 @@
{
{
"repo": "OpenVibe.Live",
"repo": "OpenVibe.Live",
"manifest": "package.json",
"manifest": "package.json",
- "spec": "v1.0.0",
- "state": "current"
+ "spec": "file:./vendor/openvibe-shared",
+ "state": "unpinned"
},
},
{
{
"repo": "OpenVibe.Media",
"repo": "OpenVibe.Media",
@@ -11752,7 +11752,7 @@
@@ -11752,7 +11752,7 @@
"repo": "OpenVibe.Live",
"repo": "OpenVibe.Live",
"table": "analytics_daily",
"table": "analytics_daily",
"declaredAt": [
"declaredAt": [
- "node_modules/openvibe-shared/analytics.js:116"
+ "vendor/openvibe-shared/analytics.js:116"
],
],
"prodDbs": [
"prodDbs": [
"analytics.db"
"analytics.db"
@@ -11768,7 +11768,7 @@
@@ -11768,7 +11768,7 @@
"repo": "OpenVibe.Live",
"repo": "OpenVibe.Live",
"table": "analytics_events",
"table": "analytics_events",
"declaredAt": [
"declaredAt": [
- "node_modules/openvibe-shared/analytics.js:74"
+ "vendor/openvibe-shared/analytics.js:74"
],
],
"prodDbs": [
"prodDbs": [
"analytics.db"
"analytics.db"
@@ -11784,7 +11784,7 @@
@@ -11784,7 +11784,7 @@
"repo": "OpenVibe.Live",
"repo": "OpenVibe.Live",
"table": "analytics_hourly",
"table": "analytics_hourly",
"declaredAt": [
"declaredAt": [
- "node_modules/openvibe-shared/analytics.js:98"
+ "vendor/openvibe-shared/analytics.js:98"
],
],
"prodDbs": [
"prodDbs": [
"analytics.db"
"analytics.db"
@@ -11800,7 +11800,7 @@
@@ -11800,7 +11800,7 @@
"repo": "OpenVibe.Live",
"repo": "OpenVibe.Live",
"table": "analytics_rate_tracking",
"table": "analytics_rate_tracking",
"declaredAt": [
"declaredAt": [
- "node_modules/openvibe-shared/analytics.js:137"
+ "vendor/openvibe-shared/analytics.js:137"
],
],
"prodDbs": [
"prodDbs": [
"analytics.db"
"analytics.db"
@@ -19566,8 +19566,8 @@
@@ -19566,8 +19566,8 @@
{
{
"severity": "info",
"severity": "info",
"area": "checkout",
"area": "checkout",
- "subject": "OpenVibe.Live",
- "detail": "local checkout c9af780 differs from origin/main e266060; scan reflects the checkout"
+ "subject": "OpenVibe.Network",
+ "detail": "local checkout 33156ef differs from origin/main 06e4a6b; scan reflects the checkout"
},
},
{
{
"severity": "info",
"severity": "info",
@@ -19841,8 +19841,8 @@
@@ -19841,8 +19841,8 @@
"outbound.internal-key": "28 of 61 call sites authenticate with the shared internal key",
"outbound.internal-key": "28 of 61 call sites authenticate with the shared internal key",
"ws.servers": "10 WebSocket server constructions",
"ws.servers": "10 WebSocket server constructions",
"tables.analytics-copies": "3 repos carry their own analytics_events",
"tables.analytics-copies": "3 repos carry their own analytics_events",
- "shared.pins": "4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0",
- "shared.drift": "2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)",
+ "shared.pins": "3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0",
+ "shared.drift": "3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)",
"ci.repos": "5 of 8 scanned repos have .github/workflows",
"ci.repos": "5 of 8 scanned repos have .github/workflows",
"deploy.drift": "5 service(s) not running origin/main",
"deploy.drift": "5 service(s) not running origin/main",
"tests.OpenVibe.Live": "58 test files",
"tests.OpenVibe.Live": "58 test files",
@@ -20322,11 +20322,11 @@
@@ -20322,11 +20322,11 @@
"metrics": [
"metrics": [
{
{
"key": "shared.pins",
"key": "shared.pins",
- "value": "4 repos pin a tagged openvibe-shared release (latest v1.0.0): Live v1.0.0, Network v1.0.0, Sites v1.0.0, Tools v1.0.0"
+ "value": "3 repos pin a tagged openvibe-shared release (latest v1.0.0): Network v1.0.0, Sites v1.0.0, Tools v1.0.0"
},
},
{
{
"key": "shared.drift",
"key": "shared.drift",
- "value": "2 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)"
+ "value": "3 manifests unpinned or behind: Community (file:./vendor/openvibe-shared), Live (file:./vendor/openvibe-shared), Media (file:./vendor/openvibe-shared)"
}
}
],
],
"verified": true
"verified": true
@@ -20586,6 +20586,19 @@
@@ -20586,6 +20586,19 @@
"status": "open",
"status": "open",
"check": "dead-dbs",
"check": "dead-dbs",
"checkResult": "live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db"
"checkResult": "live/data/backups/live-pre-643a2e6.db, live/data/hobo.db, live/data/openvibe.db"
+ },
+ {
+ "id": "H15",
+ "title": "Media objects with no good copy",
+ "source": "OpenVibe.Media reconcile-objects.js --verify, 2026-09-23",
+ "severity": "medium",
+ "constraint": "The first full verification of stored copies found 4 B2 copies whose size does not match the database and 2 missing local files: 6 objects have no verified good copy.",
+ "owner": "Media maintainers",
+ "wave": "W4 (repair) / W22 (DR drills)",
+ "mitigation": "Re-upload from any surviving source or mark the objects unrecoverable with the owner told; run reconcile --verify on a schedule and alert on new findings.",
+ "status": "open",
+ "evidence": "2026-09-23: reconcile --verify over 3,020 objects and 2,847 locations; remote 686 checked (682 present, 4 corrupt).",
+ "checkResult": null
}
}
],
],
"criteria": [
"criteria": [