openvibers/openvibe.contracts Commits

v0.66.0: incidents and maintenance on the status page (roadmap WS-N task 12). network.status-incident@1, network.status-incident-list@1 (public: active and the last 30 days) and network.status-incident-request@1 (open, or add an update), and the capability network.status.incident (internal; staff admins and the Host principal: ovhost incident / maintenance).

OP OpenVibers committed 26 Sept 2026 · 75b7411604 · 45 files, +865 −52


Changes

ddiff --git a/CHANGELOG.md b/CHANGELOG.md
iindex 246b547f..50554c5e 100644
---- a/CHANGELOG.md
++++ b/CHANGELOG.md
@@@ -6,6 +6,13 @@ the notes were in the tag and commit messages (`git tag -n1`).
## Unreleased
++## 0.66.0 — 2026-09-26
++
++**Incidents and maintenance on the status page** (roadmap WS-N task 12).
++- **New schemas** `network.status-incident@1` (an incident or maintenance window: kind, title, severity, state, services, start and end, updates), `network.status-incident-list@1` (public: `active` and the last 30 days' `recent`) and `network.status-incident-request@1` (open one, or add an update).
++- **New capability** `network.status.incident` (internal, never for apps). It covers POST /api/v1/status/incidents and /:id/updates, for staff admins and the Host principal (`ovhost incident`, `ovhost maintenance`).
++- ADR-032 (containers for platform services) is accepted: services stay systemd units.
++
## 0.65.0 — 2026-09-26
**The follow graph on Network** (roadmap WS-E task 4, ADR-030).
ddiff --git a/contracts/catalog.json b/contracts/catalog.json
iindex 6cde3738..666dd0cd 100644
---- a/contracts/catalog.json
++++ b/contracts/catalog.json
@@@ -2593,6 +2593,33 @@
"status": "active",
"adr": "ADR-014"
},
++ {
++ "id": "network.status-incident",
++ "version": "1.0.0",
++ "owner": "network",
++ "schema": "network/status-incident.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "network.status-incident-list",
++ "version": "1.0.0",
++ "owner": "network",
++ "schema": "network/status-incident-list.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
++ {
++ "id": "network.status-incident-request",
++ "version": "1.0.0",
++ "owner": "network",
++ "schema": "network/status-incident-request.v1.json",
++ "visibility": "first-party",
++ "compatibility": "backward",
++ "status": "active"
++ },
{
"id": "network.staff-list-result",
"version": "1.0.0",
ddiff --git a/contracts/network/status-incident-list.v1.json b/contracts/network/status-incident-list.v1.json
nnew file mode 100644
iindex 00000000..7571d9ed
---- /dev/null
++++ b/contracts/network/status-incident-list.v1.json
@@@ -0,0 +1,13 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident-list.v1.json",
++ "title": "NetworkStatusIncidentList",
++ "description": "network.status-incident-list@1: GET /api/v1/status/incidents on OpenVibe.Network (public): open incidents and current or upcoming maintenance windows (`active`), and those closed in the last 30 days (`recent`), newest first.",
++ "type": "object",
++ "required": ["active", "recent"],
++ "additionalProperties": false,
++ "properties": {
++ "active": { "type": "array", "items": { "$ref": "./status-incident.v1.json" } },
++ "recent": { "type": "array", "items": { "$ref": "./status-incident.v1.json" } }
++ }
++}
ddiff --git a/contracts/network/status-incident-request.v1.json b/contracts/network/status-incident-request.v1.json
nnew file mode 100644
iindex 00000000..3eb5eb93
---- /dev/null
++++ b/contracts/network/status-incident-request.v1.json
@@@ -0,0 +1,33 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident-request.v1.json",
++ "title": "NetworkStatusIncidentRequest",
++ "description": "network.status-incident-request@1 (capability network.status.incident; staff admins or the Host principal). POST /api/v1/status/incidents opens one: { kind, title, severity? (incidents), services, message, starts_at? (default now), ends_at? (a maintenance window's planned end), state? (default investigating, or scheduled for maintenance) }. POST /api/v1/status/incidents/:id/updates adds an update: { state, message, ends_at? }. A resolved incident or a completed window is closed; updates to it are refused.",
++ "oneOf": [
++ {
++ "type": "object",
++ "required": ["kind", "title", "services", "message"],
++ "additionalProperties": false,
++ "properties": {
++ "kind": { "enum": ["incident", "maintenance"] },
++ "title": { "type": "string", "minLength": 3, "maxLength": 140 },
++ "severity": { "enum": ["minor", "major", "critical"] },
++ "state": { "enum": ["investigating", "identified", "monitoring", "scheduled", "in_progress"] },
++ "services": { "type": "array", "minItems": 1, "maxItems": 40, "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" } },
++ "message": { "type": "string", "minLength": 1, "maxLength": 2000 },
++ "starts_at": { "type": "string", "format": "date-time" },
++ "ends_at": { "type": "string", "format": "date-time" }
++ }
++ },
++ {
++ "type": "object",
++ "required": ["state", "message"],
++ "additionalProperties": false,
++ "properties": {
++ "state": { "enum": ["investigating", "identified", "monitoring", "resolved", "scheduled", "in_progress", "completed"] },
++ "message": { "type": "string", "minLength": 1, "maxLength": 2000 },
++ "ends_at": { "type": "string", "format": "date-time" }
++ }
++ }
++ ]
++}
ddiff --git a/contracts/network/status-incident.v1.json b/contracts/network/status-incident.v1.json
nnew file mode 100644
iindex 00000000..89041bbd
---- /dev/null
++++ b/contracts/network/status-incident.v1.json
@@@ -0,0 +1,36 @@
++{
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident.v1.json",
++ "title": "NetworkStatusIncident",
++ "description": "network.status-incident@1 (roadmap WS-N task 12): one incident or maintenance window on openvibe.network/status, public. An incident moves investigating → identified → monitoring → resolved; a maintenance window scheduled → in_progress → completed. Each change adds an update with its message; the newest state is the incident's. Services are registry ids. Messages are plain text written for people (no internal hostnames, secrets or personal data).",
++ "type": "object",
++ "required": ["id", "kind", "title", "state", "services", "starts_at", "updates", "created_at", "updated_at"],
++ "additionalProperties": false,
++ "properties": {
++ "id": { "type": "string", "pattern": "^inc_[0-9A-HJKMNP-TV-Z]{26}$" },
++ "kind": { "enum": ["incident", "maintenance"] },
++ "title": { "type": "string", "minLength": 3, "maxLength": 140 },
++ "severity": { "enum": ["minor", "major", "critical"], "description": "Incidents only." },
++ "state": { "enum": ["investigating", "identified", "monitoring", "resolved", "scheduled", "in_progress", "completed"] },
++ "services": { "type": "array", "maxItems": 40, "items": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" } },
++ "starts_at": { "type": "string", "format": "date-time" },
++ "ends_at": { "type": ["string", "null"], "format": "date-time", "description": "When it ended, or a maintenance window's planned end." },
++ "updates": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "required": ["at", "state", "message"],
++ "additionalProperties": false,
++ "properties": {
++ "at": { "type": "string", "format": "date-time" },
++ "state": { "enum": ["investigating", "identified", "monitoring", "resolved", "scheduled", "in_progress", "completed"] },
++ "message": { "type": "string", "minLength": 1, "maxLength": 2000 }
++ }
++ }
++ },
++ "created_at": { "type": "string", "format": "date-time" },
++ "updated_at": { "type": "string", "format": "date-time" }
++ }
++}
ddiff --git a/fixtures/network.status-incident-list/invalid/bad-item.json b/fixtures/network.status-incident-list/invalid/bad-item.json
nnew file mode 100644
iindex 00000000..acd2d84e
---- /dev/null
++++ b/fixtures/network.status-incident-list/invalid/bad-item.json
@@@ -0,0 +1 @@
++{ "active": [ { "id": "nope" } ], "recent": [] }
ddiff --git a/fixtures/network.status-incident-list/valid/one.json b/fixtures/network.status-incident-list/valid/one.json
nnew file mode 100644
iindex 00000000..86850939
---- /dev/null
++++ b/fixtures/network.status-incident-list/valid/one.json
@@@ -0,0 +1 @@
++{"active": [{"id": "inc_01JAB2C3D4E5F6G7H8J9K0MNPQ", "kind": "incident", "title": "Live streams stall on start", "severity": "major", "state": "identified", "services": ["live"], "starts_at": "2026-09-26T16:00:00Z", "ends_at": null, "updates": [{"at": "2026-09-26T16:00:00Z", "state": "investigating", "message": "New streams take a minute to start."}, {"at": "2026-09-26T16:10:00Z", "state": "identified", "message": "A restart left the ingest socket unbound; rebinding."}], "created_at": "2026-09-26T16:00:00Z", "updated_at": "2026-09-26T16:10:00Z"}], "recent": []}
\\ No newline at end of file
ddiff --git a/fixtures/network.status-incident-list/valid/quiet.json b/fixtures/network.status-incident-list/valid/quiet.json
nnew file mode 100644
iindex 00000000..ba128f6e
---- /dev/null
++++ b/fixtures/network.status-incident-list/valid/quiet.json
@@@ -0,0 +1 @@
++{ "active": [], "recent": [] }
ddiff --git a/fixtures/network.status-incident-request/invalid/empty.json b/fixtures/network.status-incident-request/invalid/empty.json
nnew file mode 100644
iindex 00000000..8e300a56
---- /dev/null
++++ b/fixtures/network.status-incident-request/invalid/empty.json
@@@ -0,0 +1 @@
++{ "kind": "incident", "title": "x", "services": [], "message": "" }
ddiff --git a/fixtures/network.status-incident-request/invalid/rename-on-update.json b/fixtures/network.status-incident-request/invalid/rename-on-update.json
nnew file mode 100644
iindex 00000000..275d68c7
---- /dev/null
++++ b/fixtures/network.status-incident-request/invalid/rename-on-update.json
@@@ -0,0 +1 @@
++{ "state": "resolved", "message": "ok", "title": "renamed" }
ddiff --git a/fixtures/network.status-incident-request/valid/open.json b/fixtures/network.status-incident-request/valid/open.json
nnew file mode 100644
iindex 00000000..c08a6f5c
---- /dev/null
++++ b/fixtures/network.status-incident-request/valid/open.json
@@@ -0,0 +1 @@
++{ "kind": "incident", "title": "Chat is slow", "severity": "minor", "services": ["chat"], "message": "Messages arrive late." }
ddiff --git a/fixtures/network.status-incident-request/valid/update.json b/fixtures/network.status-incident-request/valid/update.json
nnew file mode 100644
iindex 00000000..a26b08ee
---- /dev/null
++++ b/fixtures/network.status-incident-request/valid/update.json
@@@ -0,0 +1 @@
++{ "state": "resolved", "message": "Fixed and monitored for an hour." }
ddiff --git a/fixtures/network.status-incident/invalid/unknown-state.json b/fixtures/network.status-incident/invalid/unknown-state.json
nnew file mode 100644
iindex 00000000..bd4c5851
---- /dev/null
++++ b/fixtures/network.status-incident/invalid/unknown-state.json
@@@ -0,0 +1 @@
++{ "id": "inc_01JAB2C3D4E5F6G7H8J9K0MNPQ", "kind": "incident", "title": "x", "state": "broken", "services": [], "starts_at": "2026-09-26T16:00:00Z", "updates": [], "created_at": "2026-09-26T16:00:00Z", "updated_at": "2026-09-26T16:00:00Z" }
ddiff --git a/fixtures/network.status-incident/valid/incident.json b/fixtures/network.status-incident/valid/incident.json
nnew file mode 100644
iindex 00000000..44978f2b
---- /dev/null
++++ b/fixtures/network.status-incident/valid/incident.json
@@@ -0,0 +1 @@
++{ "id": "inc_01JAB2C3D4E5F6G7H8J9K0MNPQ", "kind": "incident", "title": "Live streams stall on start", "severity": "major", "state": "identified", "services": ["live"], "starts_at": "2026-09-26T16:00:00Z", "ends_at": null, "updates": [ { "at": "2026-09-26T16:00:00Z", "state": "investigating", "message": "New streams take a minute to start." }, { "at": "2026-09-26T16:10:00Z", "state": "identified", "message": "A restart left the ingest socket unbound; rebinding." } ], "created_at": "2026-09-26T16:00:00Z", "updated_at": "2026-09-26T16:10:00Z" }
ddiff --git a/fixtures/network.status-incident/valid/maintenance.json b/fixtures/network.status-incident/valid/maintenance.json
nnew file mode 100644
iindex 00000000..c72afaca
---- /dev/null
++++ b/fixtures/network.status-incident/valid/maintenance.json
@@@ -0,0 +1 @@
++{ "id": "inc_01JAB2C3D4E5F6G7H8J9K0MNPQ", "kind": "maintenance", "title": "Media storage move", "state": "scheduled", "services": ["media"], "starts_at": "2026-09-28T03:00:00Z", "ends_at": "2026-09-28T04:00:00Z", "updates": [ { "at": "2026-09-26T16:00:00Z", "state": "scheduled", "message": "Uploads pause for up to an hour." } ], "created_at": "2026-09-26T16:00:00Z", "updated_at": "2026-09-26T16:00:00Z" }
ddiff --git a/generated/json-schema/bundle.json b/generated/json-schema/bundle.json
iindex 051f138f..e597859b 100644
---- a/generated/json-schema/bundle.json
++++ b/generated/json-schema/bundle.json
@@@ -26963,6 +26963,265 @@
}
}
},
++ "network.status-incident": {
++ "version": "1.0.0",
++ "owner": "network",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident.v1.json",
++ "title": "NetworkStatusIncident",
++ "description": "network.status-incident@1 (roadmap WS-N task 12): one incident or maintenance window on openvibe.network/status, public. An incident moves investigating → identified → monitoring → resolved; a maintenance window scheduled → in_progress → completed. Each change adds an update with its message; the newest state is the incident's. Services are registry ids. Messages are plain text written for people (no internal hostnames, secrets or personal data).",
++ "type": "object",
++ "required": [
++ "id",
++ "kind",
++ "title",
++ "state",
++ "services",
++ "starts_at",
++ "updates",
++ "created_at",
++ "updated_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^inc_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "kind": {
++ "enum": [
++ "incident",
++ "maintenance"
++ ]
++ },
++ "title": {
++ "type": "string",
++ "minLength": 3,
++ "maxLength": 140
++ },
++ "severity": {
++ "enum": [
++ "minor",
++ "major",
++ "critical"
++ ],
++ "description": "Incidents only."
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "services": {
++ "type": "array",
++ "maxItems": 40,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,39}$"
++ }
++ },
++ "starts_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ends_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time",
++ "description": "When it ended, or a maintenance window's planned end."
++ },
++ "updates": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "required": [
++ "at",
++ "state",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ }
++ }
++ }
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ },
++ "network.status-incident-list": {
++ "version": "1.0.0",
++ "owner": "network",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident-list.v1.json",
++ "title": "NetworkStatusIncidentList",
++ "description": "network.status-incident-list@1: GET /api/v1/status/incidents on OpenVibe.Network (public): open incidents and current or upcoming maintenance windows (`active`), and those closed in the last 30 days (`recent`), newest first.",
++ "type": "object",
++ "required": [
++ "active",
++ "recent"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "active": {
++ "type": "array",
++ "items": {
++ "$ref": "./status-incident.v1.json"
++ }
++ },
++ "recent": {
++ "type": "array",
++ "items": {
++ "$ref": "./status-incident.v1.json"
++ }
++ }
++ }
++ }
++ },
++ "network.status-incident-request": {
++ "version": "1.0.0",
++ "owner": "network",
++ "status": "active",
++ "schema": {
++ "$schema": "https://json-schema.org/draft/2020-12/schema",
++ "$id": "https://openvibe.network/contracts/network/status-incident-request.v1.json",
++ "title": "NetworkStatusIncidentRequest",
++ "description": "network.status-incident-request@1 (capability network.status.incident; staff admins or the Host principal). POST /api/v1/status/incidents opens one: { kind, title, severity? (incidents), services, message, starts_at? (default now), ends_at? (a maintenance window's planned end), state? (default investigating, or scheduled for maintenance) }. POST /api/v1/status/incidents/:id/updates adds an update: { state, message, ends_at? }. A resolved incident or a completed window is closed; updates to it are refused.",
++ "oneOf": [
++ {
++ "type": "object",
++ "required": [
++ "kind",
++ "title",
++ "services",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "kind": {
++ "enum": [
++ "incident",
++ "maintenance"
++ ]
++ },
++ "title": {
++ "type": "string",
++ "minLength": 3,
++ "maxLength": 140
++ },
++ "severity": {
++ "enum": [
++ "minor",
++ "major",
++ "critical"
++ ]
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "scheduled",
++ "in_progress"
++ ]
++ },
++ "services": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 40,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,39}$"
++ }
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ },
++ "starts_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ends_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
++ {
++ "type": "object",
++ "required": [
++ "state",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ },
++ "ends_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ ]
++ }
++ },
"network.staff-list-result": {
"version": "1.0.0",
"owner": "network",
ddiff --git a/generated/openapi/ai.json b/generated/openapi/ai.json
iindex 875d60e5..f0dd3775 100644
---- a/generated/openapi/ai.json
++++ b/generated/openapi/ai.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.AI API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/billing.json b/generated/openapi/billing.json
iindex 0999c2a6..037e3506 100644
---- a/generated/openapi/billing.json
++++ b/generated/openapi/billing.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Billing API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/blog.json b/generated/openapi/blog.json
iindex d0be4f1f..a48d313d 100644
---- a/generated/openapi/blog.json
++++ b/generated/openapi/blog.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Blog API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/chat.json b/generated/openapi/chat.json
iindex c0279087..4e06d297 100644
---- a/generated/openapi/chat.json
++++ b/generated/openapi/chat.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Chat API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/codes.json b/generated/openapi/codes.json
iindex 43b0552c..5d65815b 100644
---- a/generated/openapi/codes.json
++++ b/generated/openapi/codes.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Codes API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/community.json b/generated/openapi/community.json
iindex 5340f3a4..f38a832e 100644
---- a/generated/openapi/community.json
++++ b/generated/openapi/community.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Community API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/coupons.json b/generated/openapi/coupons.json
iindex 67dc01f5..5f362b8b 100644
---- a/generated/openapi/coupons.json
++++ b/generated/openapi/coupons.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Coupons API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/deals.json b/generated/openapi/deals.json
iindex dfb99bbf..cab0ff8e 100644
---- a/generated/openapi/deals.json
++++ b/generated/openapi/deals.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Deals API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/events.json b/generated/openapi/events.json
iindex 459b2571..f6fe8f00 100644
---- a/generated/openapi/events.json
++++ b/generated/openapi/events.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Events API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/games.json b/generated/openapi/games.json
iindex 25e9536d..ff50fc78 100644
---- a/generated/openapi/games.json
++++ b/generated/openapi/games.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Games API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/host.json b/generated/openapi/host.json
iindex 77a31a6c..0d77422d 100644
---- a/generated/openapi/host.json
++++ b/generated/openapi/host.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Host API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/index.json b/generated/openapi/index.json
iindex 0883db88..54a2a312 100644
---- a/generated/openapi/index.json
++++ b/generated/openapi/index.json
@@@ -96,8 +96,8 @@
"service": "network",
"name": "OpenVibe.Network",
"origin": "https://openvibe.network",
-- "operations": 13,
-- "capabilities": 12
++ "operations": 15,
++ "capabilities": 13
},
{
"service": "news",
ddiff --git a/generated/openapi/live.json b/generated/openapi/live.json
iindex 316a756a..92604a75 100644
---- a/generated/openapi/live.json
++++ b/generated/openapi/live.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Live API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/media.json b/generated/openapi/media.json
iindex acaaa716..c454f3e8 100644
---- a/generated/openapi/media.json
++++ b/generated/openapi/media.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Media API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/network.json b/generated/openapi/network.json
iindex 07326ffd..7f420a19 100644
---- a/generated/openapi/network.json
++++ b/generated/openapi/network.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Network API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
@@@ -126,6 +126,128 @@
}
}
},
++ "/api/v1/status/incidents": {
++ "post": {
++ "operationId": "post_api_v1_status_incidents",
++ "summary": "Open and update incidents and maintenance windows on the public status page (openvibe.network/status): the operator's tooling (ovhost incident / maintenance, as the Host principal) and staff admins.",
++ "description": "**network.status.incident** (internal): Open and update incidents and maintenance windows on the public status page (openvibe.network/status): the operator's tooling (ovhost incident / maintenance, as the Host principal) and staff admins. Never grantable to apps.",
++ "tags": [
++ "network.status"
++ ],
++ "x-openvibe-capabilities": [
++ "network.status.incident"
++ ],
++ "x-openvibe-visibility": [
++ "internal"
++ ],
++ "x-openvibe-quota-class": "admin",
++ "security": [
++ {
++ "openvibeToken": [
++ "network.status.incident"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/network.status-incident-request.v1"
++ }
++ }
++ }
++ },
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/network.status-incident.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
++ "/api/v1/status/incidents/{id}/updates": {
++ "post": {
++ "operationId": "post_api_v1_status_incidents_id_updates",
++ "summary": "Open and update incidents and maintenance windows on the public status page (openvibe.network/status): the operator's tooling (ovhost incident / maintenance, as the Host principal) and staff admins.",
++ "description": "**network.status.incident** (internal): Open and update incidents and maintenance windows on the public status page (openvibe.network/status): the operator's tooling (ovhost incident / maintenance, as the Host principal) and staff admins. Never grantable to apps.",
++ "tags": [
++ "network.status"
++ ],
++ "x-openvibe-capabilities": [
++ "network.status.incident"
++ ],
++ "x-openvibe-visibility": [
++ "internal"
++ ],
++ "x-openvibe-quota-class": "admin",
++ "security": [
++ {
++ "openvibeToken": [
++ "network.status.incident"
++ ]
++ }
++ ],
++ "requestBody": {
++ "required": false,
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/network.status-incident-request.v1"
++ }
++ }
++ }
++ },
++ "parameters": [
++ {
++ "name": "id",
++ "in": "path",
++ "required": true,
++ "schema": {
++ "type": "string"
++ }
++ }
++ ],
++ "responses": {
++ "2XX": {
++ "description": "Success",
++ "content": {
++ "application/json": {
++ "schema": {
++ "$ref": "#/components/schemas/network.status-incident.v1"
++ }
++ }
++ }
++ },
++ "default": {
++ "description": "An error (RFC 9457 problem details)",
++ "content": {
++ "application/problem+json": {
++ "schema": {
++ "$ref": "#/components/schemas/errors.problem.v1"
++ }
++ }
++ }
++ }
++ }
++ }
++ },
"/internal/blocks?subject=usr_…": {
"get": {
"operationId": "get_internal_blocks_subject_usr",
@@@ -1864,6 +1986,220 @@
}
}
}
++ },
++ "network.status-incident-request.v1": {
++ "title": "NetworkStatusIncidentRequest",
++ "description": "network.status-incident-request@1 (capability network.status.incident; staff admins or the Host principal). POST /api/v1/status/incidents opens one: { kind, title, severity? (incidents), services, message, starts_at? (default now), ends_at? (a maintenance window's planned end), state? (default investigating, or scheduled for maintenance) }. POST /api/v1/status/incidents/:id/updates adds an update: { state, message, ends_at? }. A resolved incident or a completed window is closed; updates to it are refused.",
++ "oneOf": [
++ {
++ "type": "object",
++ "required": [
++ "kind",
++ "title",
++ "services",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "kind": {
++ "enum": [
++ "incident",
++ "maintenance"
++ ]
++ },
++ "title": {
++ "type": "string",
++ "minLength": 3,
++ "maxLength": 140
++ },
++ "severity": {
++ "enum": [
++ "minor",
++ "major",
++ "critical"
++ ]
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "scheduled",
++ "in_progress"
++ ]
++ },
++ "services": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 40,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,39}$"
++ }
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ },
++ "starts_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ends_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ },
++ {
++ "type": "object",
++ "required": [
++ "state",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ },
++ "ends_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
++ }
++ ]
++ },
++ "network.status-incident.v1": {
++ "title": "NetworkStatusIncident",
++ "description": "network.status-incident@1 (roadmap WS-N task 12): one incident or maintenance window on openvibe.network/status, public. An incident moves investigating → identified → monitoring → resolved; a maintenance window scheduled → in_progress → completed. Each change adds an update with its message; the newest state is the incident's. Services are registry ids. Messages are plain text written for people (no internal hostnames, secrets or personal data).",
++ "type": "object",
++ "required": [
++ "id",
++ "kind",
++ "title",
++ "state",
++ "services",
++ "starts_at",
++ "updates",
++ "created_at",
++ "updated_at"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "id": {
++ "type": "string",
++ "pattern": "^inc_[0-9A-HJKMNP-TV-Z]{26}$"
++ },
++ "kind": {
++ "enum": [
++ "incident",
++ "maintenance"
++ ]
++ },
++ "title": {
++ "type": "string",
++ "minLength": 3,
++ "maxLength": 140
++ },
++ "severity": {
++ "enum": [
++ "minor",
++ "major",
++ "critical"
++ ],
++ "description": "Incidents only."
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "services": {
++ "type": "array",
++ "maxItems": 40,
++ "items": {
++ "type": "string",
++ "pattern": "^[a-z][a-z0-9-]{1,39}$"
++ }
++ },
++ "starts_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "ends_at": {
++ "type": [
++ "string",
++ "null"
++ ],
++ "format": "date-time",
++ "description": "When it ended, or a maintenance window's planned end."
++ },
++ "updates": {
++ "type": "array",
++ "minItems": 1,
++ "maxItems": 100,
++ "items": {
++ "type": "object",
++ "required": [
++ "at",
++ "state",
++ "message"
++ ],
++ "additionalProperties": false,
++ "properties": {
++ "at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "state": {
++ "enum": [
++ "investigating",
++ "identified",
++ "monitoring",
++ "resolved",
++ "scheduled",
++ "in_progress",
++ "completed"
++ ]
++ },
++ "message": {
++ "type": "string",
++ "minLength": 1,
++ "maxLength": 2000
++ }
++ }
++ }
++ },
++ "created_at": {
++ "type": "string",
++ "format": "date-time"
++ },
++ "updated_at": {
++ "type": "string",
++ "format": "date-time"
++ }
++ }
}
},
"securitySchemes": {
ddiff --git a/generated/openapi/news.json b/generated/openapi/news.json
iindex a88ecbc2..603eb1fe 100644
---- a/generated/openapi/news.json
++++ b/generated/openapi/news.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.News API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/openre.json b/generated/openapi/openre.json
iindex 2ad64b05..f3323223 100644
---- a/generated/openapi/openre.json
++++ b/generated/openapi/openre.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenRe.Stream API",
-- "version": "0.65.0",
-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/reviews.json b/generated/openapi/reviews.json
iindex b6cb893d..bb65daa0 100644
---- a/generated/openapi/reviews.json
++++ b/generated/openapi/reviews.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Reviews API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/search.json b/generated/openapi/search.json
iindex ad944560..440da5d6 100644
---- a/generated/openapi/search.json
++++ b/generated/openapi/search.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Search API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/sources.json b/generated/openapi/sources.json
iindex 140f8c6e..d5558323 100644
---- a/generated/openapi/sources.json
++++ b/generated/openapi/sources.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Sources API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tips.json b/generated/openapi/tips.json
iindex 556ec9e3..6457e7cc 100644
---- a/generated/openapi/tips.json
++++ b/generated/openapi/tips.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tips API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/tools.json b/generated/openapi/tools.json
iindex 9513b22d..6ce9aae0 100644
---- a/generated/openapi/tools.json
++++ b/generated/openapi/tools.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Tools API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/trade.json b/generated/openapi/trade.json
iindex 2319bc4d..1f4065a9 100644
---- a/generated/openapi/trade.json
++++ b/generated/openapi/trade.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Trade API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/vip.json b/generated/openapi/vip.json
iindex 364962bf..b8a93068 100644
---- a/generated/openapi/vip.json
++++ b/generated/openapi/vip.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.VIP API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/openapi/wiki.json b/generated/openapi/wiki.json
iindex 4bcf8880..0c4eaf25 100644
---- a/generated/openapi/wiki.json
++++ b/generated/openapi/wiki.json
@@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "OpenVibe.Wiki API",
-- "version": "0.65.0",
-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.65.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
++ "version": "0.66.0",
++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.66.0): each operation lists the capabilities it performs; a token for the service's audience must carry one of them unless the route is open. Generated by openvibe-contracts lib/openapi.js; do not edit.",
"license": {
"name": "MIT",
"identifier": "MIT"
ddiff --git a/generated/typescript/index.d.ts b/generated/typescript/index.d.ts
iindex ee925bb8..752aa599 100644
---- a/generated/typescript/index.d.ts
++++ b/generated/typescript/index.d.ts
@@@ -29383,6 +29383,82 @@ export interface ProjectUsageResult {
};
}
++/** [email protected] (owner: network) */
++/**
++ * network.status-incident@1 (roadmap WS-N task 12): one incident or maintenance window on openvibe.network/status, public. An incident moves investigating → identified → monitoring → resolved; a maintenance window scheduled → in_progress → completed. Each change adds an update with its message; the newest state is the incident's. Services are registry ids. Messages are plain text written for people (no internal hostnames, secrets or personal data).
++ */
++export interface NetworkStatusIncident {
++ id: string;
++ kind: "incident" | "maintenance";
++ title: string;
++ /**
++ * Incidents only.
++ */
++ severity?: "minor" | "major" | "critical";
++ state: "investigating" | "identified" | "monitoring" | "resolved" | "scheduled" | "in_progress" | "completed";
++ /**
++ * @maxItems 40
++ */
++ services: string[];
++ starts_at: string;
++ /**
++ * When it ended, or a maintenance window's planned end.
++ */
++ ends_at?: string | null;
++ /**
++ * @minItems 1
++ * @maxItems 100
++ */
++ updates: [
++ {
++ at: string;
++ state: "investigating" | "identified" | "monitoring" | "resolved" | "scheduled" | "in_progress" | "completed";
++ message: string;
++ },
++ ...{
++ at: string;
++ state: "investigating" | "identified" | "monitoring" | "resolved" | "scheduled" | "in_progress" | "completed";
++ message: string;
++ }[]
++ ];
++ created_at: string;
++ updated_at: string;
++}
++
++/** [email protected] (owner: network) */
++/**
++ * network.status-incident-list@1: GET /api/v1/status/incidents on OpenVibe.Network (public): open incidents and current or upcoming maintenance windows (`active`), and those closed in the last 30 days (`recent`), newest first.
++ */
++export interface NetworkStatusIncidentList {
++ active: NetworkStatusIncident[];
++ recent: NetworkStatusIncident[];
++}
++
++/** [email protected] (owner: network) */
++/**
++ * network.status-incident-request@1 (capability network.status.incident; staff admins or the Host principal). POST /api/v1/status/incidents opens one: { kind, title, severity? (incidents), services, message, starts_at? (default now), ends_at? (a maintenance window's planned end), state? (default investigating, or scheduled for maintenance) }. POST /api/v1/status/incidents/:id/updates adds an update: { state, message, ends_at? }. A resolved incident or a completed window is closed; updates to it are refused.
++ */
++export type NetworkStatusIncidentRequest =
++ | {
++ kind: "incident" | "maintenance";
++ title: string;
++ severity?: "minor" | "major" | "critical";
++ state?: "investigating" | "identified" | "monitoring" | "scheduled" | "in_progress";
++ /**
++ * @minItems 1
++ * @maxItems 40
++ */
++ services: [string, ...string[]];
++ message: string;
++ starts_at?: string;
++ ends_at?: string;
++ }
++ | {
++ state: "investigating" | "identified" | "monitoring" | "resolved" | "scheduled" | "in_progress" | "completed";
++ message: string;
++ ends_at?: string;
++ };
++
/** [email protected] (owner: network) */
/**
* network.staff-list-result@1: the answer of network.staff.read on OpenVibe.Network. GET /api/v1/staff/moderators[?service=chat|live|community|pastes|calls] (a service token holding network.staff.read, or a signed-in person holding staff.moderation.logs) → { service, staff }: the network's global moderators, admins and the owner who are not banned, with the staff capabilities their role holds in the contracts staff map; ?service keeps those holding the capability that moderates that service (another service name keeps those holding staff.content.moderate; an invalid value is ignored and answered as null). Answered with Cache-Control: private, no-store; a person without staff.moderation.logs gets 403 { error: forbidden }.
ddiff --git a/manifests/capabilities/network.status.incident.json b/manifests/capabilities/network.status.incident.json
nnew file mode 100644
iindex 00000000..5a879193
---- /dev/null
++++ b/manifests/capabilities/network.status.incident.json
@@@ -0,0 +1,15 @@
++{
++ "id": "network.status.incident",
++ "version": "1.0",
++ "owner": "network",
++ "status": "active",
++ "visibility": "internal",
++ "description": "Open and update incidents and maintenance windows on the public status page (openvibe.network/status): the operator's tooling (ovhost incident / maintenance, as the Host principal) and staff admins. Never grantable to apps.",
++ "permissions": ["status:write"],
++ "resourceConstraints": ["none"],
++ "quotaClass": "admin",
++ "events": [],
++ "implementedBy": ["POST /api/v1/status/incidents", "POST /api/v1/status/incidents/:id/updates"],
++ "inputSchema": "network.status-incident-request@1",
++ "outputSchema": "network.status-incident@1"
++}
ddiff --git a/manifests/services/network.json b/manifests/services/network.json
iindex 9cb3bd5d..3835b322 100644
---- a/manifests/services/network.json
++++ b/manifests/services/network.json
@@@ -46,7 +46,8 @@
"network.operator.alert",
"network.project.manage",
"network.project.read",
-- "network.staff.read"
++ "network.staff.read",
++ "network.status.incident"
],
"eventsProduced": [
"network.app.created",
ddiff --git a/package.json b/package.json
iindex 1ae9ccaf..bd4df687 100644
---- a/package.json
++++ b/package.json
@@@ -1,6 +1,6 @@
{
"name": "openvibe-contracts",
-- "version": "0.65.0",
++ "version": "0.66.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"types": "generated/typescript/index.d.ts",