openvibers/openvibe.host Commits
Docs: ovhost deploys 20 services and runs the backups and drills (README said no deploy used it); cutover runbook gains the DNS steps (lower TTL a day ahead, record the old records, 30-minute watch, decommission after twice the old TTL) and port 1936 is recorded as open; register C-81: placeholder labels now come from facts
Changes
@@@ -2,7 +2,7 @@> The network's deployment/control plane first; then isolated hosting for community sites, bots and mods.--**Status:** alpha. Stage A (operator plane) is a CLI, `ovhost`, tested against a fake host. It is installed on the production host (2026-09-23, `/usr/local/bin/ovhost`, inventory `/etc/openvibe/host.json`) and used read-only (`status`, `validate`); no service's deploy has moved to it yet. Stage B (tenant static hosting) is a service, written and tested; it runs on the host on loopback `:4910` (2026-09-23 audit) and is **not launched**: `openvibe.host` is still the Sites placeholder and `*.openvibe.host` answers 404. The launch is ready to run: [docs/launch.md](docs/launch.md) (steps, verification, rollback and the launch-rule evidence) and [docs/threat-review.md](docs/threat-review.md). Stage C (sandboxed user code) is **not started**.++**Status:** alpha. Stage A (operator plane) is a CLI, `ovhost`, tested against a fake host. It is installed on the production host (2026-09-23, `/usr/local/bin/ovhost`, inventory `/etc/openvibe/host.json`) and it deploys 20 services (`ovhost deploy <svc>`: Network, Events, Chat, Billing, Tips, VIP, AI, Search, Sources, Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Codes, Host, Media, Community; 70+ releases since 2026-09-23, with automatic rollback on a failed readiness check) and runs the nightly backups and the restore drills of 19 services. Live, Tools, Sites, Games and OpenRe still deploy with their own scripts. Stage B (tenant static hosting) is a service, written and tested; it runs on the host on loopback `:4910` (2026-09-23 audit) and is **not launched**: `openvibe.host` is still the Sites placeholder and `*.openvibe.host` answers 404. The launch is ready to run: [docs/launch.md](docs/launch.md) (steps, verification, rollback and the launch-rule evidence) and [docs/threat-review.md](docs/threat-review.md). Stage C (sandboxed user code) is **not started**.**Domain:** `openvibe.host` (dashboard and API) and `*.openvibe.host` (tenant sites). The domain keeps its placeholder page on [OpenVibe.Sites](https://github.com/OpenVibers/OpenVibe.Sites) until Stage B is deployed and launched (see [Launch rule](#launch-rule)).**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §15.3 and §15.17; roadmap Wave 21.**License:** AGPL-3.0 (same as every OpenVibe service).@@@ -131,7 +131,7 @@ The dates below assume each caller moves by **2026-10-09**. The key paths then g| # | What | Where | Owner | Removal condition | Target | Rollback lever until then ||---|---|---|---|---|---|---|| C-80 | **`openvibe-shared/analytics.js`** (`AnalyticsTracker`) stores raw IP, `user_id`, city and full UA. **No deployed service uses it.** Live (`server/analytics/`, `0e07aec`), Network (`server/analytics/`) and Tools (`apps/_shared/analytics`, `533c9a3`) run their own ADR-021 trackers. No other repo requires it. The one remaining `require` is the stale local checkout `~/OpenVibers/OpenVibe.Live` (`e266060`, behind `origin/main`). It is still exported (`package.json:10`, `index.js:8,40-44`) with no deprecation marker. Stale docs: Shared `docs/migration-plan.md:29,252,493`; Live `SECURITY_AUDIT.md:98`. **RETIRED 2026-09-23**: the ADR-021 module is `openvibe-shared/analytics` v1.4.0 (with GPC/DNT); Live `c893c6c`, Tools `5d1b423` and Network `9bbd90f` use it, their local copies are deleted, verified on production (no ip/user_id/city; DNT requests not recorded). | OpenVibe.Shared `analytics.js` | Shared | **No condition documented** (ADR-021 does not mention it). *Proposed*: mark it deprecated in the next Shared minor, then remove it in the next major, since removing an export is breaking (ADR-008). | Deprecate 2026-10-09; remove in Shared v2.0.0, 2026-11-06 | Pin the previous Shared tag. |--| C-81 | **OpenVibe.Sites placeholders**. There are 16, all `"stage": "placeholder"`: openvibe.chat, .news, .reviews, .tips, .vip, .trade, .host, .deals, .coupons, openre.stream, and auth., api., admin., themes., realtime. and ai.openvibe.network. The page says "coming soon · this page is a placeholder, nothing here is live yet". None claims to be a working product. **Two defects:** repos outside `EXISTING_REPOS` are labelled "(charter only, no code yet)", which is false for Tips, VIP, News, Reviews, Trade, Deals, Coupons and Host; and **realtime.openvibe.network advertises a product that ADR-005 closed**. | Sites `sites.json`, `build.js:22,157-161,283`, `deploy/nginx/*.conf` | Sites (each service owns its launch) | *documented*: each entry is "Removed from sites.json in the same release that the real service takes over this domain" (`build.js:283`, `README.md:20-21`, test `test/build.test.js:39-43`). *Proposed*: fix the "charter only" label from the repo's STATUS, and remove the realtime placeholder now. | Realtime and label: 2026-09-30; the rest: at each launch | Re-add the entry. |++| C-81 | **OpenVibe.Sites placeholders**. There are 16, all `"stage": "placeholder"`: openvibe.chat, .news, .reviews, .tips, .vip, .trade, .host, .deals, .coupons, openre.stream, and auth., api., admin., themes., realtime. and ai.openvibe.network. The page says "coming soon · this page is a placeholder, nothing here is live yet". None claims to be a working product. **Two defects:** repos outside `EXISTING_REPOS` are labelled "(charter only, no code yet)", which is false for Tips, VIP, News, Reviews, Trade, Deals, Coupons and Host; and **realtime.openvibe.network advertises a product that ADR-005 closed**. | Sites `sites.json`, `build.js:22,157-161,283`, `deploy/nginx/*.conf` | Sites (each service owns its launch) | *partly done 2026-09-24*: every placeholder's label comes from the product's STATUS.json/registry facts (Sites `facts.json`, `8be8071`), so a running product is "in development" with what its launch waits for, never "charter only"; realtime is a closed notice (ADR-005); openvibe.host describes Host as it is. Retire each placeholder when its product launches | Realtime and label: 2026-09-30; the rest: at each launch | Re-add the entry. || C-82 | **OpenVibe.Realtime**, closed by ADR-005: realtime runs inside Events as SSE `/realtime/stream`. `STATUS.json` says `stage: closed`. Leftovers: the README still says "Decision pending" (`:12,51-53`); the GitHub repo is not archived; Contracts `manifests/services/realtime.json:8` says `"status": "placeholder"`; Events `README.md:6` says "until ADR-005 decides"; and the Sites placeholder (C-81). | OpenVibe.Realtime; Contracts; Sites; Events | Contracts (manifest), Sites, Events | *proposed*: fix the README, mark the manifest `closed` (a Contracts release), remove the Sites placeholder, archive the repo. | 2026-09-30 | ADR-005: revisit only on measured load. || C-83 | **Live `/internal/media-webhook`** next to the Events consumer `/internal/media-events` (media.vod.*, media.clip.*, media.storage.*). `MEDIA_EVENTS_AUTHORITY=webhook` \| `both` \| `events`; each outcome is applied once (inbox consumer `live-media-outcomes`, key object + event id; Media webhooks carry `event_id` since `cbf8410`). **`both` since 2026-09-23 20:00 UTC** (3 subscriptions created). | Live `server/media-proxy/webhook.js`, `outcomes.js`, `media-events.js`; Media `server/webhooks.js` | Live + Media | *documented* (Live `docs/architecture.md` "Media outcomes over Events"): `events` has run clean (every VOD/clip since the switch has its `vod_ai_state`/`clip_ai_state` row and a receipt, no DLQ entries for Live's subscriptions); then clear Live's `webhook_url` in Media `apps`, wait a release, delete the route, `MEDIA_WEBHOOK_SECRET` and the `webhook`/`both` modes. | `events` 2026-10-01; removal 2026-10-14 | `MEDIA_EVENTS_AUTHORITY=webhook`; `subscribe-media-events.js --disable` || C-84 | **Live deploy notice over the Chat bridge** (`chat-remote.js` `deployNotice`) next to the `live.release.deployed` event (Live `e73a92d`). | Live `server/chat/deploy-notice.js`, `server/chat/chat-remote.js` | Chat + Live | *done 2026-09-23*: Chat subscribes to `live.release.deployed` (Chat `ed90461`, table `deploy_releases` keyed by head) and folds by `subject.id`; the 22:14 UTC deploy produced one card via both paths (`duplicate:release`), and since Live `5324f40` (22:18 UTC deploy: `first_via = events`, folded) the bridge hop runs only while Live's Events publishing is off | 2026-10-14 | Keep the bridge call |@@@ -29,7 +29,7 @@ State markers:| C | AI → OpenVibe.AI (Wave 13) | **DONE** 2026-09-23 ~15:40 UTC (`AI_SERVICE=remote`) | AI [`docs/migration.md`](https://github.com/OpenVibers/OpenVibe.AI/blob/main/docs/migration.md) | Unset `AI_SERVICE`, restart Live || D | Events delivery signature v2 | **IN PROGRESS**: Events sends v2; consumer deploys unknown; v1 still sent | Events [`docs/replay-window-rollout.md`](https://github.com/OpenVibers/OpenVibe.Events/blob/main/docs/replay-window-rollout.md) | The consumer redeploys its previous release; replay the DLQ || E | Money → OpenVibe.Billing | **BLOCKED (owner)**: PowerChat dashboard. Billing runs in shadow. | Billing [`docs/live-cutover.md`](https://github.com/OpenVibers/OpenVibe.Billing/blob/main/docs/live-cutover.md) | Depends on the step reached. After step 9 there is **no tool** |--| F | RTMP ingest → OpenRe.Stream | **BLOCKED (owner)**: port 1936 at the provider edge. DNS `ingest.openre.stream` is done and OpenRe is deployed. | OpenRe [`docs/cutover.md`](https://github.com/OpenVibers/OpenRe.Stream/blob/main/docs/cutover.md) (steps, checks and rollback; `scripts/cutover-preflight.js`) | Per slot `{"authority":"live"}` + `set-definition-state.js --state disabled`. All slots: unset `OPENRE_URL` |++| F | RTMP ingest → OpenRe.Stream | **BLOCKED (owner)**: broadcaster windows and the per-slot rehearsal. DNS `ingest.openre.stream` is done, port 1936 is open (2026-09-23) and OpenRe is deployed. | OpenRe [`docs/cutover.md`](https://github.com/OpenVibers/OpenRe.Stream/blob/main/docs/cutover.md) (steps, checks and rollback; `scripts/cutover-preflight.js`) | Per slot `{"authority":"live"}` + `set-definition-state.js --state disabled`. All slots: unset `OPENRE_URL` || G | Retire the shims | **NOT STARTED**. Dated in [compatibility-register.md](compatibility-register.md) | Network [`docs/retirement.md`](https://github.com/OpenVibers/OpenVibe.Network/blob/main/docs/retirement.md) | per entry |The remaining order is D → E → F → G.@@@ -55,7 +55,12 @@ These actions need the owner's accounts or physical presence. Nothing in this ru**DNS only (grey cloud)**. RTMP cannot go through Cloudflare's proxy (OpenRe `README.md:145`,`deploy/nginx/openre.stream.conf:15-17`).3. **Port 1936/tcp, for step F.** Open it in the host firewall **and** at the provider edge (OpenRe-- `README.md:145,160`).++ `README.md:145,160`). *Done 2026-09-23: 1936 answers from outside since 19:24 UTC.*++3a. **DNS changes in a cutover (any step that moves a hostname).** A day before: lower the record's TTL to 60 s++ and write down the current records (`dig +noall +answer <name> A AAAA CNAME` into the step's notes). At the++ switch: change the record, then watch the new target for 30 minutes (readiness, error rate, the step's own++ checks) before calling the step done. Keep the old target running until the old TTL has passed twice over;++ only then decommission it, and put the TTL back.4. **Broadcaster windows, for step F.** For each slot, agree a maintenance window with its broadcaster.The slot is offline, and the broadcaster regenerates the key and pastes the new server into OBS(ADR-009).@@@ -308,7 +313,7 @@ PowerChat delivery lands in exactly one ledger.Read the full list before choosing the day. VIP checkout stays closed until this cutover.--## F. RTMP ingest → OpenRe.Stream: BLOCKED on the owner (DNS, port 1936, broadcaster windows)++## F. RTMP ingest → OpenRe.Stream: BLOCKED on the owner (rehearsal and broadcaster windows; DNS and port 1936 are done)OpenRe is deployed. The API is `openre-api` on 127.0.0.1:4500. The other units are`openre-session-coordinator`, `openre-rtmp-ingest@<sha>` and `openre-restream-worker@<sha>`. The database
@@ -2,7 +2,7 @@
@@ -2,7 +2,7 @@
> The network's deployment/control plane first; then isolated hosting for community sites, bots and mods.
> The network's deployment/control plane first; then isolated hosting for community sites, bots and mods.
-**Status:** alpha. Stage A (operator plane) is a CLI, `ovhost`, tested against a fake host. It is installed on the production host (2026-09-23, `/usr/local/bin/ovhost`, inventory `/etc/openvibe/host.json`) and used read-only (`status`, `validate`); no service's deploy has moved to it yet. Stage B (tenant static hosting) is a service, written and tested; it runs on the host on loopback `:4910` (2026-09-23 audit) and is **not launched**: `openvibe.host` is still the Sites placeholder and `*.openvibe.host` answers 404. The launch is ready to run: [docs/launch.md](docs/launch.md) (steps, verification, rollback and the launch-rule evidence) and [docs/threat-review.md](docs/threat-review.md). Stage C (sandboxed user code) is **not started**.
+**Status:** alpha. Stage A (operator plane) is a CLI, `ovhost`, tested against a fake host. It is installed on the production host (2026-09-23, `/usr/local/bin/ovhost`, inventory `/etc/openvibe/host.json`) and it deploys 20 services (`ovhost deploy <svc>`: Network, Events, Chat, Billing, Tips, VIP, AI, Search, Sources, Wiki, Blog, News, Reviews, Deals, Coupons, Trade, Codes, Host, Media, Community; 70+ releases since 2026-09-23, with automatic rollback on a failed readiness check) and runs the nightly backups and the restore drills of 19 services. Live, Tools, Sites, Games and OpenRe still deploy with their own scripts. Stage B (tenant static hosting) is a service, written and tested; it runs on the host on loopback `:4910` (2026-09-23 audit) and is **not launched**: `openvibe.host` is still the Sites placeholder and `*.openvibe.host` answers 404. The launch is ready to run: [docs/launch.md](docs/launch.md) (steps, verification, rollback and the launch-rule evidence) and [docs/threat-review.md](docs/threat-review.md). Stage C (sandboxed user code) is **not started**.
**Domain:** `openvibe.host` (dashboard and API) and `*.openvibe.host` (tenant sites). The domain keeps its placeholder page on [OpenVibe.Sites](https://github.com/OpenVibers/OpenVibe.Sites) until Stage B is deployed and launched (see [Launch rule](#launch-rule)).
**Domain:** `openvibe.host` (dashboard and API) and `*.openvibe.host` (tenant sites). The domain keeps its placeholder page on [OpenVibe.Sites](https://github.com/OpenVibers/OpenVibe.Sites) until Stage B is deployed and launched (see [Launch rule](#launch-rule)).
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §15.3 and §15.17; roadmap Wave 21.
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §15.3 and §15.17; roadmap Wave 21.
**License:** AGPL-3.0 (same as every OpenVibe service).
**License:** AGPL-3.0 (same as every OpenVibe service).
@@ -131,7 +131,7 @@ The dates below assume each caller moves by **2026-10-09**. The key paths then g
@@ -131,7 +131,7 @@ The dates below assume each caller moves by **2026-10-09**. The key paths then g
| # | What | Where | Owner | Removal condition | Target | Rollback lever until then |
| # | What | Where | Owner | Removal condition | Target | Rollback lever until then |
|---|---|---|---|---|---|---|
|---|---|---|---|---|---|---|
| C-80 | **`openvibe-shared/analytics.js`** (`AnalyticsTracker`) stores raw IP, `user_id`, city and full UA. **No deployed service uses it.** Live (`server/analytics/`, `0e07aec`), Network (`server/analytics/`) and Tools (`apps/_shared/analytics`, `533c9a3`) run their own ADR-021 trackers. No other repo requires it. The one remaining `require` is the stale local checkout `~/OpenVibers/OpenVibe.Live` (`e266060`, behind `origin/main`). It is still exported (`package.json:10`, `index.js:8,40-44`) with no deprecation marker. Stale docs: Shared `docs/migration-plan.md:29,252,493`; Live `SECURITY_AUDIT.md:98`. **RETIRED 2026-09-23**: the ADR-021 module is `openvibe-shared/analytics` v1.4.0 (with GPC/DNT); Live `c893c6c`, Tools `5d1b423` and Network `9bbd90f` use it, their local copies are deleted, verified on production (no ip/user_id/city; DNT requests not recorded). | OpenVibe.Shared `analytics.js` | Shared | **No condition documented** (ADR-021 does not mention it). *Proposed*: mark it deprecated in the next Shared minor, then remove it in the next major, since removing an export is breaking (ADR-008). | Deprecate 2026-10-09; remove in Shared v2.0.0, 2026-11-06 | Pin the previous Shared tag. |
| C-80 | **`openvibe-shared/analytics.js`** (`AnalyticsTracker`) stores raw IP, `user_id`, city and full UA. **No deployed service uses it.** Live (`server/analytics/`, `0e07aec`), Network (`server/analytics/`) and Tools (`apps/_shared/analytics`, `533c9a3`) run their own ADR-021 trackers. No other repo requires it. The one remaining `require` is the stale local checkout `~/OpenVibers/OpenVibe.Live` (`e266060`, behind `origin/main`). It is still exported (`package.json:10`, `index.js:8,40-44`) with no deprecation marker. Stale docs: Shared `docs/migration-plan.md:29,252,493`; Live `SECURITY_AUDIT.md:98`. **RETIRED 2026-09-23**: the ADR-021 module is `openvibe-shared/analytics` v1.4.0 (with GPC/DNT); Live `c893c6c`, Tools `5d1b423` and Network `9bbd90f` use it, their local copies are deleted, verified on production (no ip/user_id/city; DNT requests not recorded). | OpenVibe.Shared `analytics.js` | Shared | **No condition documented** (ADR-021 does not mention it). *Proposed*: mark it deprecated in the next Shared minor, then remove it in the next major, since removing an export is breaking (ADR-008). | Deprecate 2026-10-09; remove in Shared v2.0.0, 2026-11-06 | Pin the previous Shared tag. |
-| C-81 | **OpenVibe.Sites placeholders**. There are 16, all `"stage": "placeholder"`: openvibe.chat, .news, .reviews, .tips, .vip, .trade, .host, .deals, .coupons, openre.stream, and auth., api., admin., themes., realtime. and ai.openvibe.network. The page says "coming soon · this page is a placeholder, nothing here is live yet". None claims to be a working product. **Two defects:** repos outside `EXISTING_REPOS` are labelled "(charter only, no code yet)", which is false for Tips, VIP, News, Reviews, Trade, Deals, Coupons and Host; and **realtime.openvibe.network advertises a product that ADR-005 closed**. | Sites `sites.json`, `build.js:22,157-161,283`, `deploy/nginx/*.conf` | Sites (each service owns its launch) | *documented*: each entry is "Removed from sites.json in the same release that the real service takes over this domain" (`build.js:283`, `README.md:20-21`, test `test/build.test.js:39-43`). *Proposed*: fix the "charter only" label from the repo's STATUS, and remove the realtime placeholder now. | Realtime and label: 2026-09-30; the rest: at each launch | Re-add the entry. |
+| C-81 | **OpenVibe.Sites placeholders**. There are 16, all `"stage": "placeholder"`: openvibe.chat, .news, .reviews, .tips, .vip, .trade, .host, .deals, .coupons, openre.stream, and auth., api., admin., themes., realtime. and ai.openvibe.network. The page says "coming soon · this page is a placeholder, nothing here is live yet". None claims to be a working product. **Two defects:** repos outside `EXISTING_REPOS` are labelled "(charter only, no code yet)", which is false for Tips, VIP, News, Reviews, Trade, Deals, Coupons and Host; and **realtime.openvibe.network advertises a product that ADR-005 closed**. | Sites `sites.json`, `build.js:22,157-161,283`, `deploy/nginx/*.conf` | Sites (each service owns its launch) | *partly done 2026-09-24*: every placeholder's label comes from the product's STATUS.json/registry facts (Sites `facts.json`, `8be8071`), so a running product is "in development" with what its launch waits for, never "charter only"; realtime is a closed notice (ADR-005); openvibe.host describes Host as it is. Retire each placeholder when its product launches | Realtime and label: 2026-09-30; the rest: at each launch | Re-add the entry. |
| C-82 | **OpenVibe.Realtime**, closed by ADR-005: realtime runs inside Events as SSE `/realtime/stream`. `STATUS.json` says `stage: closed`. Leftovers: the README still says "Decision pending" (`:12,51-53`); the GitHub repo is not archived; Contracts `manifests/services/realtime.json:8` says `"status": "placeholder"`; Events `README.md:6` says "until ADR-005 decides"; and the Sites placeholder (C-81). | OpenVibe.Realtime; Contracts; Sites; Events | Contracts (manifest), Sites, Events | *proposed*: fix the README, mark the manifest `closed` (a Contracts release), remove the Sites placeholder, archive the repo. | 2026-09-30 | ADR-005: revisit only on measured load. |
| C-82 | **OpenVibe.Realtime**, closed by ADR-005: realtime runs inside Events as SSE `/realtime/stream`. `STATUS.json` says `stage: closed`. Leftovers: the README still says "Decision pending" (`:12,51-53`); the GitHub repo is not archived; Contracts `manifests/services/realtime.json:8` says `"status": "placeholder"`; Events `README.md:6` says "until ADR-005 decides"; and the Sites placeholder (C-81). | OpenVibe.Realtime; Contracts; Sites; Events | Contracts (manifest), Sites, Events | *proposed*: fix the README, mark the manifest `closed` (a Contracts release), remove the Sites placeholder, archive the repo. | 2026-09-30 | ADR-005: revisit only on measured load. |
| C-83 | **Live `/internal/media-webhook`** next to the Events consumer `/internal/media-events` (media.vod.*, media.clip.*, media.storage.*). `MEDIA_EVENTS_AUTHORITY=webhook` \| `both` \| `events`; each outcome is applied once (inbox consumer `live-media-outcomes`, key object + event id; Media webhooks carry `event_id` since `cbf8410`). **`both` since 2026-09-23 20:00 UTC** (3 subscriptions created). | Live `server/media-proxy/webhook.js`, `outcomes.js`, `media-events.js`; Media `server/webhooks.js` | Live + Media | *documented* (Live `docs/architecture.md` "Media outcomes over Events"): `events` has run clean (every VOD/clip since the switch has its `vod_ai_state`/`clip_ai_state` row and a receipt, no DLQ entries for Live's subscriptions); then clear Live's `webhook_url` in Media `apps`, wait a release, delete the route, `MEDIA_WEBHOOK_SECRET` and the `webhook`/`both` modes. | `events` 2026-10-01; removal 2026-10-14 | `MEDIA_EVENTS_AUTHORITY=webhook`; `subscribe-media-events.js --disable` |
| C-83 | **Live `/internal/media-webhook`** next to the Events consumer `/internal/media-events` (media.vod.*, media.clip.*, media.storage.*). `MEDIA_EVENTS_AUTHORITY=webhook` \| `both` \| `events`; each outcome is applied once (inbox consumer `live-media-outcomes`, key object + event id; Media webhooks carry `event_id` since `cbf8410`). **`both` since 2026-09-23 20:00 UTC** (3 subscriptions created). | Live `server/media-proxy/webhook.js`, `outcomes.js`, `media-events.js`; Media `server/webhooks.js` | Live + Media | *documented* (Live `docs/architecture.md` "Media outcomes over Events"): `events` has run clean (every VOD/clip since the switch has its `vod_ai_state`/`clip_ai_state` row and a receipt, no DLQ entries for Live's subscriptions); then clear Live's `webhook_url` in Media `apps`, wait a release, delete the route, `MEDIA_WEBHOOK_SECRET` and the `webhook`/`both` modes. | `events` 2026-10-01; removal 2026-10-14 | `MEDIA_EVENTS_AUTHORITY=webhook`; `subscribe-media-events.js --disable` |
| C-84 | **Live deploy notice over the Chat bridge** (`chat-remote.js` `deployNotice`) next to the `live.release.deployed` event (Live `e73a92d`). | Live `server/chat/deploy-notice.js`, `server/chat/chat-remote.js` | Chat + Live | *done 2026-09-23*: Chat subscribes to `live.release.deployed` (Chat `ed90461`, table `deploy_releases` keyed by head) and folds by `subject.id`; the 22:14 UTC deploy produced one card via both paths (`duplicate:release`), and since Live `5324f40` (22:18 UTC deploy: `first_via = events`, folded) the bridge hop runs only while Live's Events publishing is off | 2026-10-14 | Keep the bridge call |
| C-84 | **Live deploy notice over the Chat bridge** (`chat-remote.js` `deployNotice`) next to the `live.release.deployed` event (Live `e73a92d`). | Live `server/chat/deploy-notice.js`, `server/chat/chat-remote.js` | Chat + Live | *done 2026-09-23*: Chat subscribes to `live.release.deployed` (Chat `ed90461`, table `deploy_releases` keyed by head) and folds by `subject.id`; the 22:14 UTC deploy produced one card via both paths (`duplicate:release`), and since Live `5324f40` (22:18 UTC deploy: `first_via = events`, folded) the bridge hop runs only while Live's Events publishing is off | 2026-10-14 | Keep the bridge call |
@@ -29,7 +29,7 @@ State markers:
@@ -29,7 +29,7 @@ State markers:
| C | AI → OpenVibe.AI (Wave 13) | **DONE** 2026-09-23 ~15:40 UTC (`AI_SERVICE=remote`) | AI [`docs/migration.md`](https://github.com/OpenVibers/OpenVibe.AI/blob/main/docs/migration.md) | Unset `AI_SERVICE`, restart Live |
| C | AI → OpenVibe.AI (Wave 13) | **DONE** 2026-09-23 ~15:40 UTC (`AI_SERVICE=remote`) | AI [`docs/migration.md`](https://github.com/OpenVibers/OpenVibe.AI/blob/main/docs/migration.md) | Unset `AI_SERVICE`, restart Live |
| D | Events delivery signature v2 | **IN PROGRESS**: Events sends v2; consumer deploys unknown; v1 still sent | Events [`docs/replay-window-rollout.md`](https://github.com/OpenVibers/OpenVibe.Events/blob/main/docs/replay-window-rollout.md) | The consumer redeploys its previous release; replay the DLQ |
| D | Events delivery signature v2 | **IN PROGRESS**: Events sends v2; consumer deploys unknown; v1 still sent | Events [`docs/replay-window-rollout.md`](https://github.com/OpenVibers/OpenVibe.Events/blob/main/docs/replay-window-rollout.md) | The consumer redeploys its previous release; replay the DLQ |
| E | Money → OpenVibe.Billing | **BLOCKED (owner)**: PowerChat dashboard. Billing runs in shadow. | Billing [`docs/live-cutover.md`](https://github.com/OpenVibers/OpenVibe.Billing/blob/main/docs/live-cutover.md) | Depends on the step reached. After step 9 there is **no tool** |
| E | Money → OpenVibe.Billing | **BLOCKED (owner)**: PowerChat dashboard. Billing runs in shadow. | Billing [`docs/live-cutover.md`](https://github.com/OpenVibers/OpenVibe.Billing/blob/main/docs/live-cutover.md) | Depends on the step reached. After step 9 there is **no tool** |
-| F | RTMP ingest → OpenRe.Stream | **BLOCKED (owner)**: port 1936 at the provider edge. DNS `ingest.openre.stream` is done and OpenRe is deployed. | OpenRe [`docs/cutover.md`](https://github.com/OpenVibers/OpenRe.Stream/blob/main/docs/cutover.md) (steps, checks and rollback; `scripts/cutover-preflight.js`) | Per slot `{"authority":"live"}` + `set-definition-state.js --state disabled`. All slots: unset `OPENRE_URL` |
+| F | RTMP ingest → OpenRe.Stream | **BLOCKED (owner)**: broadcaster windows and the per-slot rehearsal. DNS `ingest.openre.stream` is done, port 1936 is open (2026-09-23) and OpenRe is deployed. | OpenRe [`docs/cutover.md`](https://github.com/OpenVibers/OpenRe.Stream/blob/main/docs/cutover.md) (steps, checks and rollback; `scripts/cutover-preflight.js`) | Per slot `{"authority":"live"}` + `set-definition-state.js --state disabled`. All slots: unset `OPENRE_URL` |
| G | Retire the shims | **NOT STARTED**. Dated in [compatibility-register.md](compatibility-register.md) | Network [`docs/retirement.md`](https://github.com/OpenVibers/OpenVibe.Network/blob/main/docs/retirement.md) | per entry |
| G | Retire the shims | **NOT STARTED**. Dated in [compatibility-register.md](compatibility-register.md) | Network [`docs/retirement.md`](https://github.com/OpenVibers/OpenVibe.Network/blob/main/docs/retirement.md) | per entry |
The remaining order is D → E → F → G.
The remaining order is D → E → F → G.
@@ -55,7 +55,12 @@ These actions need the owner's accounts or physical presence. Nothing in this ru
@@ -55,7 +55,12 @@ These actions need the owner's accounts or physical presence. Nothing in this ru
**DNS only (grey cloud)**. RTMP cannot go through Cloudflare's proxy (OpenRe `README.md:145`,
**DNS only (grey cloud)**. RTMP cannot go through Cloudflare's proxy (OpenRe `README.md:145`,
`deploy/nginx/openre.stream.conf:15-17`).
`deploy/nginx/openre.stream.conf:15-17`).
3. **Port 1936/tcp, for step F.** Open it in the host firewall **and** at the provider edge (OpenRe
3. **Port 1936/tcp, for step F.** Open it in the host firewall **and** at the provider edge (OpenRe
- `README.md:145,160`).
+ `README.md:145,160`). *Done 2026-09-23: 1936 answers from outside since 19:24 UTC.*
+3a. **DNS changes in a cutover (any step that moves a hostname).** A day before: lower the record's TTL to 60 s
+ and write down the current records (`dig +noall +answer <name> A AAAA CNAME` into the step's notes). At the
+ switch: change the record, then watch the new target for 30 minutes (readiness, error rate, the step's own
+ checks) before calling the step done. Keep the old target running until the old TTL has passed twice over;
+ only then decommission it, and put the TTL back.
4. **Broadcaster windows, for step F.** For each slot, agree a maintenance window with its broadcaster.
4. **Broadcaster windows, for step F.** For each slot, agree a maintenance window with its broadcaster.
The slot is offline, and the broadcaster regenerates the key and pastes the new server into OBS
The slot is offline, and the broadcaster regenerates the key and pastes the new server into OBS
(ADR-009).
(ADR-009).
@@ -308,7 +313,7 @@ PowerChat delivery lands in exactly one ledger.
@@ -308,7 +313,7 @@ PowerChat delivery lands in exactly one ledger.
Read the full list before choosing the day. VIP checkout stays closed until this cutover.
Read the full list before choosing the day. VIP checkout stays closed until this cutover.
-## F. RTMP ingest → OpenRe.Stream: BLOCKED on the owner (DNS, port 1936, broadcaster windows)
+## F. RTMP ingest → OpenRe.Stream: BLOCKED on the owner (rehearsal and broadcaster windows; DNS and port 1936 are done)
OpenRe is deployed. The API is `openre-api` on 127.0.0.1:4500. The other units are
OpenRe is deployed. The API is `openre-api` on 127.0.0.1:4500. The other units are
`openre-session-coordinator`, `openre-rtmp-ingest@<sha>` and `openre-restream-worker@<sha>`. The database
`openre-session-coordinator`, `openre-rtmp-ingest@<sha>` and `openre-restream-worker@<sha>`. The database