openvibers/openvibe.sites Commits

Placeholder labels come from facts, not a hand-kept list

OP OpenVibers committed 24 Sept 2026 · 8be8071816 · 54 files, +827 −221

build.js labelled every repository outside a static EXISTING_REPOS set of six "(charter only, no code
yet)", and status.json said repoStage charter-only. That was false for Tips, VIP, News, Reviews, Deals,
Coupons, Trade, Host, Chat, OpenRe.Stream and AI: all have code and run on the host's loopback.

facts.json is a committed snapshot of each named repository's STATUS.json (read at HEAD of the sibling
checkout, commit recorded) and Network's registry exposure (/api/v1/registry/services). scripts/facts.js
refreshes it; build.js reads only the snapshot, so builds stay reproducible and CI needs no network.

A page now says where its product stands: "in development" when the service runs, with what its
public launch waits for (the new `launch` field in sites.json); "not routed yet" with a link to the live
service for the Network subdomains; "charter only" only when there is no code. status.json carries the
same facts (repoStage, service, launchWaitsFor, factsAsOf).

Stale copy fixed on the way: Chat already runs Live's chat (voice stays in Live); OpenRe.Stream is not
behind Live yet (no slot uses it; WHIP not ported) and no longer lists RobotStreamer; AI runs as an
internal service Live and Network call; api. points at the registry, /.well-known/openvibe and
openvibe.codes; auth. links the OpenID configuration Network actually serves (/oauth/.well-known/...).
The navbar's "What it will be" link now has its #what target.

test/build.test.js: no page for a repository with code says "charter only"; a running service states
its launch condition; a live service's subdomain links it; facts.json matches the sibling STATUS.json
files when they are checked out.

Changes

ddiff --git a/README.md b/README.md
iindex 47b9f9e..504b274 100644
---- a/README.md
++++ b/README.md
@@@ -14,10 +14,20 @@ SEO (canonical, Open Graph, Twitter, JSON-LD, robots, sitemap, manifest).
```
npm ci # openvibe-shared: the pinned OpenVibe.Shared release (package.json)
++node scripts/facts.js # refresh facts.json (each repo's STATUS.json + Network's registry exposure)
node build.js # dist/<domain>/… + deploy/nginx/<domain>.conf
node build.js --check # fails when dist/ is stale
++npm test # dist current; labels match facts.json; facts.json matches the sibling STATUS.json files
```
++What a page says about its product comes from `facts.json`, never from a hand-kept list: each
++repository's committed `STATUS.json` (read from the sibling `~/OpenVibers/<repo>` checkouts at HEAD)
++and Network's registry exposure (`/api/v1/registry/services`). A product whose service runs is
++labelled "in development" with what its public launch waits for (`launch` in `sites.json`); a
++subdomain of a live service says it is not routed yet; only a repository with no code says
++"charter only". The build reads the committed snapshot, so it is reproducible; `npm test` fails
++locally when a sibling's `STATUS.json` stage or code flag no longer matches it.
++
Deploy (host): the repo lives at `/opt/openvibe.sites`; `deploy/scripts/deploy.sh` runs `npm ci`, rebuilds, installs
the vhosts into `/etc/nginx/sites-available`, enables them and reloads nginx. Each domain has a
Let's Encrypt wildcard certificate (`certbot --dns-cloudflare`, see the host's renewal configs).
ddiff --git a/build.js b/build.js
iindex ad0a667..a53ca71 100644
---- a/build.js
++++ b/build.js
@@@ -6,10 +6,12 @@
* node build.js → dist/<domain>/{index.html,robots.txt,sitemap.xml,manifest.webmanifest}
* node build.js --check → exit 1 when dist/ is stale (CI / deploy guard)
*
-- * One template, one catalog (sites.json). Every page is real content for people and crawlers:
-- * what the site will be, what to use meanwhile, the whole network, sign-in — with the shared
-- * navbar/footer/theme loader from openvibe.network so the domain already feels like the rest of
-- * the network. No build step at request time: nginx serves the files.
++ * One template, one catalog (sites.json), one snapshot of facts (facts.json, refreshed by
++ * scripts/facts.js from each repository's STATUS.json and the Network registry). Every page is real
++ * content for people and crawlers: what the site will be, where its product stands today (from
++ * facts.json, never a hand-kept list), what to use meanwhile, the whole network, sign-in — with the
++ * shared navbar/footer/theme loader from openvibe.network so the domain already feels like the rest
++ * of the network. No build step at request time: nginx serves the files.
*/
const fs = require('fs');
const path = require('path');
@@@ -18,16 +20,66 @@ const legal = require('openvibe-shared/legal');
// Which clauses apply to each domain once it opens (mirrors OpenVibe.Network/server/chrome/sites.js).
const LEGAL_PROFILE = { chat: 'ugc', codes: 'ugc', blog: 'info', wiki: 'ugc', news: 'info', reviews: 'ugc', tips: 'streaming', vip: 'account', trade: 'ugc', host: 'hosting', deals: 'info', coupons: 'info', stream: 'streaming' };
// Sites whose own server has no page routes: their legal pages are built here and served by nginx.
--// Repositories that already run a real service (a placeholder subdomain is a planned surface of them, not a new codebase).
--const EXISTING_REPOS = new Set(['OpenVibe.Network', 'OpenVibe.Live', 'OpenVibe.Media', 'OpenVibe.Community', 'OpenVibe.Tools', 'OpenVibe.Games']);
const LEGAL_ONLY = [{ domain: 'openvibe.games', name: 'OpenVibe.Games', id: 'games', profile: 'games' }];
const legalSite = (site) => ({ id: site.tld, service: 'network', host: site.domain, name: site.name, profile: site.legalProfile || LEGAL_PROFILE[site.tld] || 'info' });
const ROOT = __dirname;
const DIST = path.join(ROOT, 'dist');
const catalog = JSON.parse(fs.readFileSync(path.join(ROOT, 'sites.json'), 'utf8'));
++// What is true about each repository a page names: its committed STATUS.json and Network's registry
++// exposure, snapshotted by scripts/facts.js. The build reads only this file, so it is reproducible.
++const facts = JSON.parse(fs.readFileSync(path.join(ROOT, 'facts.json'), 'utf8'));
const NET = catalog.network;
const esc = (s) => String(s == null ? '' : s).replace(/[&<>"']/g, c => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
++
++/** The facts row for a site's repository (null when the page names none). A missing row fails the build. */
++function repoFacts(site) {
++ if (!site.plannedRepo) return null;
++ const f = facts.repos[site.plannedRepo];
++ if (!f) throw new Error(`${site.domain}: facts.json has no row for ${site.plannedRepo}; run node scripts/facts.js`);
++ return f;
++}
++/**
++ * Where the product behind a page stands, from facts only:
++ * closed the repository's STATUS.json says closed (a decision record, nothing to launch)
++ * surface the repository's service is public elsewhere; this domain is not routed to it yet
++ * running the service is built and runs on the host (loopback only); the domain is not public yet
++ * code code exists, nothing deployed
++ * planned charter only, no code
++ */
++function standing(site) {
++ const f = repoFacts(site);
++ if (!f) return 'planned';
++ const st = f.status || {}; const rg = f.registry || {};
++ if (st.stage === 'closed' || rg.state === 'closed') return 'closed';
++ if (rg.state === 'live' && rg.public_site === 'service') return 'surface';
++ if (rg.state === 'internal' || (st.code && st.deployed)) return 'running';
++ if (st.code) return 'code';
++ return 'planned';
++}
++const STANDING = {
++ running: { label: 'in development', repoStage: 'service-running' },
++ code: { label: 'in development', repoStage: 'code-not-deployed' },
++ surface: { label: 'not routed yet', repoStage: 'surface-of-a-live-service' },
++ planned: { label: 'planned', repoStage: 'charter-only' },
++ closed: { label: 'closed', repoStage: 'closed' },
++};
++const repoLink = (repo) => `<a href="https://github.com/OpenVibers/${esc(repo)}" rel="noopener"><code>OpenVibers/${esc(repo)}</code></a>`;
++/** The hero's status sentence: what is true about the product, and what its public launch waits for. */
++function statusText(site) {
++ const k = standing(site);
++ const f = repoFacts(site);
++ const repo = site.plannedRepo ? repoLink(site.plannedRepo) : '<code>OpenVibe.Network</code>';
++ const waits = site.launch ? ` The public launch is waiting for ${esc(site.launch)}.` : '';
++ if (k === 'running') return `${repo} is built and its service runs on the network's host, but it is not public yet; this page is a placeholder.${waits}`;
++ if (k === 'code') return `${repo} has code, but nothing is deployed yet; this page is a placeholder.${waits}`;
++ if (k === 'surface') {
++ const o = f.registry.origin;
++ return `${repo} is live at <a href="${esc(o)}/">${esc(o.replace(/^https?:\/\//, ''))}</a>; this subdomain is not routed to it yet, so it serves this placeholder.`;
++ }
++ if (k === 'closed') return `${repo} is closed, so no product launches here; this page is a placeholder.`;
++ return `${repo}: charter only, no code yet; this page is a placeholder.${waits}`;
++}
const today = new Date().toISOString().slice(0, 10);
// A page is first published once; rebuilding it later changes dateModified, never datePublished.
const FIRST_PUBLISHED = '2026-09-17';
@@@ -145,7 +197,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid ${esc(site.icon)}" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="${esc(site.tld)}"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="${esc(site.tld)}"></span> Part of the OpenVibe network · <b>${esc(STANDING[standing(site)].label)}</b></div>
<h1>${site.hostParts ? `<span class="d">${esc(site.hostParts[0])}</span><span class="tld">.${esc(site.hostParts[1])}</span>` : `${esc(core)}<span class="d">.</span><span class="tld">${esc(site.name.split('.').pop())}</span>`}</h1>
<div class="tag">${esc(site.tagline)}</div>
<p class="lead">${esc(site.description)}</p>
@@@ -154,10 +206,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="${NET.networkUrl}/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="${esc(NET.discord)}" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: ${site.plannedRepo ? `<a href="https://github.com/OpenVibers/${esc(site.plannedRepo)}" rel="noopener"><code>OpenVibers/${esc(site.plannedRepo)}</code></a>${EXISTING_REPOS.has(site.plannedRepo) ? ' (a surface of that existing service; not split out yet)' : ' (charter only, no code yet)'}` : '<code>OpenVibe.Network</code>'} · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>${esc(STANDING[standing(site)].label)}</b> · ${statusText(site)} · as of ${esc(facts.generated)} · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What ${esc(site.name)} will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -179,7 +231,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<div class="grid">
${others.map(s => `<a class="card" href="${esc(s.url)}"><div class="ic"><i class="fa-solid ${esc(s.icon)}" aria-hidden="true"></i></div><b>${esc(s.name)}</b><span>${esc(s.desc)}</span><span class="go">${esc(s.url.replace(/^https?:\/\//, ''))} →</span></a>`).join('\n ')}
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
${siblings.map(s => `<a href="https://${esc(s.domain)}/"><i class="fa-solid ${esc(s.icon)}" aria-hidden="true"></i>${esc(s.name)}</a>`).join('\n ')}
</div>
@@@ -273,6 +325,25 @@ server {
`;
}
++/** /status.json: the same facts as the page, for scripts (CORS-open). */
++function statusJson(site) {
++ const f = repoFacts(site);
++ const k = standing(site);
++ const st = (f && f.status) || null; const rg = (f && f.registry) || null;
++ return JSON.stringify({
++ domain: site.domain, name: site.name, stage: site.kind || 'placeholder', live: false,
++ plannedRepo: site.plannedRepo ? `OpenVibers/${site.plannedRepo}` : null,
++ repoUrl: site.plannedRepo ? `https://github.com/OpenVibers/${site.plannedRepo}` : null,
++ repoExists: !!site.plannedRepo,
++ repoStage: STANDING[k].repoStage,
++ service: f ? { stage: st && st.stage, code: st ? st.code : null, deployed: st ? st.deployed : null, statusCommit: st && st.commit, exposure: rg && rg.state, publicOrigin: rg && rg.origin } : null,
++ launchWaitsFor: site.launch || null,
++ factsAsOf: facts.generated,
++ network: NET.networkUrl, updated: today,
++ note: 'Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository\'s STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain.',
++ }, null, 2) + '\n';
++}
++
function build() {
const out = {};
for (const site of catalog.sites) {
@@@ -280,7 +351,7 @@ function build() {
out[`${site.domain}/robots.txt`] = robots(site);
out[`${site.domain}/sitemap.xml`] = sitemap(site);
out[`${site.domain}/manifest.webmanifest`] = manifest(site);
-- out[`${site.domain}/status.json`] = JSON.stringify({ domain: site.domain, name: site.name, stage: site.stage || 'placeholder', live: false, plannedRepo: site.plannedRepo ? `OpenVibers/${site.plannedRepo}` : null, repoUrl: site.plannedRepo ? `https://github.com/OpenVibers/${site.plannedRepo}` : null, repoExists: !!site.plannedRepo, repoStage: site.plannedRepo ? (EXISTING_REPOS.has(site.plannedRepo) ? 'existing-service' : 'charter-only') : null, network: NET.networkUrl, updated: today, note: 'Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain.' }, null, 2) + '\n';
++ out[`${site.domain}/status.json`] = statusJson(site);
for (const kind of ['terms', 'privacy', 'dmca']) out[`${site.domain}/${kind}.html`] = legal.page(kind, legalSite(site));
out[`../deploy/nginx/${site.domain}.conf`] = vhost(site);
}
ddiff --git a/dist/admin.openvibe.network/index.html b/dist/admin.openvibe.network/index.html
iindex 45f2158..b45add1 100644
---- a/dist/admin.openvibe.network/index.html
++++ b/dist/admin.openvibe.network/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="admin.openvibe.network — One operator console for every service.">
<meta name="twitter:description" content="admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://admin.openvibe.network/#site","url":"https://admin.openvibe.network/","name":"admin.openvibe.network","description":"admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://admin.openvibe.network/#page","url":"https://admin.openvibe.network/","name":"admin.openvibe.network — One operator console for every service.","description":"admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.","isPartOf":{"@id":"https://admin.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"admin.openvibe.network","item":"https://admin.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://admin.openvibe.network/#site","url":"https://admin.openvibe.network/","name":"admin.openvibe.network","description":"admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://admin.openvibe.network/#page","url":"https://admin.openvibe.network/","name":"admin.openvibe.network — One operator console for every service.","description":"admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.","isPartOf":{"@id":"https://admin.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"admin.openvibe.network","item":"https://admin.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-shield-halved" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="admin"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="admin"></span> Part of the OpenVibe network · <b>not routed yet</b></div>
<h1><span class="d">admin</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">One operator console for every service.</div>
<p class="lead">admin.openvibe.network will be the federated operator console: users, roles, bans, registry and policy, event queues, storage, billing, migrations and emergency controls, discovered from each service rather than hard-wired.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> (a surface of that existing service; not split out yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>not routed yet</b> · <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> is live at <a href="https://openvibe.network/">openvibe.network</a>; this subdomain is not routed to it yet, so it serves this placeholder. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What admin.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/admin.openvibe.network/sitemap.xml b/dist/admin.openvibe.network/sitemap.xml
iindex 5e936dd..f162561 100644
---- a/dist/admin.openvibe.network/sitemap.xml
++++ b/dist/admin.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://admin.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://admin.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/admin.openvibe.network/status.json b/dist/admin.openvibe.network/status.json
iindex 7746d24..9a0ca90 100644
---- a/dist/admin.openvibe.network/status.json
++++ b/dist/admin.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Network",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Network",
"repoExists": true,
-- "repoStage": "existing-service",
++ "repoStage": "surface-of-a-live-service",
++ "service": {
++ "stage": null,
++ "code": null,
++ "deployed": null,
++ "statusCommit": null,
++ "exposure": "live",
++ "publicOrigin": "https://openvibe.network"
++ },
++ "launchWaitsFor": null,
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/ai.openvibe.network/index.html b/dist/ai.openvibe.network/index.html
iindex c904c96..7059583 100644
---- a/dist/ai.openvibe.network/index.html
++++ b/dist/ai.openvibe.network/index.html
@@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>ai.openvibe.network — AI as a service, for every OpenVibe product.</title>
--<meta name="description" content="ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.">
++<meta name="description" content="OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.">
<meta name="keywords" content="openvibe ai, openvibe network ai, openvibe platform">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#c084fc">
@@@ -17,14 +17,14 @@
<meta property="og:site_name" content="ai.openvibe.network">
<meta property="og:url" content="https://ai.openvibe.network/">
<meta property="og:title" content="ai.openvibe.network — AI as a service, for every OpenVibe product.">
--<meta property="og:description" content="ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.">
++<meta property="og:description" content="OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="ai.openvibe.network — AI as a service, for every OpenVibe product.">
--<meta name="twitter:description" content="ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.">
++<meta name="twitter:description" content="OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://ai.openvibe.network/#site","url":"https://ai.openvibe.network/","name":"ai.openvibe.network","description":"ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://ai.openvibe.network/#page","url":"https://ai.openvibe.network/","name":"ai.openvibe.network — AI as a service, for every OpenVibe product.","description":"ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.","isPartOf":{"@id":"https://ai.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"ai.openvibe.network","item":"https://ai.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://ai.openvibe.network/#site","url":"https://ai.openvibe.network/","name":"ai.openvibe.network","description":"OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://ai.openvibe.network/#page","url":"https://ai.openvibe.network/","name":"ai.openvibe.network — AI as a service, for every OpenVibe product.","description":"OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.","isPartOf":{"@id":"https://ai.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"ai.openvibe.network","item":"https://ai.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,19 +92,19 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-robot" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="ai"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="ai"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1><span class="d">ai</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">AI as a service, for every OpenVibe product.</div>
-- <p class="lead">ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.</p>
++ <p class="lead">OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fai.openvibe.network%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.AI" rel="noopener"><code>OpenVibers/OpenVibe.AI</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.AI" rel="noopener"><code>OpenVibers/OpenVibe.AI</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a public API with its own access rules; today only other OpenVibe services call it. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What ai.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -119,7 +119,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<h2>Meanwhile, on the network</h2>
<p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
<div class="grid">
-- <a class="card" href="https://openvibe.live"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>AI clips and captions</b><span>Live captions, translation and AI moments already run on OpenVibe.Live.</span><span class="go">openvibe.live →</span></a>
++ <a class="card" href="https://openvibe.live"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>AI on OpenVibe.Live</b><span>Live&#39;s AI moments, recaps, summaries and translations run through OpenVibe.AI; captions still run inside Live.</span><span class="go">openvibe.live →</span></a>
</div>
</section>
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/ai.openvibe.network/sitemap.xml b/dist/ai.openvibe.network/sitemap.xml
iindex 5c0a2b4..08bd21f 100644
---- a/dist/ai.openvibe.network/sitemap.xml
++++ b/dist/ai.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://ai.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://ai.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/ai.openvibe.network/status.json b/dist/ai.openvibe.network/status.json
iindex 4aca220..ababe14 100644
---- a/dist/ai.openvibe.network/status.json
++++ b/dist/ai.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.AI",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.AI",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "f034a9f",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a public API with its own access rules; today only other OpenVibe services call it",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/api.openvibe.network/index.html b/dist/api.openvibe.network/index.html
iindex bda3fa1..b58b580 100644
---- a/dist/api.openvibe.network/index.html
++++ b/dist/api.openvibe.network/index.html
@@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>api.openvibe.network — The network, machine-readable.</title>
--<meta name="description" content="api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.">
++<meta name="description" content="api.openvibe.network is the planned home of the network&#39;s public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.">
<meta name="keywords" content="openvibe api, openvibe network api, openvibe platform">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#22d3ee">
@@@ -17,14 +17,14 @@
<meta property="og:site_name" content="api.openvibe.network">
<meta property="og:url" content="https://api.openvibe.network/">
<meta property="og:title" content="api.openvibe.network — The network, machine-readable.">
--<meta property="og:description" content="api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.">
++<meta property="og:description" content="api.openvibe.network is the planned home of the network&#39;s public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="api.openvibe.network — The network, machine-readable.">
--<meta name="twitter:description" content="api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.">
++<meta name="twitter:description" content="api.openvibe.network is the planned home of the network&#39;s public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://api.openvibe.network/#site","url":"https://api.openvibe.network/","name":"api.openvibe.network","description":"api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://api.openvibe.network/#page","url":"https://api.openvibe.network/","name":"api.openvibe.network — The network, machine-readable.","description":"api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.","isPartOf":{"@id":"https://api.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"api.openvibe.network","item":"https://api.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://api.openvibe.network/#site","url":"https://api.openvibe.network/","name":"api.openvibe.network","description":"api.openvibe.network is the planned home of the network's public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://api.openvibe.network/#page","url":"https://api.openvibe.network/","name":"api.openvibe.network — The network, machine-readable.","description":"api.openvibe.network is the planned home of the network's public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.","isPartOf":{"@id":"https://api.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"api.openvibe.network","item":"https://api.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,19 +92,19 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-plug" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="api"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="api"></span> Part of the OpenVibe network · <b>not routed yet</b></div>
<h1><span class="d">api</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">The network, machine-readable.</div>
-- <p class="lead">api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.</p>
++ <p class="lead">api.openvibe.network is the planned home of the network&#39;s public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fapi.openvibe.network%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> (a surface of that existing service; not split out yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>not routed yet</b> · <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> is live at <a href="https://openvibe.network/">openvibe.network</a>; this subdomain is not routed to it yet, so it serves this placeholder. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What api.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -119,8 +119,9 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<h2>Meanwhile, on the network</h2>
<p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
<div class="grid">
-- <a class="card" href="https://openvibe.network/developers"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Developer pages</b><span>Current developer documentation on openvibe.network.</span><span class="go">openvibe.network/developers →</span></a>
-- <a class="card" href="https://openvibe.live/documentation"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Streaming API docs</b><span>Ingest, WHIP and playback docs live on OpenVibe.Live.</span><span class="go">openvibe.live/documentation →</span></a>
++ <a class="card" href="https://openvibe.network/api/v1/registry"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Registry API</b><span>Services, capabilities, namespaces, event topics and releases, as JSON.</span><span class="go">openvibe.network/api/v1/registry →</span></a>
++ <a class="card" href="https://openvibe.network/.well-known/openvibe"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Service discovery</b><span>The issuer, token and key endpoints, and where each service answers.</span><span class="go">openvibe.network/.well-known/openvibe →</span></a>
++ <a class="card" href="https://openvibe.codes"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Developer portal</b><span>Projects, apps and credentials, contract and SDK docs on OpenVibe.Codes.</span><span class="go">openvibe.codes →</span></a>
</div>
</section>
@@@ -135,7 +136,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/api.openvibe.network/sitemap.xml b/dist/api.openvibe.network/sitemap.xml
iindex 0e920af..b55546a 100644
---- a/dist/api.openvibe.network/sitemap.xml
++++ b/dist/api.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://api.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://api.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/api.openvibe.network/status.json b/dist/api.openvibe.network/status.json
iindex 1c102a9..c5b7de5 100644
---- a/dist/api.openvibe.network/status.json
++++ b/dist/api.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Network",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Network",
"repoExists": true,
-- "repoStage": "existing-service",
++ "repoStage": "surface-of-a-live-service",
++ "service": {
++ "stage": null,
++ "code": null,
++ "deployed": null,
++ "statusCommit": null,
++ "exposure": "live",
++ "publicOrigin": "https://openvibe.network"
++ },
++ "launchWaitsFor": null,
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/auth.openvibe.network/index.html b/dist/auth.openvibe.network/index.html
iindex 59dd14f..2b2daed 100644
---- a/dist/auth.openvibe.network/index.html
++++ b/dist/auth.openvibe.network/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="auth.openvibe.network — Sign in, once, for the whole network.">
<meta name="twitter:description" content="auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://auth.openvibe.network/#site","url":"https://auth.openvibe.network/","name":"auth.openvibe.network","description":"auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://auth.openvibe.network/#page","url":"https://auth.openvibe.network/","name":"auth.openvibe.network — Sign in, once, for the whole network.","description":"auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.","isPartOf":{"@id":"https://auth.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"auth.openvibe.network","item":"https://auth.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://auth.openvibe.network/#site","url":"https://auth.openvibe.network/","name":"auth.openvibe.network","description":"auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://auth.openvibe.network/#page","url":"https://auth.openvibe.network/","name":"auth.openvibe.network — Sign in, once, for the whole network.","description":"auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.","isPartOf":{"@id":"https://auth.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"auth.openvibe.network","item":"https://auth.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-key" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="auth"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="auth"></span> Part of the OpenVibe network · <b>not routed yet</b></div>
<h1><span class="d">auth</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">Sign in, once, for the whole network.</div>
<p class="lead">auth.openvibe.network will be the dedicated home of OpenVibe identity: sign-in, registration, OAuth 2.0 / OpenID Connect for apps, sessions and linked accounts. Today all of this runs inside openvibe.network itself.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> (a surface of that existing service; not split out yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>not routed yet</b> · <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> is live at <a href="https://openvibe.network/">openvibe.network</a>; this subdomain is not routed to it yet, so it serves this placeholder. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What auth.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -120,7 +120,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
<div class="grid">
<a class="card" href="https://openvibe.network/auth/login"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Sign in on openvibe.network</b><span>The live sign-in flow, used by every OpenVibe site today.</span><span class="go">openvibe.network/auth/login →</span></a>
-- <a class="card" href="https://openvibe.network/.well-known/openid-configuration"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>OIDC discovery</b><span>The OpenID configuration is already published.</span><span class="go">openvibe.network/.well-known/openid-configuration →</span></a>
++ <a class="card" href="https://openvibe.network/oauth/.well-known/openid-configuration"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>OIDC discovery</b><span>The OpenID configuration Network publishes today.</span><span class="go">openvibe.network/oauth/.well-known/openid-configuration →</span></a>
</div>
</section>
@@@ -135,7 +135,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/auth.openvibe.network/sitemap.xml b/dist/auth.openvibe.network/sitemap.xml
iindex ccf6e8a..9e608d0 100644
---- a/dist/auth.openvibe.network/sitemap.xml
++++ b/dist/auth.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://auth.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://auth.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/auth.openvibe.network/status.json b/dist/auth.openvibe.network/status.json
iindex 3ed8851..37c2364 100644
---- a/dist/auth.openvibe.network/status.json
++++ b/dist/auth.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Network",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Network",
"repoExists": true,
-- "repoStage": "existing-service",
++ "repoStage": "surface-of-a-live-service",
++ "service": {
++ "stage": null,
++ "code": null,
++ "deployed": null,
++ "statusCommit": null,
++ "exposure": "live",
++ "publicOrigin": "https://openvibe.network"
++ },
++ "launchWaitsFor": null,
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openre.stream/index.html b/dist/openre.stream/index.html
iindex 2e1d6c9..a797a4f 100644
---- a/dist/openre.stream/index.html
++++ b/dist/openre.stream/index.html
@@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OpenRe.Stream — Ingest and restream, in the open.</title>
--<meta name="description" content="OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.">
++<meta name="description" content="OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.">
<meta name="keywords" content="openre stream, rtmp ingest, whip, srt, restream, open source streaming infrastructure">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#ef4444">
@@@ -17,14 +17,14 @@
<meta property="og:site_name" content="OpenRe.Stream">
<meta property="og:url" content="https://openre.stream/">
<meta property="og:title" content="OpenRe.Stream — Ingest and restream, in the open.">
--<meta property="og:description" content="OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.">
++<meta property="og:description" content="OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="OpenRe.Stream — Ingest and restream, in the open.">
--<meta name="twitter:description" content="OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.">
++<meta name="twitter:description" content="OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openre.stream/#site","url":"https://openre.stream/","name":"OpenRe.Stream","description":"OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openre.stream/#page","url":"https://openre.stream/","name":"OpenRe.Stream — Ingest and restream, in the open.","description":"OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.","isPartOf":{"@id":"https://openre.stream/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenRe.Stream","item":"https://openre.stream/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openre.stream/#site","url":"https://openre.stream/","name":"OpenRe.Stream","description":"OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openre.stream/#page","url":"https://openre.stream/","name":"OpenRe.Stream — Ingest and restream, in the open.","description":"OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.","isPartOf":{"@id":"https://openre.stream/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenRe.Stream","item":"https://openre.stream/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,24 +92,24 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="stream"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="stream"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenRe<span class="d">.</span><span class="tld">Stream</span></h1>
<div class="tag">Ingest and restream, in the open.</div>
-- <p class="lead">OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.</p>
++ <p class="lead">OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fopenre.stream%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenRe.Stream" rel="noopener"><code>OpenVibers/OpenRe.Stream</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenRe.Stream" rel="noopener"><code>OpenVibers/OpenRe.Stream</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for the stream slots to move from OpenVibe.Live&#39;s ingest to OpenRe.Stream, one at a time; no stream uses it yet. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenRe.Stream will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
-- <div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Ingest</b><span>RTMP, WHIP/WebRTC and SRT, with keys and lifecycle in one place.</span></div>
-- <div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Restream</b><span>Twitch, YouTube, Kick, SRT and RobotStreamer destinations.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Ingest</b><span>RTMP ingest with keys and lifecycle in one place; WHIP/WebRTC and SRT ingest to follow.</span></div>
++ <div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Restream</b><span>Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination.</span></div>
<div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Status</b><span>Live acknowledgement, errors relayed in plain words, uptime.</span></div>
<div class="card"><div class="ic"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div><b>Open</b><span>Run it yourself; the code is on GitHub.</span></div>
</div>
@@@ -120,7 +120,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<p class="lead2">Most of this already exists somewhere on OpenVibe — start there today.</p>
<div class="grid">
<a class="card" href="https://openvibe.live/broadcast"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Go live on OpenVibe.Live</b><span>Ingest and restreaming run inside Live today.</span><span class="go">openvibe.live/broadcast →</span></a>
-- <a class="card" href="https://github.com/OpenVibers/OpenVibe.Live/blob/main/docs/restreaming.md"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Restreaming docs</b><span>How the restream paths work.</span><span class="go">github.com/OpenVibers/OpenVibe.Live/blob/main/docs/restreaming.md →</span></a>
++ <a class="card" href="https://openvibe.live/docs/restreaming"><div class="ic"><i class="fa-solid fa-arrow-up-right-from-square" aria-hidden="true"></i></div><b>Restreaming docs</b><span>How the restream paths work.</span><span class="go">openvibe.live/docs/restreaming →</span></a>
</div>
</section>
@@@ -135,7 +135,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openre.stream/sitemap.xml b/dist/openre.stream/sitemap.xml
iindex 31e4031..dbbdbea 100644
---- a/dist/openre.stream/sitemap.xml
++++ b/dist/openre.stream/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openre.stream/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openre.stream/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openre.stream/status.json b/dist/openre.stream/status.json
iindex 3de714e..0359742 100644
---- a/dist/openre.stream/status.json
++++ b/dist/openre.stream/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenRe.Stream",
"repoUrl": "https://github.com/OpenVibers/OpenRe.Stream",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "cc70a5a",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "the stream slots to move from OpenVibe.Live's ingest to OpenRe.Stream, one at a time; no stream uses it yet",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.chat/index.html b/dist/openvibe.chat/index.html
iindex edeb334..dd41d60 100644
---- a/dist/openvibe.chat/index.html
++++ b/dist/openvibe.chat/index.html
@@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>OpenVibe.Chat — One chat for the whole network.</title>
--<meta name="description" content="OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.">
++<meta name="description" content="OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.">
<meta name="keywords" content="openvibe chat, community chat, voice rooms, direct messages, free speech chat">
<meta name="robots" content="index, follow, max-image-preview:large">
<meta name="theme-color" content="#a78bfa">
@@@ -17,14 +17,14 @@
<meta property="og:site_name" content="OpenVibe.Chat">
<meta property="og:url" content="https://openvibe.chat/">
<meta property="og:title" content="OpenVibe.Chat — One chat for the whole network.">
--<meta property="og:description" content="OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.">
++<meta property="og:description" content="OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.">
<meta property="og:image" content="https://openvibe.network/assets/logo-512.png">
<meta property="og:image:alt" content="OpenVibe">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="OpenVibe.Chat — One chat for the whole network.">
--<meta name="twitter:description" content="OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.">
++<meta name="twitter:description" content="OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.chat/#site","url":"https://openvibe.chat/","name":"OpenVibe.Chat","description":"OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.chat/#page","url":"https://openvibe.chat/","name":"OpenVibe.Chat — One chat for the whole network.","description":"OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.","isPartOf":{"@id":"https://openvibe.chat/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Chat","item":"https://openvibe.chat/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.chat/#site","url":"https://openvibe.chat/","name":"OpenVibe.Chat","description":"OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.chat/#page","url":"https://openvibe.chat/","name":"OpenVibe.Chat — One chat for the whole network.","description":"OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.","isPartOf":{"@id":"https://openvibe.chat/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Chat","item":"https://openvibe.chat/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,19 +92,19 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-comments" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="chat"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="chat"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Chat</span></h1>
<div class="tag">One chat for the whole network.</div>
-- <p class="lead">OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.</p>
++ <p class="lead">OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.</p>
<div class="ctas">
<a class="btn btn-primary" href="https://openvibe.network/login?return=https%3A%2F%2Fopenvibe.chat%2F"><i class="fa-solid fa-right-to-bracket"></i> Sign in with OpenVibe</a>
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Chat" rel="noopener"><code>OpenVibers/OpenVibe.Chat</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Chat" rel="noopener"><code>OpenVibers/OpenVibe.Chat</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for its own web client at this address; the service already runs the chat on OpenVibe.Live. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Chat will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -135,7 +135,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
<a href="https://openvibe.reviews/"><i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i>OpenVibe.Reviews</a>
ddiff --git a/dist/openvibe.chat/sitemap.xml b/dist/openvibe.chat/sitemap.xml
iindex 3a45e43..0545818 100644
---- a/dist/openvibe.chat/sitemap.xml
++++ b/dist/openvibe.chat/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.chat/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.chat/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.chat/status.json b/dist/openvibe.chat/status.json
iindex b782340..8424f95 100644
---- a/dist/openvibe.chat/status.json
++++ b/dist/openvibe.chat/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Chat",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Chat",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "fcc824a",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "its own web client at this address; the service already runs the chat on OpenVibe.Live",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.coupons/index.html b/dist/openvibe.coupons/index.html
iindex f4f634d..8868128 100644
---- a/dist/openvibe.coupons/index.html
++++ b/dist/openvibe.coupons/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Coupons — Codes that actually work.">
<meta name="twitter:description" content="OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.coupons/#site","url":"https://openvibe.coupons/","name":"OpenVibe.Coupons","description":"OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.coupons/#page","url":"https://openvibe.coupons/","name":"OpenVibe.Coupons — Codes that actually work.","description":"OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.","isPartOf":{"@id":"https://openvibe.coupons/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Coupons","item":"https://openvibe.coupons/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.coupons/#site","url":"https://openvibe.coupons/","name":"OpenVibe.Coupons","description":"OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.coupons/#page","url":"https://openvibe.coupons/","name":"OpenVibe.Coupons — Codes that actually work.","description":"OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.","isPartOf":{"@id":"https://openvibe.coupons/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Coupons","item":"https://openvibe.coupons/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-ticket" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="coupons"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="coupons"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Coupons</span></h1>
<div class="tag">Codes that actually work.</div>
<p class="lead">OpenVibe.Coupons is community-checked coupon discovery: codes matched to stores, validity reported by real people, expirations tracked, and a browser helper on the way.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Coupons" rel="noopener"><code>OpenVibers/OpenVibe.Coupons</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Coupons" rel="noopener"><code>OpenVibers/OpenVibe.Coupons</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a person to verify a coupons source&#39;s terms and switch it on. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Coupons will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.coupons/sitemap.xml b/dist/openvibe.coupons/sitemap.xml
iindex 8260d4f..fe32d44 100644
---- a/dist/openvibe.coupons/sitemap.xml
++++ b/dist/openvibe.coupons/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.coupons/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.coupons/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.coupons/status.json b/dist/openvibe.coupons/status.json
iindex 3468677..30dc73c 100644
---- a/dist/openvibe.coupons/status.json
++++ b/dist/openvibe.coupons/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Coupons",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Coupons",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "93f333b",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a person to verify a coupons source's terms and switch it on",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.deals/index.html b/dist/openvibe.deals/index.html
iindex a65fb20..a2c046b 100644
---- a/dist/openvibe.deals/index.html
++++ b/dist/openvibe.deals/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Deals — Deals worth seeing.">
<meta name="twitter:description" content="OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.deals/#site","url":"https://openvibe.deals/","name":"OpenVibe.Deals","description":"OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.deals/#page","url":"https://openvibe.deals/","name":"OpenVibe.Deals — Deals worth seeing.","description":"OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.","isPartOf":{"@id":"https://openvibe.deals/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Deals","item":"https://openvibe.deals/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.deals/#site","url":"https://openvibe.deals/","name":"OpenVibe.Deals","description":"OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.deals/#page","url":"https://openvibe.deals/","name":"OpenVibe.Deals — Deals worth seeing.","description":"OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.","isPartOf":{"@id":"https://openvibe.deals/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Deals","item":"https://openvibe.deals/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-tags" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="deals"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="deals"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Deals</span></h1>
<div class="tag">Deals worth seeing.</div>
<p class="lead">OpenVibe.Deals is community deal discovery for the OpenVibe network: deals people vote on, hotness that reflects real interest, keyword alerts, price comparisons and honest discussion.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Deals" rel="noopener"><code>OpenVibers/OpenVibe.Deals</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Deals" rel="noopener"><code>OpenVibers/OpenVibe.Deals</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a person to verify a deals source&#39;s terms and switch it on. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Deals will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.deals/sitemap.xml b/dist/openvibe.deals/sitemap.xml
iindex 5f2e029..9368268 100644
---- a/dist/openvibe.deals/sitemap.xml
++++ b/dist/openvibe.deals/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.deals/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.deals/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.deals/status.json b/dist/openvibe.deals/status.json
iindex 1abf21d..b618487 100644
---- a/dist/openvibe.deals/status.json
++++ b/dist/openvibe.deals/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Deals",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Deals",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "f453cb5",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a person to verify a deals source's terms and switch it on",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.host/index.html b/dist/openvibe.host/index.html
iindex 0f9e842..09d2eb2 100644
---- a/dist/openvibe.host/index.html
++++ b/dist/openvibe.host/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Host — Run it yourself.">
<meta name="twitter:description" content="OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.host/#site","url":"https://openvibe.host/","name":"OpenVibe.Host","description":"OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.host/#page","url":"https://openvibe.host/","name":"OpenVibe.Host — Run it yourself.","description":"OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.","isPartOf":{"@id":"https://openvibe.host/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Host","item":"https://openvibe.host/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.host/#site","url":"https://openvibe.host/","name":"OpenVibe.Host","description":"OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.host/#page","url":"https://openvibe.host/","name":"OpenVibe.Host — Run it yourself.","description":"OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.","isPartOf":{"@id":"https://openvibe.host/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Host","item":"https://openvibe.host/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-server" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="host"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="host"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Host</span></h1>
<div class="tag">Run it yourself.</div>
<p class="lead">OpenVibe.Host is the hosting and deployment surface of the OpenVibe network: deploy OpenVibe services, bots, mods and static sites, with TLS, DNS and logs handled for you.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Host" rel="noopener"><code>OpenVibers/OpenVibe.Host</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Host" rel="noopener"><code>OpenVibers/OpenVibe.Host</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for the owner&#39;s go on its launch checklist. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Host will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.host/sitemap.xml b/dist/openvibe.host/sitemap.xml
iindex 453fc63..a67da0d 100644
---- a/dist/openvibe.host/sitemap.xml
++++ b/dist/openvibe.host/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.host/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.host/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.host/status.json b/dist/openvibe.host/status.json
iindex 9e9469d..28e549b 100644
---- a/dist/openvibe.host/status.json
++++ b/dist/openvibe.host/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Host",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Host",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "2144ceb",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "the owner's go on its launch checklist",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.news/index.html b/dist/openvibe.news/index.html
iindex eef9d63..2e0b958 100644
---- a/dist/openvibe.news/index.html
++++ b/dist/openvibe.news/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.News — Sourced. Summarised. Many angles.">
<meta name="twitter:description" content="OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can&#39;t see.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.news/#site","url":"https://openvibe.news/","name":"OpenVibe.News","description":"OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can't see.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.news/#page","url":"https://openvibe.news/","name":"OpenVibe.News — Sourced. Summarised. Many angles.","description":"OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can't see.","isPartOf":{"@id":"https://openvibe.news/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.News","item":"https://openvibe.news/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.news/#site","url":"https://openvibe.news/","name":"OpenVibe.News","description":"OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can't see.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.news/#page","url":"https://openvibe.news/","name":"OpenVibe.News — Sourced. Summarised. Many angles.","description":"OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can't see.","isPartOf":{"@id":"https://openvibe.news/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.News","item":"https://openvibe.news/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-newspaper" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="news"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="news"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">News</span></h1>
<div class="tag">Sourced. Summarised. Many angles.</div>
<p class="lead">OpenVibe.News aggregates the news with transparency: sourced stories, summaries that show their sources, multiple angles side by side, topic pages and framing you control — not an algorithm you can&#39;t see.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.News" rel="noopener"><code>OpenVibers/OpenVibe.News</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.News" rel="noopener"><code>OpenVibers/OpenVibe.News</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a person to verify a news source&#39;s terms and an editor to publish the first reviewed story. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.News will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.reviews/"><i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i>OpenVibe.Reviews</a>
ddiff --git a/dist/openvibe.news/sitemap.xml b/dist/openvibe.news/sitemap.xml
iindex b674bb0..0d281ab 100644
---- a/dist/openvibe.news/sitemap.xml
++++ b/dist/openvibe.news/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.news/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.news/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.news/status.json b/dist/openvibe.news/status.json
iindex ccfcc36..3950437 100644
---- a/dist/openvibe.news/status.json
++++ b/dist/openvibe.news/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.News",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.News",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "c2c31b0",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a person to verify a news source's terms and an editor to publish the first reviewed story",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.reviews/index.html b/dist/openvibe.reviews/index.html
iindex 5b1df1d..d1d5888 100644
---- a/dist/openvibe.reviews/index.html
++++ b/dist/openvibe.reviews/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Reviews — What people actually say.">
<meta name="twitter:description" content="OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.reviews/#site","url":"https://openvibe.reviews/","name":"OpenVibe.Reviews","description":"OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.reviews/#page","url":"https://openvibe.reviews/","name":"OpenVibe.Reviews — What people actually say.","description":"OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.","isPartOf":{"@id":"https://openvibe.reviews/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Reviews","item":"https://openvibe.reviews/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.reviews/#site","url":"https://openvibe.reviews/","name":"OpenVibe.Reviews","description":"OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.reviews/#page","url":"https://openvibe.reviews/","name":"OpenVibe.Reviews — What people actually say.","description":"OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.","isPartOf":{"@id":"https://openvibe.reviews/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Reviews","item":"https://openvibe.reviews/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-star-half-stroke" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="reviews"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="reviews"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Reviews</span></h1>
<div class="tag">What people actually say.</div>
<p class="lead">OpenVibe.Reviews gathers what people say about products, services, employers, hosts and communities across many sources — with provenance, without fake ratings — and lets the community discuss it.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Reviews" rel="noopener"><code>OpenVibers/OpenVibe.Reviews</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Reviews" rel="noopener"><code>OpenVibers/OpenVibe.Reviews</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a person to verify a review source&#39;s terms and an editor to publish the first reviewed summary. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Reviews will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.reviews/sitemap.xml b/dist/openvibe.reviews/sitemap.xml
iindex 0bdfc67..5458bc1 100644
---- a/dist/openvibe.reviews/sitemap.xml
++++ b/dist/openvibe.reviews/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.reviews/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.reviews/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.reviews/status.json b/dist/openvibe.reviews/status.json
iindex dc6647d..a051eed 100644
---- a/dist/openvibe.reviews/status.json
++++ b/dist/openvibe.reviews/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Reviews",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Reviews",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "8905235",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a person to verify a review source's terms and an editor to publish the first reviewed summary",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.tips/index.html b/dist/openvibe.tips/index.html
iindex fbe0fbc..d505529 100644
---- a/dist/openvibe.tips/index.html
++++ b/dist/openvibe.tips/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Tips — Support the people you watch.">
<meta name="twitter:description" content="OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.tips/#site","url":"https://openvibe.tips/","name":"OpenVibe.Tips","description":"OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.tips/#page","url":"https://openvibe.tips/","name":"OpenVibe.Tips — Support the people you watch.","description":"OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.","isPartOf":{"@id":"https://openvibe.tips/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Tips","item":"https://openvibe.tips/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.tips/#site","url":"https://openvibe.tips/","name":"OpenVibe.Tips","description":"OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.tips/#page","url":"https://openvibe.tips/","name":"OpenVibe.Tips — Support the people you watch.","description":"OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.","isPartOf":{"@id":"https://openvibe.tips/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Tips","item":"https://openvibe.tips/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-hand-holding-heart" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="tips"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="tips"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Tips</span></h1>
<div class="tag">Support the people you watch.</div>
<p class="lead">OpenVibe.Tips is the tipping and alerts layer of the OpenVibe network: tips, donation goals, superchats, paid text-to-speech and media requests, with alert overlays for creators.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Tips" rel="noopener"><code>OpenVibers/OpenVibe.Tips</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Tips" rel="noopener"><code>OpenVibers/OpenVibe.Tips</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for the payments cutover to OpenVibe.Billing and a security review; tips keep working on OpenVibe.Live meanwhile. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Tips will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.tips/sitemap.xml b/dist/openvibe.tips/sitemap.xml
iindex ae8a5d7..550e3e5 100644
---- a/dist/openvibe.tips/sitemap.xml
++++ b/dist/openvibe.tips/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.tips/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.tips/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.tips/status.json b/dist/openvibe.tips/status.json
iindex eaa801c..f9ed67b 100644
---- a/dist/openvibe.tips/status.json
++++ b/dist/openvibe.tips/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Tips",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Tips",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "3fb582e",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "the payments cutover to OpenVibe.Billing and a security review; tips keep working on OpenVibe.Live meanwhile",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.trade/index.html b/dist/openvibe.trade/index.html
iindex 46dfbea..186669c 100644
---- a/dist/openvibe.trade/index.html
++++ b/dist/openvibe.trade/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.Trade — Watch, discuss, decide.">
<meta name="twitter:description" content="OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.trade/#site","url":"https://openvibe.trade/","name":"OpenVibe.Trade","description":"OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.trade/#page","url":"https://openvibe.trade/","name":"OpenVibe.Trade — Watch, discuss, decide.","description":"OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.","isPartOf":{"@id":"https://openvibe.trade/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Trade","item":"https://openvibe.trade/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.trade/#site","url":"https://openvibe.trade/","name":"OpenVibe.Trade","description":"OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.trade/#page","url":"https://openvibe.trade/","name":"OpenVibe.Trade — Watch, discuss, decide.","description":"OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.","isPartOf":{"@id":"https://openvibe.trade/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.Trade","item":"https://openvibe.trade/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-chart-line" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="trade"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="trade"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">Trade</span></h1>
<div class="tag">Watch, discuss, decide.</div>
<p class="lead">OpenVibe.Trade is the market intelligence room of the OpenVibe network: watchlists, alerts, summaries and community discussion for markets, collectibles and deals — information and tools, never advice.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Trade" rel="noopener"><code>OpenVibers/OpenVibe.Trade</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.Trade" rel="noopener"><code>OpenVibers/OpenVibe.Trade</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for a verified data source and editors adding the first instruments. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.Trade will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.trade/sitemap.xml b/dist/openvibe.trade/sitemap.xml
iindex 2b047b4..abcc87d 100644
---- a/dist/openvibe.trade/sitemap.xml
++++ b/dist/openvibe.trade/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.trade/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.trade/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.trade/status.json b/dist/openvibe.trade/status.json
iindex f8bc949..039eebd 100644
---- a/dist/openvibe.trade/status.json
++++ b/dist/openvibe.trade/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Trade",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Trade",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "62ea99c",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "a verified data source and editors adding the first instruments",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/openvibe.vip/index.html b/dist/openvibe.vip/index.html
iindex 4782720..9a65c0f 100644
---- a/dist/openvibe.vip/index.html
++++ b/dist/openvibe.vip/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="OpenVibe.VIP — Memberships, network-wide.">
<meta name="twitter:description" content="OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.vip/#site","url":"https://openvibe.vip/","name":"OpenVibe.VIP","description":"OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.vip/#page","url":"https://openvibe.vip/","name":"OpenVibe.VIP — Memberships, network-wide.","description":"OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.","isPartOf":{"@id":"https://openvibe.vip/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.VIP","item":"https://openvibe.vip/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://openvibe.vip/#site","url":"https://openvibe.vip/","name":"OpenVibe.VIP","description":"OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://openvibe.vip/#page","url":"https://openvibe.vip/","name":"OpenVibe.VIP — Memberships, network-wide.","description":"OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.","isPartOf":{"@id":"https://openvibe.vip/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"OpenVibe.VIP","item":"https://openvibe.vip/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-crown" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="vip"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="vip"></span> Part of the OpenVibe network · <b>in development</b></div>
<h1>OpenVibe<span class="d">.</span><span class="tld">VIP</span></h1>
<div class="tag">Memberships, network-wide.</div>
<p class="lead">OpenVibe.VIP is the membership layer of the OpenVibe network: creator memberships, channel subscriptions, VIP tiers and perks that unlock across Live, Community, Blog and more.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.VIP" rel="noopener"><code>OpenVibers/OpenVibe.VIP</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>in development</b> · <a href="https://github.com/OpenVibers/OpenVibe.VIP" rel="noopener"><code>OpenVibers/OpenVibe.VIP</code></a> is built and its service runs on the network's host, but it is not public yet; this page is a placeholder. The public launch is waiting for the payments cutover to OpenVibe.Billing; checkout stays closed until then. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What OpenVibe.VIP will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/openvibe.vip/sitemap.xml b/dist/openvibe.vip/sitemap.xml
iindex 3fb7f0c..f4fc259 100644
---- a/dist/openvibe.vip/sitemap.xml
++++ b/dist/openvibe.vip/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://openvibe.vip/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://openvibe.vip/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/openvibe.vip/status.json b/dist/openvibe.vip/status.json
iindex 9567c7f..3bcb4f8 100644
---- a/dist/openvibe.vip/status.json
++++ b/dist/openvibe.vip/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.VIP",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.VIP",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "service-running",
++ "service": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "statusCommit": "a675577",
++ "exposure": "internal",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": "the payments cutover to OpenVibe.Billing; checkout stays closed until then",
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/realtime.openvibe.network/index.html b/dist/realtime.openvibe.network/index.html
iindex 7526bec..7b8d323 100644
---- a/dist/realtime.openvibe.network/index.html
++++ b/dist/realtime.openvibe.network/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="realtime.openvibe.network — Authorized live updates, resumable.">
<meta name="twitter:description" content="realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://realtime.openvibe.network/#site","url":"https://realtime.openvibe.network/","name":"realtime.openvibe.network","description":"realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://realtime.openvibe.network/#page","url":"https://realtime.openvibe.network/","name":"realtime.openvibe.network — Authorized live updates, resumable.","description":"realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.","isPartOf":{"@id":"https://realtime.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"realtime.openvibe.network","item":"https://realtime.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://realtime.openvibe.network/#site","url":"https://realtime.openvibe.network/","name":"realtime.openvibe.network","description":"realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://realtime.openvibe.network/#page","url":"https://realtime.openvibe.network/","name":"realtime.openvibe.network — Authorized live updates, resumable.","description":"realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.","isPartOf":{"@id":"https://realtime.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"realtime.openvibe.network","item":"https://realtime.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-satellite-dish" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="realtime"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="realtime"></span> Part of the OpenVibe network · <b>closed</b></div>
<h1><span class="d">realtime</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">Authorized live updates, resumable.</div>
<p class="lead">realtime.openvibe.network will be the browser delivery plane for events: WebSocket and SSE subscriptions with cursors, presence and gap recovery, separate from the durable event store.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Realtime" rel="noopener"><code>OpenVibers/OpenVibe.Realtime</code></a> (charter only, no code yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>closed</b> · <a href="https://github.com/OpenVibers/OpenVibe.Realtime" rel="noopener"><code>OpenVibers/OpenVibe.Realtime</code></a> is closed, so no product launches here; this page is a placeholder. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What realtime.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/realtime.openvibe.network/sitemap.xml b/dist/realtime.openvibe.network/sitemap.xml
iindex 25fa635..b83bd54 100644
---- a/dist/realtime.openvibe.network/sitemap.xml
++++ b/dist/realtime.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://realtime.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://realtime.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/realtime.openvibe.network/status.json b/dist/realtime.openvibe.network/status.json
iindex 2356ffa..7ff809d 100644
---- a/dist/realtime.openvibe.network/status.json
++++ b/dist/realtime.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Realtime",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Realtime",
"repoExists": true,
-- "repoStage": "charter-only",
++ "repoStage": "closed",
++ "service": {
++ "stage": "closed",
++ "code": false,
++ "deployed": false,
++ "statusCommit": "d58c62c",
++ "exposure": "placeholder",
++ "publicOrigin": null
++ },
++ "launchWaitsFor": null,
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/dist/themes.openvibe.network/index.html b/dist/themes.openvibe.network/index.html
iindex 34cef42..983453e 100644
---- a/dist/themes.openvibe.network/index.html
++++ b/dist/themes.openvibe.network/index.html
@@@ -24,7 +24,7 @@
<meta name="twitter:title" content="themes.openvibe.network — Your look, on every site.">
<meta name="twitter:description" content="themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.">
<meta name="twitter:image" content="https://openvibe.network/assets/logo-512.png">
--<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://themes.openvibe.network/#site","url":"https://themes.openvibe.network/","name":"themes.openvibe.network","description":"themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://themes.openvibe.network/#page","url":"https://themes.openvibe.network/","name":"themes.openvibe.network — Your look, on every site.","description":"themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.","isPartOf":{"@id":"https://themes.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-23","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"themes.openvibe.network","item":"https://themes.openvibe.network/"}]}}]}</script>
++<script type="application/ld+json">{"@context":"https://schema.org","@graph":[{"@type":"WebSite","@id":"https://themes.openvibe.network/#site","url":"https://themes.openvibe.network/","name":"themes.openvibe.network","description":"themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.","inLanguage":"en","publisher":{"@type":"Organization","@id":"https://openvibe.network/#org","name":"OpenVibe","url":"https://openvibe.network/","logo":"https://openvibe.network/assets/logo-512.png","sameAs":["https://github.com/OpenVibers","https://discord.gg/M6MuRUaeJj"]},"isPartOf":{"@type":"WebSite","@id":"https://openvibe.network/#site","name":"OpenVibe.Network","url":"https://openvibe.network/"}},{"@type":"WebPage","@id":"https://themes.openvibe.network/#page","url":"https://themes.openvibe.network/","name":"themes.openvibe.network — Your look, on every site.","description":"themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.","isPartOf":{"@id":"https://themes.openvibe.network/#site"},"datePublished":"2026-09-17","dateModified":"2026-09-24","breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"OpenVibe","item":"https://openvibe.network/"},{"@type":"ListItem","position":2,"name":"themes.openvibe.network","item":"https://themes.openvibe.network/"}]}}]}</script>
<script>(function(){try{var raw=localStorage.getItem('ov_theme');if(!raw)return;var t=JSON.parse(raw),v=t&&t.variables;if(!v)return;var el=document.documentElement;for(var k in v)if(k.charAt(0)==='-')el.style.setProperty(k,v[k]);if(t.id)el.setAttribute('data-theme',t.id);}catch(_){}})();</script>
<script src="https://openvibe.network/shared/theme-loader.js" defer></script>
<link rel="preconnect" href="https://cdnjs.cloudflare.com" crossorigin>
@@@ -92,7 +92,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<main class="wrap">
<header class="hero">
<div class="mark"><i class="fa-solid fa-palette" aria-hidden="true"></i></div>
-- <div class="badge"><span class="ov-mark" data-size="16" data-variant="themes"></span> Part of the OpenVibe network · <b>opening soon</b></div>
++ <div class="badge"><span class="ov-mark" data-size="16" data-variant="themes"></span> Part of the OpenVibe network · <b>not routed yet</b></div>
<h1><span class="d">themes</span><span class="tld">.openvibe.network</span></h1>
<div class="tag">Your look, on every site.</div>
<p class="lead">themes.openvibe.network will be the theme catalog and API: built-in and community themes, previews, per-site overrides, import/export and the shared design tokens every OpenVibe site renders.</p>
@@@ -101,10 +101,10 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="btn" href="https://openvibe.network/#network"><i class="fa-solid fa-circle-nodes"></i> The whole network</a>
<a class="btn" href="https://discord.gg/M6MuRUaeJj" rel="noopener"><i class="fa-brands fa-discord"></i> Follow the build</a>
</div>
-- <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>coming soon</b> · this page is a placeholder, nothing here is live yet · home: <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> (a surface of that existing service; not split out yet) · <a href="/status.json">status.json</a></p>
++ <p class="status"><i class="fa-solid fa-clock" aria-hidden="true"></i> Status: <b>not routed yet</b> · <a href="https://github.com/OpenVibers/OpenVibe.Network" rel="noopener"><code>OpenVibers/OpenVibe.Network</code></a> is live at <a href="https://openvibe.network/">openvibe.network</a>; this subdomain is not routed to it yet, so it serves this placeholder. · as of 2026-09-24 · <a href="/status.json">status.json</a></p>
</header>
-- <section>
++ <section id="what">
<h2>What themes.openvibe.network will be</h2>
<p class="lead2">Same account, same themes, same navbar as every other OpenVibe site — built in the open, run by its community.</p>
<div class="grid">
@@@ -134,7 +134,7 @@ a.card:hover{transform:translateY(-3px);border-color:rgba(var(--site-rgb),.6);bo
<a class="card" href="https://openvibe.media"><div class="ic"><i class="fa-solid fa-photo-film" aria-hidden="true"></i></div><b>OpenVibe.Media</b><span>VODs, clips and files</span><span class="go">openvibe.media →</span></a>
<a class="card" href="https://openvibe.network"><div class="ic"><i class="fa-solid fa-circle-nodes" aria-hidden="true"></i></div><b>OpenVibe.Network</b><span>One account, every site</span><span class="go">openvibe.network →</span></a>
</div>
-- <h2 style="margin-top:28px;font-size:16px">More rooms opening</h2>
++ <h2 style="margin-top:28px;font-size:16px">Other OpenVibe domains, not open yet</h2>
<div class="rooms" style="margin-top:8px">
<a href="https://openvibe.chat/"><i class="fa-solid fa-comments" aria-hidden="true"></i>OpenVibe.Chat</a>
<a href="https://openvibe.news/"><i class="fa-solid fa-newspaper" aria-hidden="true"></i>OpenVibe.News</a>
ddiff --git a/dist/themes.openvibe.network/sitemap.xml b/dist/themes.openvibe.network/sitemap.xml
iindex f0ba8b0..ebc53dc 100644
---- a/dist/themes.openvibe.network/sitemap.xml
++++ b/dist/themes.openvibe.network/sitemap.xml
@@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
-- <url><loc>https://themes.openvibe.network/</loc><lastmod>2026-09-23</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
++ <url><loc>https://themes.openvibe.network/</loc><lastmod>2026-09-24</lastmod><changefreq>weekly</changefreq><priority>1.0</priority></url>
</urlset>
ddiff --git a/dist/themes.openvibe.network/status.json b/dist/themes.openvibe.network/status.json
iindex b2029fe..ec81861 100644
---- a/dist/themes.openvibe.network/status.json
++++ b/dist/themes.openvibe.network/status.json
@@@ -6,8 +6,18 @@
"plannedRepo": "OpenVibers/OpenVibe.Network",
"repoUrl": "https://github.com/OpenVibers/OpenVibe.Network",
"repoExists": true,
-- "repoStage": "existing-service",
++ "repoStage": "surface-of-a-live-service",
++ "service": {
++ "stage": null,
++ "code": null,
++ "deployed": null,
++ "statusCommit": null,
++ "exposure": "live",
++ "publicOrigin": "https://openvibe.network"
++ },
++ "launchWaitsFor": null,
++ "factsAsOf": "2026-09-24",
"network": "https://openvibe.network",
-- "updated": "2026-09-23",
-- "note": "Static placeholder served by OpenVibers/OpenVibe.Sites. Removed from sites.json in the same release that the real service takes over this domain."
++ "updated": "2026-09-24",
++ "note": "Static page served by OpenVibers/OpenVibe.Sites; service facts come from each repository's STATUS.json and the Network registry (facts.json). Removed from sites.json in the same release that the real service takes over this domain."
}
ddiff --git a/facts.json b/facts.json
nnew file mode 100644
iindex 0000000..f9f0e88
---- /dev/null
++++ b/facts.json
@@@ -0,0 +1,225 @@
++{
++ "note": "Facts the Sites placeholder copy is built from. Refresh with `node scripts/facts.js`, review the diff, run `node build.js`, commit both. Never edit by hand.",
++ "generated": "2026-09-24",
++ "sources": {
++ "status": "STATUS.json at HEAD of each OpenVibers checkout (commit recorded per repo)",
++ "registry": "https://openvibe.network/api/v1/registry/services (openvibe-contracts 0.33.0)"
++ },
++ "repos": {
++ "OpenRe.Stream": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "cc70a5a"
++ },
++ "registry": {
++ "id": "openre",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openre.stream"
++ }
++ },
++ "OpenVibe.AI": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "f034a9f"
++ },
++ "registry": {
++ "id": "ai",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": null,
++ "origin": null,
++ "planned_origin": "https://ai.openvibe.network"
++ }
++ },
++ "OpenVibe.Chat": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "fcc824a"
++ },
++ "registry": {
++ "id": "chat",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": null,
++ "origin": null,
++ "planned_origin": null
++ }
++ },
++ "OpenVibe.Coupons": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "93f333b"
++ },
++ "registry": {
++ "id": "coupons",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.coupons"
++ }
++ },
++ "OpenVibe.Deals": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "f453cb5"
++ },
++ "registry": {
++ "id": "deals",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.deals"
++ }
++ },
++ "OpenVibe.Host": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "2144ceb"
++ },
++ "registry": {
++ "id": "host",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.host"
++ }
++ },
++ "OpenVibe.Network": {
++ "status": null,
++ "registry": {
++ "id": "network",
++ "manifest_status": "stable",
++ "state": "live",
++ "public_site": "service",
++ "origin": "https://openvibe.network",
++ "planned_origin": null
++ }
++ },
++ "OpenVibe.News": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "c2c31b0"
++ },
++ "registry": {
++ "id": "news",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.news"
++ }
++ },
++ "OpenVibe.Realtime": {
++ "status": {
++ "stage": "closed",
++ "code": false,
++ "deployed": false,
++ "updated": "2026-09-23",
++ "commit": "d58c62c"
++ },
++ "registry": {
++ "id": "realtime",
++ "manifest_status": "placeholder",
++ "state": "placeholder",
++ "public_site": null,
++ "origin": null,
++ "planned_origin": null
++ }
++ },
++ "OpenVibe.Reviews": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "8905235"
++ },
++ "registry": {
++ "id": "reviews",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.reviews"
++ }
++ },
++ "OpenVibe.Tips": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "3fb582e"
++ },
++ "registry": {
++ "id": "tips",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.tips"
++ }
++ },
++ "OpenVibe.Trade": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "62ea99c"
++ },
++ "registry": {
++ "id": "trade",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.trade"
++ }
++ },
++ "OpenVibe.VIP": {
++ "status": {
++ "stage": "alpha",
++ "code": true,
++ "deployed": true,
++ "updated": "2026-09-23",
++ "commit": "a675577"
++ },
++ "registry": {
++ "id": "vip",
++ "manifest_status": "alpha",
++ "state": "internal",
++ "public_site": "placeholder",
++ "origin": null,
++ "planned_origin": "https://openvibe.vip"
++ }
++ }
++ }
++}
ddiff --git a/scripts/facts.js b/scripts/facts.js
nnew file mode 100644
iindex 0000000..ecc1a36
---- /dev/null
++++ b/scripts/facts.js
@@@ -0,0 +1,97 @@
++#!/usr/bin/env node
++'use strict';
++/**
++ * Refresh facts.json: what is true about each repository a Sites page names, so the placeholder
++ * copy comes from facts and never from a hand-kept list (roadmap §32.7 launch rule, §32.10).
++ *
++ * node scripts/facts.js → STATUS.json of every repo + Network's registry exposure
++ * node scripts/facts.js --offline → STATUS.json only; keeps the registry rows already in facts.json
++ *
++ * Two sources, both recorded with where they came from:
++ * - each repository's committed STATUS.json (`git show HEAD:STATUS.json` in the sibling OpenVibers
++ * checkout, so nobody's uncommitted edit leaks in), with the commit it was read at;
++ * - Network's registry exposure (GET /api/v1/registry/services): whether each service's public
++ * domain serves it (live), it runs on the host's loopback only (internal), or nothing runs.
++ *
++ * build.js reads only the committed facts.json, so a build is reproducible (CI has no sibling
++ * checkouts and no network). Review the diff, rebuild (node build.js), commit both.
++ */
++const fs = require('fs');
++const path = require('path');
++const { execFileSync } = require('child_process');
++
++const ROOT = path.join(__dirname, '..');
++const REPOS_DIR = process.env.OPENVIBERS_DIR || path.join(ROOT, '..');
++const REGISTRY = process.env.REGISTRY_URL || 'https://openvibe.network/api/v1/registry/services';
++const OUT = path.join(ROOT, 'facts.json');
++const offline = process.argv.includes('--offline');
++
++const catalog = JSON.parse(fs.readFileSync(path.join(ROOT, 'sites.json'), 'utf8'));
++const previous = fs.existsSync(OUT) ? JSON.parse(fs.readFileSync(OUT, 'utf8')) : { repos: {} };
++
++// A STATUS.json says "deployed" as a boolean, as prose ("loopback only, not launched") or only in
++// its "deployment" sentence ("Deployed internally, not launched: …"; "none of its own: …").
++function deployedOf(s) {
++ const says = (v) => !/^(no|not|none)\b/i.test(v.trim());
++ if (typeof s.deployed === 'boolean') return s.deployed;
++ if (typeof s.deployed === 'string') return says(s.deployed);
++ if (typeof s.deployment === 'string') return says(s.deployment);
++ return null;
++}
++
++function statusOf(repo) {
++ const dir = path.join(REPOS_DIR, repo);
++ if (!fs.existsSync(path.join(dir, '.git'))) return { missing: `no checkout at ${dir}` };
++ let raw;
++ try { raw = execFileSync('git', ['-C', dir, 'show', 'HEAD:STATUS.json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] }); } catch { return null; }
++ const s = JSON.parse(raw);
++ const commit = execFileSync('git', ['-C', dir, 'rev-parse', '--short=7', 'HEAD'], { encoding: 'utf8' }).trim();
++ return { stage: s.stage || null, code: s.code === true, deployed: deployedOf(s), updated: s.updated || null, commit };
++}
++
++async function registryRows() {
++ const res = await fetch(REGISTRY, { headers: { accept: 'application/json' } });
++ if (!res.ok) throw new Error(`${REGISTRY} answered ${res.status}`);
++ const body = await res.json();
++ const byRepo = {};
++ for (const m of body.services) {
++ const repo = String(m.repository || '').replace(/^OpenVibers\//, '');
++ if (!repo) continue;
++ const e = m.exposure || {};
++ const origin = e.state === 'live' && e.public_site === 'service' ? m.publicOrigin || null : null;
++ byRepo[repo] = { id: m.id, manifest_status: m.status, state: e.state || 'unknown', public_site: e.public_site == null ? null : e.public_site, origin, planned_origin: origin ? null : m.publicOrigin || null };
++ }
++ return { contracts_version: body.contracts_version || null, byRepo };
++}
++
++(async () => {
++ const repos = [...new Set(catalog.sites.map(s => s.plannedRepo).filter(Boolean))].sort();
++ const reg = offline ? null : await registryRows();
++ const out = {
++ note: 'Facts the Sites placeholder copy is built from. Refresh with `node scripts/facts.js`, review the diff, run `node build.js`, commit both. Never edit by hand.',
++ generated: new Date().toISOString().slice(0, 10),
++ sources: {
++ status: 'STATUS.json at HEAD of each OpenVibers checkout (commit recorded per repo)',
++ registry: offline ? (previous.sources && previous.sources.registry) || null : `${REGISTRY} (openvibe-contracts ${reg.contracts_version})`,
++ },
++ repos: {},
++ };
++ for (const repo of repos) {
++ const status = statusOf(repo);
++ if (status && status.missing) {
++ // No checkout here: keep what the last refresh saw rather than inventing anything.
++ if (!previous.repos[repo]) throw new Error(`${repo}: ${status.missing} and no earlier fact to keep`);
++ console.warn(`[facts] ${repo}: ${status.missing}; kept the previous STATUS row`);
++ out.repos[repo] = { ...previous.repos[repo] };
++ } else {
++ out.repos[repo] = { status };
++ }
++ const registry = offline ? (previous.repos[repo] || {}).registry || null : reg.byRepo[repo] || null;
++ out.repos[repo].registry = registry;
++ }
++ fs.writeFileSync(OUT, JSON.stringify(out, null, 2) + '\n');
++ for (const [repo, f] of Object.entries(out.repos)) {
++ const s = f.status || {}; const r = f.registry || {};
++ console.log(`${repo.padEnd(18)} stage=${s.stage} code=${s.code} deployed=${s.deployed} registry=${r.state || '-'}${r.public_site ? `/${r.public_site}` : ''} @${s.commit || '-'}`);
++ }
++})().catch((e) => { console.error(`[facts] ${e.message}`); process.exit(1); });
ddiff --git a/sites.json b/sites.json
iindex 160da5d..742e222 100644
---- a/sites.json
++++ b/sites.json
@@@ -57,7 +57,7 @@
"icon": "fa-comments",
"accent": "#a78bfa",
"tagline": "One chat for the whole network.",
-- "description": "OpenVibe.Chat is the communication layer of the OpenVibe network: global rooms, stream chat, direct messages, group rooms, voice calls and text-to-speech — one identity, every conversation.",
++ "description": "OpenVibe.Chat is the chat service of the OpenVibe network. It already runs the chat on OpenVibe.Live: global and stream chat, direct messages and text-to-speech. openvibe.chat is planned as its own home: rooms that span every OpenVibe site, group rooms and voice, one identity for every conversation.",
"pillars": [
[
"Global rooms",
@@@ -89,8 +89,8 @@
]
],
"keywords": "openvibe chat, community chat, voice rooms, direct messages, free speech chat",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Chat"
++ "plannedRepo": "OpenVibe.Chat",
++ "launch": "its own web client at this address; the service already runs the chat on OpenVibe.Live"
},
{
"domain": "openvibe.news",
@@@ -126,8 +126,8 @@
]
],
"keywords": "openvibe news, transparent news, news aggregation, multiple perspectives",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.News"
++ "plannedRepo": "OpenVibe.News",
++ "launch": "a person to verify a news source's terms and an editor to publish the first reviewed story"
},
{
"domain": "openvibe.reviews",
@@@ -163,8 +163,8 @@
]
],
"keywords": "openvibe reviews, review aggregation, honest reviews",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Reviews"
++ "plannedRepo": "OpenVibe.Reviews",
++ "launch": "a person to verify a review source's terms and an editor to publish the first reviewed summary"
},
{
"domain": "openvibe.tips",
@@@ -200,8 +200,8 @@
]
],
"keywords": "openvibe tips, tip streamers, donation alerts, superchat",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Tips"
++ "plannedRepo": "OpenVibe.Tips",
++ "launch": "the payments cutover to OpenVibe.Billing and a security review; tips keep working on OpenVibe.Live meanwhile"
},
{
"domain": "openvibe.vip",
@@@ -237,8 +237,8 @@
]
],
"keywords": "openvibe vip, creator memberships, subscriptions",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.VIP"
++ "plannedRepo": "OpenVibe.VIP",
++ "launch": "the payments cutover to OpenVibe.Billing; checkout stays closed until then"
},
{
"domain": "openvibe.trade",
@@@ -274,8 +274,8 @@
]
],
"keywords": "openvibe trade, watchlists, market alerts, community trading tools",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Trade"
++ "plannedRepo": "OpenVibe.Trade",
++ "launch": "a verified data source and editors adding the first instruments"
},
{
"domain": "openvibe.host",
@@@ -311,8 +311,8 @@
]
],
"keywords": "openvibe host, hosting, deployment, self-hosting openvibe",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Host"
++ "plannedRepo": "OpenVibe.Host",
++ "launch": "the owner's go on its launch checklist"
},
{
"domain": "openvibe.deals",
@@@ -348,8 +348,8 @@
]
],
"keywords": "openvibe deals, community deals, deal alerts",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Deals"
++ "plannedRepo": "OpenVibe.Deals",
++ "launch": "a person to verify a deals source's terms and switch it on"
},
{
"domain": "openvibe.coupons",
@@@ -385,8 +385,8 @@
]
],
"keywords": "openvibe coupons, coupon codes, community coupons",
-- "stage": "placeholder",
-- "plannedRepo": "OpenVibe.Coupons"
++ "plannedRepo": "OpenVibe.Coupons",
++ "launch": "a person to verify a coupons source's terms and switch it on"
},
{
"domain": "openre.stream",
@@@ -396,15 +396,15 @@
"icon": "fa-satellite-dish",
"accent": "#ef4444",
"tagline": "Ingest and restream, in the open.",
-- "description": "OpenRe.Stream is the ingest and restream infrastructure behind OpenVibe.Live: RTMP, WHIP and SRT ingest, stream lifecycle, restream destinations and output status — the plumbing, documented and open.",
++ "description": "OpenRe.Stream is the ingest and restream service split out of OpenVibe.Live: RTMP ingest with stream keys and lifecycle, and restreaming to RTMP, RTMPS and SRT destinations, with WHIP to follow. Broadcasters still go live through OpenVibe.Live until their stream moves over.",
"pillars": [
[
"Ingest",
-- "RTMP, WHIP/WebRTC and SRT, with keys and lifecycle in one place."
++ "RTMP ingest with keys and lifecycle in one place; WHIP/WebRTC and SRT ingest to follow."
],
[
"Restream",
-- "Twitch, YouTube, Kick, SRT and RobotStreamer destinations."
++ "Twitch, YouTube, Kick and any RTMP, RTMPS or SRT destination."
],
[
"Status",
@@@ -423,13 +423,13 @@
],
[
"Restreaming docs",
-- "https://github.com/OpenVibers/OpenVibe.Live/blob/main/docs/restreaming.md",
++ "https://openvibe.live/docs/restreaming",
"How the restream paths work."
]
],
"keywords": "openre stream, rtmp ingest, whip, srt, restream, open source streaming infrastructure",
-- "stage": "placeholder",
-- "plannedRepo": "OpenRe.Stream"
++ "plannedRepo": "OpenRe.Stream",
++ "launch": "the stream slots to move from OpenVibe.Live's ingest to OpenRe.Stream, one at a time; no stream uses it yet"
},
{
"domain": "auth.openvibe.network",
@@@ -442,7 +442,6 @@
"name": "auth.openvibe.network",
"icon": "fa-key",
"accent": "#60a5fa",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.Network",
"legalProfile": "account",
"tagline": "Sign in, once, for the whole network.",
@@@ -473,8 +472,8 @@
],
[
"OIDC discovery",
-- "https://openvibe.network/.well-known/openid-configuration",
-- "The OpenID configuration is already published."
++ "https://openvibe.network/oauth/.well-known/openid-configuration",
++ "The OpenID configuration Network publishes today."
]
],
"keywords": "openvibe auth, openvibe network auth, openvibe platform"
@@@ -490,11 +489,10 @@
"name": "api.openvibe.network",
"icon": "fa-plug",
"accent": "#22d3ee",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.Network",
"legalProfile": "info",
"tagline": "The network, machine-readable.",
-- "description": "api.openvibe.network will expose the ecosystem registry: services, capabilities, event topics, namespaces and releases as versioned, documented APIs backed by the OpenVibe contracts.",
++ "description": "api.openvibe.network is the planned home of the network's public APIs. The ecosystem registry (services, capabilities, event topics, namespaces and releases, backed by the OpenVibe contracts) already answers on openvibe.network; this subdomain is not routed to it yet.",
"pillars": [
[
"Service registry",
@@@ -515,14 +513,19 @@
],
"meanwhile": [
[
-- "Developer pages",
-- "https://openvibe.network/developers",
-- "Current developer documentation on openvibe.network."
++ "Registry API",
++ "https://openvibe.network/api/v1/registry",
++ "Services, capabilities, namespaces, event topics and releases, as JSON."
],
[
-- "Streaming API docs",
-- "https://openvibe.live/documentation",
-- "Ingest, WHIP and playback docs live on OpenVibe.Live."
++ "Service discovery",
++ "https://openvibe.network/.well-known/openvibe",
++ "The issuer, token and key endpoints, and where each service answers."
++ ],
++ [
++ "Developer portal",
++ "https://openvibe.codes",
++ "Projects, apps and credentials, contract and SDK docs on OpenVibe.Codes."
]
],
"keywords": "openvibe api, openvibe network api, openvibe platform"
@@@ -538,7 +541,6 @@
"name": "admin.openvibe.network",
"icon": "fa-shield-halved",
"accent": "#f59e0b",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.Network",
"legalProfile": "account",
"tagline": "One operator console for every service.",
@@@ -581,7 +583,6 @@
"name": "themes.openvibe.network",
"icon": "fa-palette",
"accent": "#a78bfa",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.Network",
"legalProfile": "info",
"tagline": "Your look, on every site.",
@@@ -624,7 +625,6 @@
"name": "realtime.openvibe.network",
"icon": "fa-satellite-dish",
"accent": "#34d399",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.Realtime",
"legalProfile": "info",
"tagline": "Authorized live updates, resumable.",
@@@ -667,11 +667,11 @@
"name": "ai.openvibe.network",
"icon": "fa-robot",
"accent": "#c084fc",
-- "stage": "placeholder",
"plannedRepo": "OpenVibe.AI",
++ "launch": "a public API with its own access rules; today only other OpenVibe services call it",
"legalProfile": "info",
"tagline": "AI as a service, for every OpenVibe product.",
-- "description": "ai.openvibe.network will be the shared AI layer: providers and models, routing, prompt templates, workflows, runs, citations, caching and quotas, used by Live, Wiki, News and the rest instead of each product wiring its own.",
++ "description": "OpenVibe.AI is the shared AI layer of the OpenVibe network: providers and models, routing, prompt templates, workflows, runs and quotas, so each product stops wiring its own. It runs today as an internal service that OpenVibe.Live and OpenVibe.Network call; ai.openvibe.network has no public page or API yet.",
"pillars": [
[
"Providers & routing",
@@@ -692,9 +692,9 @@
],
"meanwhile": [
[
-- "AI clips and captions",
++ "AI on OpenVibe.Live",
"https://openvibe.live",
-- "Live captions, translation and AI moments already run on OpenVibe.Live."
++ "Live's AI moments, recaps, summaries and translations run through OpenVibe.AI; captions still run inside Live."
]
],
"keywords": "openvibe ai, openvibe network ai, openvibe platform"
ddiff --git a/test/build.test.js b/test/build.test.js
iindex 227573a..7f65d0f 100644
---- a/test/build.test.js
++++ b/test/build.test.js
@@@ -36,6 +36,48 @@ for (const site of catalog.sites) {
assert.ok(conf.includes(`root /opt/openvibe.sites/dist/${d};`), `${d}: vhost root`);
}
++// Labels come from facts (facts.json: each repository's STATUS.json + the Network registry), never a
++// hand-kept list: a product whose code exists is never "charter only", and a product that runs says
++// what its public launch waits for (roadmap §32.7 launch rule, §32.10).
++const facts = JSON.parse(read('facts.json'));
++const NO_CODE = /charter only|no code yet/i;
++for (const site of catalog.sites) {
++ if (!site.plannedRepo) continue;
++ const d = site.domain;
++ const f = facts.repos[site.plannedRepo];
++ assert.ok(f, `${d}: facts.json has a row for ${site.plannedRepo} (node scripts/facts.js)`);
++ const html = read(`dist/${d}/index.html`);
++ const status = JSON.parse(read(`dist/${d}/status.json`));
++ const st = f.status || {}; const rg = f.registry || {};
++ const hasCode = st.code === true || ['live', 'internal'].includes(rg.state);
++ if (hasCode) {
++ assert.doesNotMatch(html, NO_CODE, `${d}: ${site.plannedRepo} has code, so the page never says "charter only, no code yet"`);
++ assert.notStrictEqual(status.repoStage, 'charter-only', `${d}: status.json repoStage`);
++ }
++ const runs = rg.state === 'internal' || (st.code === true && st.deployed === true);
++ if (runs && st.stage !== 'closed' && rg.state !== 'live') {
++ assert.ok(site.launch, `${d}: the service runs, so sites.json says what its public launch waits for ("launch")`);
++ assert.ok(html.includes(`The public launch is waiting for ${site.launch.replace(/'/g, '&#39;')}.`), `${d}: the page says what the launch waits for`);
++ assert.match(html, /in development/, `${d}: labelled in development`);
++ assert.strictEqual(status.repoStage, 'service-running', `${d}: status.json repoStage`);
++ assert.strictEqual(status.launchWaitsFor, site.launch, `${d}: status.json launchWaitsFor`);
++ }
++ if (rg.state === 'live' && rg.public_site === 'service') {
++ assert.ok(html.includes(`href="${rg.origin}/"`), `${d}: links the live service ${rg.origin}`);
++ assert.strictEqual(status.repoStage, 'surface-of-a-live-service', `${d}: status.json repoStage`);
++ }
++}
++// facts.json is current with the sibling checkouts when they are here (CI has none; skip there).
++const REPOS_DIR = process.env.OPENVIBERS_DIR || path.join(ROOT, '..');
++for (const [repo, f] of Object.entries(facts.repos)) {
++ const dir = path.join(REPOS_DIR, repo);
++ if (!fs.existsSync(path.join(dir, '.git')) || !f.status) continue;
++ let s;
++ try { s = JSON.parse(execFileSync('git', ['-C', dir, 'show', 'HEAD:STATUS.json'], { encoding: 'utf8', stdio: ['ignore', 'pipe', 'ignore'] })); } catch { continue; }
++ assert.strictEqual(f.status.stage, s.stage || null, `${repo}: STATUS.json stage changed; run node scripts/facts.js and rebuild`);
++ assert.strictEqual(f.status.code, s.code === true, `${repo}: STATUS.json code changed; run node scripts/facts.js and rebuild`);
++}
++
// A domain that a real service answers is never also a placeholder here (roadmap 7.2 rule 8).
const LIVE_SERVICES = ['events.openvibe.network', 'billing.openvibe.network', 'openvibe.wiki', 'openvibe.blog', 'openvibe.codes', 'openvibe.community', 'openvibe.live', 'openvibe.media', 'openvibe.tools', 'openvibe.network'];
for (const d of LIVE_SERVICES) {