openvibers/openvibe.ai Commits

AI: the retired ai.openvibe.network vhost is deleted (plan T6) (#40)

OP OpenVibers committed 10 Oct 2026 · f8b45213dd · 7 files, +12 −50

Plan T6: "the ai.openvibe.network redirect removed once nothing calls it." Nothing calls it. In nginx's logs the last service call (a `/release.json` poller from the host) was 2026-10-02 00:13; since then only crawlers have reached the old host.

This deletes `deploy/nginx/ai.openvibe.network.conf` (the 301 redirect vhost) and updates the README, STATUS.json (its domain line still described the Sites placeholder), `.env.example`, the ai.openvibe.services vhost header and the proposal copy of the manifest. `test/home.test.js` asserts the retired vhost is gone; 10/10 pass. Contracts 0.127.0 already dropped the domain from the registry. After the deploy, the vhost comes out of nginx on the host.

Changes

ddiff --git a/.env.example b/.env.example
iindex 4bf18f0..19a910b 100644
---- a/.env.example
++++ b/.env.example
@@@ -1,6 +1,6 @@
# ═══════════════════════════════════════════════════════════════
# ai.openvibe.services — OpenVibe.AI Environment Configuration
--# The public home and API origin (ai.openvibe.network answers 301 to it). BASE_URL defaults to it in production.
++# The public home and API origin. BASE_URL defaults to it in production.
# Copy to .env and fill in values. In production this lives at /etc/openvibe/ai.env (0600).
# Secrets are read by NAME only (providers store 'env:NAME' references); nothing logs or returns them.
# ═══════════════════════════════════════════════════════════════
ddiff --git a/README.md b/README.md
iindex 0fcd434..1f06e50 100644
---- a/README.md
++++ b/README.md
@@@ -6,7 +6,7 @@
production use: OpenVibe.Live runs with `AI_SERVICE=remote` and Network's footer copy runs
`network.site_copy` here. Public since 2026-10-07 at [ai.openvibe.services](https://ai.openvibe.services):
the home (`server/home.js`), `/stats` and the developer-app API (`ai.app.run`).
--**Domain:** `ai.openvibe.services` (`ai.openvibe.network` answers 301 to it) · **Port:** 4700 · **Unit:** `openvibe-ai.service`
++**Domain:** `ai.openvibe.services` · **Port:** 4700 · **Unit:** `openvibe-ai.service`
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §12.1, §12.13, §15.14, §33, §34.
**License:** AGPL-3.0 (same as every OpenVibe service).
@@@ -445,7 +445,7 @@ principal `ai`. The vhost `deploy/nginx/ai.openvibe.services.conf` (on the `*.op
serves the home, `/stats`, `/shared/*`, `/robots.txt`, `/sitemap.xml`, `/llms.txt`, health/ready, the operator
console `/console` with its sign-in `/auth/`, and exactly the developer-app routes (the six operations by POST,
`/api/v1/runs/:id` by GET, rate-limited per address); every other `/api/` path and `/metrics` stay host-local.
--`deploy/nginx/ai.openvibe.network.conf` answers 301 to the same path on ai.openvibe.services. The console needs
++The old `ai.openvibe.network` address was retired on 2026-10-10. The console needs
`AI_CONSOLE_SESSION_SECRET` (32+ random characters) and `OV_OAUTH_CLIENT_SECRET` in the env file (without them it
answers 503 in production); Network client `ai` lists `https://ai.openvibe.services/auth/callback`.
ddiff --git a/STATUS.json b/STATUS.json
iindex 07019ea..773073d 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -6,7 +6,7 @@
"plan": "OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026)",
"runtime": "node 22, express, postgresql",
"port": 4700,
-- "domain": "ai.openvibe.network still serves the OpenVibe.Sites placeholder; the service runs on openvibe-ovh (/opt/openvibe.ai, unit openvibe-ai) on 127.0.0.1:4700, loopback only, used by OpenVibe.Live and OpenVibe.Network",
++ "domain": "ai.openvibe.services (the old ai.openvibe.network address was retired on 2026-10-10); the service runs on openvibe-ovh (/opt/openvibe.ai, unit openvibe-ai) on 127.0.0.1:4700 behind nginx; OpenVibe.Live and OpenVibe.Network call it on loopback",
"contracts": "openvibe-contracts v0.126.0",
"sdk": "openvibe-sdk v0.35.0",
"shared": "openvibe-shared v2.20.3",
ddiff --git a/deploy/nginx/ai.openvibe.network.conf b/deploy/nginx/ai.openvibe.network.conf
ddeleted file mode 100644
iindex 13c0f5b..0000000
---- a/deploy/nginx/ai.openvibe.network.conf
++++ /dev/null
@@@ -1,35 +0,0 @@
--## ═══════════════════════════════════════════════════════════════
--## ai.openvibe.network — Nginx Configuration (REFERENCE)
--##
--## Deployed to /etc/nginx/sites-available/ai.openvibe.network.conf — keep them in sync, and reload
--## nginx after changing it. OpenVibe.AI's public origin is https://ai.openvibe.services
--## (deploy/nginx/ai.openvibe.services.conf); this name answers 301 to the same path there.
--## Services on this host never come through here: they call 127.0.0.1:4700 directly.
--## ═══════════════════════════════════════════════════════════════
--
--server {
-- listen 80;
-- listen [::]:80;
-- server_name ai.openvibe.network;
--
-- location /.well-known/acme-challenge/ { root /var/www/certbot; }
-- location / { return 301 https://ai.openvibe.services$request_uri; }
--}
--
--server {
-- listen 443 ssl;
-- listen [::]:443 ssl;
-- http2 on;
-- server_name ai.openvibe.network;
--
-- ssl_certificate /etc/letsencrypt/live/openvibe.network/fullchain.pem;
-- ssl_certificate_key /etc/letsencrypt/live/openvibe.network/privkey.pem;
-- ssl_protocols TLSv1.2 TLSv1.3;
--
-- access_log /var/log/nginx/ai.openvibe.network.access.log;
-- error_log /var/log/nginx/ai.openvibe.network.error.log;
--
-- add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
--
-- location / { return 301 https://ai.openvibe.services$request_uri; }
--}
ddiff --git a/deploy/nginx/ai.openvibe.services.conf b/deploy/nginx/ai.openvibe.services.conf
iindex 5fc1ee5..abed85d 100644
---- a/deploy/nginx/ai.openvibe.services.conf
++++ b/deploy/nginx/ai.openvibe.services.conf
@@@ -4,8 +4,8 @@
## Deployed to /etc/nginx/sites-available/ai.openvibe.services.conf — keep them in sync, and reload
## nginx after changing it. It uses the *.openvibe.services certificate the host already holds
## (/etc/letsencrypt/live/openvibe.services/); installed in place of the OpenVibe.Sites placeholder
--## vhost of the same name, it replaces that placeholder. ai.openvibe.network (its own vhost) answers
--## 301 to here.
++## vhost of the same name, it replaces that placeholder. The old ai.openvibe.network address was retired on
++## 2026-10-10 (its last service caller stopped on 10-02).
##
## The Node service (port 4700, systemd unit openvibe-ai) serves:
## / the product home for a browser (server/home.js), the text API index for anything else
ddiff --git a/docs/capabilities-proposal/service-manifest.ai.json b/docs/capabilities-proposal/service-manifest.ai.json
iindex 6381751..36d2545 100644
---- a/docs/capabilities-proposal/service-manifest.ai.json
++++ b/docs/capabilities-proposal/service-manifest.ai.json
@@@ -8,8 +8,7 @@
"status": "alpha",
"repository": "OpenVibers/OpenVibe.AI",
"domains": [
-- "ai.openvibe.services",
-- "ai.openvibe.network"
++ "ai.openvibe.services"
],
"publicOrigin": "https://ai.openvibe.services",
"health": "/api/health",
@@@ -77,14 +76,14 @@
],
"window": "automatic only while ovhost waits for readiness after the restart (30 s in host.example.json); manual afterwards, as long as no blocker applies",
"blockers": {
-- "none": "the schema code only adds (CREATE \u2026 IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
++ "none": "the schema code only adds (CREATE … IF NOT EXISTS, ADD COLUMN; no DROP, RENAME or table rebuild), which an older release ignores"
}
},
"contracts": {
"range": ">=0.6.0 <1.0.0"
},
"leases": {
-- "none": "no claims: one process owns ai.db (better-sqlite3, single writer); a run is taken with a compare-and-set on its status (queued \u2192 running)"
++ "none": "no claims: one process owns ai.db (better-sqlite3, single writer); a run is taken with a compare-and-set on its status (queued → running)"
}
},
"notes": "Providers, models, routing profiles, versioned prompt templates and workflows, runs, request logs, citations, scoped cache, quotas and audit. Workflow output is a draft/evidence package attributed to workflow + model + run. ai.run.queued|succeeded|failed|cached have payload contracts (v0.30.0, status planned): AI publishes them once its Events client is wired in; it publishes none today. ai.run.create takes ai.run-request@1 and returns ai.run@1."
ddiff --git a/test/home.test.js b/test/home.test.js
iindex 35f1292..6bf2589 100644
---- a/test/home.test.js
++++ b/test/home.test.js
@@@ -2,7 +2,7 @@
// The public home (plan T6: AI as a developer product). ai.openvibe.services renders server/home.js for a
// browser and keeps the text/plain API index for curl and API clients, serves the pinned OpenVibe Frame at
// /shared, and answers robots.txt, sitemap.xml and llms.txt. The vhosts: the developer-app routes are the only
--// API the public vhost proxies, and ai.openvibe.network is a 301 to the product origin.
++// API the public vhost proxies, and the old ai.openvibe.network address is retired (no vhost of its own).
const assert = require('assert');
const fs = require('fs');
const path = require('path');
@@@ -87,10 +87,8 @@ t.test('the public vhost proxies the home, its files and exactly the developer-a
assert.ok(!conf.includes('$proxy_add_x_forwarded_for'));
});
--t.test('ai.openvibe.network answers 301 to the same path on ai.openvibe.services, and proxies nothing', () => {
-- const conf = active('ai.openvibe.network.conf');
-- assert.ok(!conf.includes('proxy_pass'), 'nothing is served under the old name');
-- assert.strictEqual((conf.match(/return 301 https:\/\/ai\.openvibe\.services\$request_uri;/g) || []).length, 2, 'HTTP and HTTPS');
++t.test('the retired ai.openvibe.network address has no vhost (plan T6, 2026-10-10)', () => {
++ assert.ok(!fs.existsSync(path.join(__dirname, '..', 'deploy', 'nginx', 'ai.openvibe.network.conf')));
});
t.test('the CSPs let Cloudflare Web Analytics load and report (it injects its beacon on this zone)', async () => {