{"id":"pst_01M3FRR5RP5QF0HCK59T1QPRP0","url":"https://openvibe.blog/@openvibe/patch-notes-tiering-for-native-v2-objects","blog":{"id":"blg_01M362MF0EDJ7QHQTRD8A3Q981","handle":"openvibe","title":"The OpenVibe blog","url":"https://openvibe.blog/"},"title":"Patch notes: Tiering for native v2 objects","summary":"What shipped on OpenVibe on 2026-09-26: 28 changes to OpenVibe.Live, OpenVibe.Network, OpenVibe.Media, OpenVibe.Codes, OpenVibe.Events, OpenVibe.Tools and 1 more.","body_markdown":"What shipped on OpenVibe on 2026-09-26: 28 changes to OpenVibe.Live, OpenVibe.Network, OpenVibe.Media, OpenVibe.Codes, OpenVibe.Events, OpenVibe.Tools and 1 more. Every line below is a commit message from the OpenVibers repositories, linked to the change itself.\n\n## Highlights\n\n- **OpenVibe.Media:** Tiering for native v2 objects (roadmap WS-G task 11): popular objects get a verified R2 copy that /o/:id plays from, behind a site-level activation gate that is off by default. Popularity (server/objects/popularity.js, ADR-021): GET /o/:id… ([`43990ec`](https://github.com/OpenVibers/OpenVibe.Media/commit/43990ec2f45866480b0d3a22d2aace4dab98ee0c))\n- **OpenVibe.Live:** A second RTMP slot's encoder no longer takes over the first slot's stream (roadmap D20 parity: per-stream control profiles). An RTMP publish attached to any live RTMP stream of the user that was waiting for an encoder, so with two slots on… ([`d565a2e`](https://github.com/OpenVibers/OpenVibe.Live/commit/d565a2e2d312b5d94f95407faa8328d4ee01de0e))\n\n## OpenVibe.Live\n\n[openvibe.live](https://openvibe.live) · [repository](https://github.com/OpenVibers/OpenVibe.Live)\n\n- N-1 fixtures re-recorded from 4479b66, the release now in production (npm run n-1:record). ([`2d84855`](https://github.com/OpenVibers/OpenVibe.Live/commit/2d848559b4a2d852e0eb2065d1d0f5fb2abce54b))\n- Live's bell is realtime too: the shell initialises OpenVibeNotifications itself (before the shared navbar, which then leaves it alone), so the navbar's notificationsRealtime (13525eb) never reached it. The shell's init now passes realtime… ([`c458b2e`](https://github.com/OpenVibers/OpenVibe.Live/commit/c458b2e7e067678a0b7032aebc1fb2f037aff2a0))\n- Channel pages show the owner's game progress (roadmap WS-M task 2, PF7): GET /api/streams/channel/:username/game reads the public fields of their games.progress.summary user module (level, achievements, playtime) from Network's public… ([`f9599c6`](https://github.com/OpenVibers/OpenVibe.Live/commit/f9599c631bd977fee05ddb99a0c8b3f3ce2ebd8b))\n- N-1 fixtures re-recorded from f9599c6, the release now in production (npm run n-1:record). ([`b15f0f7`](https://github.com/OpenVibers/OpenVibe.Live/commit/b15f0f7072f8fa40de8a0c8ec0c8be6edc9d68f2))\n- Live VODs extend toward the live edge again (roadmap D20 parity: VOD tail, finalisation, seek). /api/vods/:id/live-info said seekable: false for every recording, because it trusted only a 'seekable' field OpenVibe.Media's rows do not have… ([`688f178`](https://github.com/OpenVibers/OpenVibe.Live/commit/688f178d03c6a2b126d451a0b20478ff9392a131))\n- Purges and deletes stay consistent with replay (roadmap D20 parity: replay purge consistency). (1) The dashboard's chat purge, its preview and the log filter send ISO instants ('...T...Z') and chat_messages keeps SQLite's 'YYYY-MM-DD… ([`efe74a4`](https://github.com/OpenVibers/OpenVibe.Live/commit/efe74a40573cc2566e6dbb7b2805867ac24acf2d))\n- The broadcaster's Viewer preview opens the slot on air (roadmap D20 parity: viewer-style preview). openViewerPreview() put streamData.slug || streamId in the /@user/<slot> position, but streamData is the stream row: it has no slug, so the… ([`86693f9`](https://github.com/OpenVibers/OpenVibe.Live/commit/86693f94c6d1728091e741fdcd916d0734914da6))\n- The RTMP broadcaster's live preview shows again; live thumbnail cadence pinned (roadmap D20 parity: thumbnail cadence). The preview asked for /thumbnails/stream-<id>-live.jpg, which nothing served since live thumbnails became… ([`cb70d30`](https://github.com/OpenVibers/OpenVibe.Live/commit/cb70d3004b5ce4ef66ef00c782c472cbdcbe4b72))\n- Opt-in low-bitrate alert, and the disconnect alert for encoder streams (roadmap D20 parity: audible disconnect and low-bitrate alerts). The broadcaster's opt-in disconnect beep existed for browser broadcasts only: the encoder settings'… ([`5608a6c`](https://github.com/OpenVibers/OpenVibe.Live/commit/5608a6c1e92060f74c5f219b21b07d3c91638ac5))\n- A second RTMP slot's encoder no longer takes over the first slot's stream (roadmap D20 parity: per-stream control profiles). An RTMP publish attached to any live RTMP stream of the user that was waiting for an encoder, so with two slots on… ([`d565a2e`](https://github.com/OpenVibers/OpenVibe.Live/commit/d565a2e2d312b5d94f95407faa8328d4ee01de0e))\n- Chat-log views verified by test (roadmap D20 parity: chat-log UI). test/chat-log-ui.test.js runs the dashboard's own Chat Logs functions (loadDashChatLogs, dashPurgeChatRange) on a fake DOM against the real chat routes: a streamer sees… ([`78df125`](https://github.com/OpenVibers/OpenVibe.Live/commit/78df1250f285029aa0c687c4551f5fca366c2e80))\n- A screen-mode slot goes live from a phone with the camera (roadmap D20 parity: mobile broadcasting). Phone browsers have no getDisplayMedia, so a slot set to screen sharing could not go live from a phone at all: capture threw… ([`6212df7`](https://github.com/OpenVibers/OpenVibe.Live/commit/6212df7690a3c05a26e3a25d5dad758aa87e8276))\n- Follows, ADR-030 step 4 in Live. With FOLLOWS_AUTHORITY=network, both follow buttons record the change on Network first (PUT/DELETE /internal/follows/channel/<subject>, Live's service token, network.follows.write) and write Live's row only… ([`813f4ad`](https://github.com/OpenVibers/OpenVibe.Live/commit/813f4ad881d765d1a9a12b2d0f62967b98f41b46))\n- Creator analytics through Network (roadmap WS-E task 6; Contracts v0.68.0, pinned from 0.56.0). live.stream.ended carries the stream's totals (stats: peak and average viewers, unique chatters, messages, watch minutes; counts only)… ([`83ad224`](https://github.com/OpenVibers/OpenVibe.Live/commit/83ad224f32bae31281601a724d6ea80c9249eba1))\n\n## OpenVibe.Network\n\n[openvibe.network](https://openvibe.network) · [repository](https://github.com/OpenVibers/OpenVibe.Network)\n\n- Project usage (roadmap WS-N task 4; Contracts v0.63.0 common.usage-recorded@1, network.project-usage-result@1): the Events consumer (POST /internal/events) now also takes tools.usage.recorded and events.usage.recorded, the owning services'… ([`7e5112a`](https://github.com/OpenVibers/OpenVibe.Network/commit/7e5112a29c9f29e884bed28c3bc4802c4e9960b6))\n- Admin: a Lineage tab, the operator view of unresolved references (roadmap D20, remaining item 2). It lists what Live's canonical channel/owner resolver answered unresolved (conflict, source_unavailable, not_found, display_name_only), by… ([`1117f25`](https://github.com/OpenVibers/OpenVibe.Network/commit/1117f253f6d11906d58564d55b355bcdc16dc00a))\n- Wiki may ask VIP who reads a VIP space or page: principal wiki gets vip.resource.policy.evaluate (audience openvibe.vip), as Blog and Community have (roadmap WS-K task 8, Contracts 0.64.0). ([`2e3fdcc`](https://github.com/OpenVibers/OpenVibe.Network/commit/2e3fdcc0c55ed15fa359924f5d1aa8fdf2ec76a7))\n- The follow graph on Network (roadmap WS-E task 4, ADR-030 steps 1-3; Contracts v0.65.0, pinned from 0.63.0). user_follows is keyed by subjects (a Live channel is its owner's subject), with active, notify flags and a per-pair revision.… ([`bb18d98`](https://github.com/OpenVibers/OpenVibe.Network/commit/bb18d98a46b962b4fd5ebf2b1edf1c2996cc570a))\n- Incidents and maintenance on /status (roadmap WS-N task 12; Contracts v0.66.0, pinned from 0.65.0). server/status/incidents.js stores incidents (investigating, identified, monitoring, resolved) and maintenance windows (scheduled… ([`1a22cd0`](https://github.com/OpenVibers/OpenVibe.Network/commit/1a22cd0834eadfdb0744e60bb0b3f3ca5be52562))\n- Follows, ADR-030 step 4 on Network (Contracts v0.67.0, pinned from 0.66.0). Products record follows on a person's behalf at PUT/DELETE /internal/follows/:type/:target (network.follows.write, service token only… ([`3928b03`](https://github.com/OpenVibers/OpenVibe.Network/commit/3928b03dd372c5cdc6f27cb899d0e65a8de1138a))\n- Creator analytics from events (roadmap WS-E task 6; Contracts v0.68.0, pinned from 0.67.0). Network consumes live.stream.ended (added to its topics) into creator_streams: one row per stream, replaced on redelivery, counts only (no viewer… ([`45f6c4c`](https://github.com/OpenVibers/OpenVibe.Network/commit/45f6c4ce2bbff69ee8eedaa41879ff9bd7507765))\n- scripts/creator-analytics-backfill.js (roadmap WS-E task 6): Live's ended streams of the last 400 days into creator_streams, so Live's analytics can switch to Network without losing history. Dry run by default; --apply only with a backup… ([`aaf627c`](https://github.com/OpenVibers/OpenVibe.Network/commit/aaf627c61bbc78cfafe7e95b1008112ba037c3dd))\n\n## OpenVibe.Media\n\n[openvibe.media](https://openvibe.media) · [repository](https://github.com/OpenVibers/OpenVibe.Media)\n\n- N-1 tests (roadmap WS-P task 11): the previous release's clients against this server, and its SQL against this schema. test/n-1.test.js boots this checkout as a real server/index.js in the drill sandbox (MEDIA_DRILL: loopback, no outbound… ([`44bc3f2`](https://github.com/OpenVibers/OpenVibe.Media/commit/44bc3f2529065ff2ffe25d8b8ddd2db326c5823f))\n- Tiering for native v2 objects (roadmap WS-G task 11): popular objects get a verified R2 copy that /o/:id plays from, behind a site-level activation gate that is off by default. Popularity (server/objects/popularity.js, ADR-021): GET /o/:id… ([`43990ec`](https://github.com/OpenVibers/OpenVibe.Media/commit/43990ec2f45866480b0d3a22d2aace4dab98ee0c))\n\n## OpenVibe.Codes\n\n[openvibe.codes](https://openvibe.codes) · [repository](https://github.com/OpenVibers/OpenVibe.Codes)\n\n- Per-project usage page (roadmap WS-N task 4): /projects/:project/usage?days=7|30|90&env=all|production|sandbox, for the project's owner, admins and staff, renders OpenVibe.Network's GET /api/v1/projects/:project/usage… ([`253c29d`](https://github.com/OpenVibers/OpenVibe.Codes/commit/253c29d57b7bb656b967ec1bf90dca2bb2d0619c))\n\n## OpenVibe.Events\n\n[events.openvibe.network](https://events.openvibe.network) · [repository](https://github.com/OpenVibers/OpenVibe.Events)\n\n- Project usage rollups (roadmap WS-N task 4; Contracts v0.63.0 events.usage.recorded, common.usage-recorded@1): each developer project's use is counted per environment and UTC hour in the transaction that does the work (server/usage.js… ([`bb78877`](https://github.com/OpenVibers/OpenVibe.Events/commit/bb7887768136f0e5402db33203092ace9efb422d))\n\n## OpenVibe.Tools\n\n[openvibe.tools](https://openvibe.tools) · [repository](https://github.com/OpenVibers/OpenVibe.Tools)\n\n- Project usage rollups (roadmap WS-N task 4; Contracts v0.63.0 tools.usage.recorded, common.usage-recorded@1): a developer app's job (it carries a project) that ends is counted in the transaction that records its end… ([`f15b263`](https://github.com/OpenVibers/OpenVibe.Tools/commit/f15b263920bc7a10c1076cbf93bf4bce038804fa))\n\n## OpenVibe.Wiki\n\n[openvibe.wiki](https://openvibe.wiki) · [repository](https://github.com/OpenVibers/OpenVibe.Wiki)\n\n- VIP spaces and pages (roadmap WS-K task 8; Contracts 0.64.0, pinned from 0.49.0). A new visibility, vip: read by the space's roles and by the viewers OpenVibe.VIP admits as members of the space owner (vip.resource.policy.evaluate; resource… ([`c76d051`](https://github.com/OpenVibers/OpenVibe.Wiki/commit/c76d051481f07f1c762df57ce9e287f8c32665e7))\n\n---\n\nPatch notes are put together automatically when enough changes have shipped, or when a large feature lands. See every site's own updates page for the live list.","revision":1,"state":"published","visibility":"public","published_at":"2026-09-26T21:08:15.256Z","revised_at":"2026-09-26T21:08:15.255Z","author":{"subject":"usr_01KKT9AC60KM7CRTB3WN1Z8P56","name":"goosely","username":"goosely"},"authorship":{"mode":"imported","workflow":null,"reviewed":false,"disclosure":{"mode":"imported","short":"Imported","long":"Imported from Commit messages from the OpenVibers repositories on GitHub; originally by OpenVibers."}},"tags":["patch-notes","live","network","media","codes","events","tools","wiki"],"categories":[],"series":{"title":"Patch notes","url":"https://openvibe.blog/@openvibe/series/patch-notes","position":null},"media":[],"citations":[],"indexability":{"indexable":true,"robots":"index, follow","reasons":[]}}