openvibers/openvibe.contracts Commits
v0.62.0: operator alerts (roadmap WS-H task 11). Capability network.operator.alert (internal; POST /internal/operator/alerts on Network, granted to the Host principal) with network.operator-alerts-request@1 (the complete set of alerts firing at one source: fingerprint, name, severity, summary, description, service, started_at) and network.operator-alerts-result@1 (firing, opened, reminded, resolved, notified). Network pages the owner when an alert opens, once a day while it stays open, and when it resolves.
Changes
@@@ -6,6 +6,12 @@ the notes were in the tag and commit messages (`git tag -n1`).## Unreleased++## 0.62.0 — 2026-09-26++++**Operator alerts** (roadmap WS-H task 11; the delivery path that Host's Prometheus alerts lacked).++- **New capability `network.operator.alert`** (internal, owner network), implemented by `POST /internal/operator/alerts` on OpenVibe.Network and granted to the Host principal. The request is the complete set of alerts firing now at one source (`prometheus`). Network pages the operator (the owner account) as a critical or high `admin` notification when an alert opens, reminds once a day while it stays open, and sends a resolved notice when it drops out of the set. Being an `admin` notification, it reaches the bell, web push and the realtime topic, and no block hides it.++- **New schemas** `network.operator-alerts-request@1` (source, sent_at, up to 200 alerts: fingerprint, name, severity, summary, description, service, started_at; no free-form labels) and `network.operator-alerts-result@1` (firing, opened, reminded, resolved, notified).++## 0.61.0 — 2026-09-26**A person's realtime topic and realtime tickets** (roadmap WS-E task 3, WS-F task 1; ADR-005 amendment 2).@@@ -2485,6 +2485,24 @@"compatibility": "backward","status": "active"},++ {++ "id": "network.operator-alerts-request",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/operator-alerts-request.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active"++ },++ {++ "id": "network.operator-alerts-result",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/operator-alerts-result.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active"++ },{"id": "network.realtime-ticket-result","version": "1.0.0",nnew file mode 100644@@@ -0,0 +1,31 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/operator-alerts-request.v1.json",++ "title": "NetworkOperatorAlertsRequest",++ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",++ "type": "object",++ "required": ["source", "alerts"],++ "additionalProperties": false,++ "properties": {++ "source": { "enum": ["prometheus"], "description": "Where the alerts are evaluated. Resolution is per source." },++ "sent_at": { "type": "string", "format": "date-time" },++ "alerts": {++ "type": "array",++ "maxItems": 200,++ "items": {++ "type": "object",++ "required": ["fingerprint", "name", "severity", "summary", "started_at"],++ "additionalProperties": false,++ "properties": {++ "fingerprint": { "type": "string", "pattern": "^[0-9a-f]{16,64}$" },++ "name": { "type": "string", "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$" },++ "severity": { "enum": ["critical", "warning", "info"] },++ "summary": { "type": "string", "minLength": 1, "maxLength": 300 },++ "description": { "type": "string", "maxLength": 1000 },++ "service": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" },++ "started_at": { "type": "string", "format": "date-time" }++ }++ }++ }++ }++}nnew file mode 100644@@@ -0,0 +1,17 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/operator-alerts-result.v1.json",++ "title": "NetworkOperatorAlertsResult",++ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",++ "type": "object",++ "required": ["ok", "firing", "opened", "reminded", "resolved", "notified"],++ "additionalProperties": false,++ "properties": {++ "ok": { "const": true },++ "firing": { "type": "integer", "minimum": 0 },++ "opened": { "type": "integer", "minimum": 0 },++ "reminded": { "type": "integer", "minimum": 0 },++ "resolved": { "type": "integer", "minimum": 0 },++ "notified": { "type": "integer", "minimum": 0 }++ }++}nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z", "labels": { "instance": "127.0.0.1:9100" } } ] }nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "started_at": "2026-09-26T05:35:00Z" } ] }nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "page", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z" } ] }nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "grafana", "alerts": [] }nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "prometheus", "alerts": [ { "fingerprint": "3F1C2A9B7D4E6F80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z" } ] }nnew file mode 100644@@@ -0,0 +1 @@++{ "source": "prometheus", "alerts": [] }nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "source": "prometheus",++ "sent_at": "2026-09-26T14:10:00Z",++ "alerts": [++ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No successful backup in 26 hours", "description": "ovhost backup --all has not succeeded since 2026-09-25 03:35 UTC.", "service": "host", "started_at": "2026-09-26T05:35:00Z" },++ { "fingerprint": "9a8b7c6d5e4f3a2b1c0d", "name": "OpenVibeBrowserCheckFailed", "severity": "warning", "summary": "The browser check of live failed after release 8caa540", "service": "live", "started_at": "2026-09-26T14:05:00Z" }++ ]++}nnew file mode 100644@@@ -0,0 +1 @@++{ "ok": true, "firing": -1, "opened": 0, "reminded": 0, "resolved": 0, "notified": 0 }nnew file mode 100644@@@ -0,0 +1 @@++{ "ok": true, "firing": 1, "opened": 1, "reminded": 0, "resolved": 0 }nnew file mode 100644@@@ -0,0 +1 @@++{ "ok": true, "firing": 2, "opened": 1, "reminded": 0, "resolved": 1, "notified": 2 }nnew file mode 100644@@@ -0,0 +1 @@++{ "ok": true, "firing": 0, "opened": 0, "reminded": 0, "resolved": 0, "notified": 0 }@@@ -26010,6 +26010,130 @@]}},++ "network.operator-alerts-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/operator-alerts-request.v1.json",++ "title": "NetworkOperatorAlertsRequest",++ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",++ "type": "object",++ "required": [++ "source",++ "alerts"++ ],++ "additionalProperties": false,++ "properties": {++ "source": {++ "enum": [++ "prometheus"++ ],++ "description": "Where the alerts are evaluated. Resolution is per source."++ },++ "sent_at": {++ "type": "string",++ "format": "date-time"++ },++ "alerts": {++ "type": "array",++ "maxItems": 200,++ "items": {++ "type": "object",++ "required": [++ "fingerprint",++ "name",++ "severity",++ "summary",++ "started_at"++ ],++ "additionalProperties": false,++ "properties": {++ "fingerprint": {++ "type": "string",++ "pattern": "^[0-9a-f]{16,64}$"++ },++ "name": {++ "type": "string",++ "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$"++ },++ "severity": {++ "enum": [++ "critical",++ "warning",++ "info"++ ]++ },++ "summary": {++ "type": "string",++ "minLength": 1,++ "maxLength": 300++ },++ "description": {++ "type": "string",++ "maxLength": 1000++ },++ "service": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,39}$"++ },++ "started_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ }++ }++ }++ },++ "network.operator-alerts-result": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/operator-alerts-result.v1.json",++ "title": "NetworkOperatorAlertsResult",++ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",++ "type": "object",++ "required": [++ "ok",++ "firing",++ "opened",++ "reminded",++ "resolved",++ "notified"++ ],++ "additionalProperties": false,++ "properties": {++ "ok": {++ "const": true++ },++ "firing": {++ "type": "integer",++ "minimum": 0++ },++ "opened": {++ "type": "integer",++ "minimum": 0++ },++ "reminded": {++ "type": "integer",++ "minimum": 0++ },++ "resolved": {++ "type": "integer",++ "minimum": 0++ },++ "notified": {++ "type": "integer",++ "minimum": 0++ }++ }++ }++ },"network.realtime-ticket-result": {"version": "1.0.0","owner": "network",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Chat API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Codes API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Coupons API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Deals API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Events API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -96,8 +96,8 @@"service": "network","name": "OpenVibe.Network","origin": "https://openvibe.network",-- "operations": 11,-- "capabilities": 10++ "operations": 12,++ "capabilities": 11},{"service": "news",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Live API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Media API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Network API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -618,6 +618,62 @@}}}++ },++ "/internal/operator/alerts": {++ "post": {++ "operationId": "post_internal_operator_alerts",++ "summary": "Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",++ "description": "**network.operator.alert** (internal): Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",++ "tags": [++ "network.operator"++ ],++ "x-openvibe-capabilities": [++ "network.operator.alert"++ ],++ "x-openvibe-visibility": [++ "internal"++ ],++ "x-openvibe-quota-class": "notify",++ "security": [++ {++ "openvibeToken": [++ "network.operator.alert"++ ]++ }++ ],++ "requestBody": {++ "required": false,++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.operator-alerts-request.v1"++ }++ }++ }++ },++ "responses": {++ "2XX": {++ "description": "Success",++ "content": {++ "application/json": {++ "schema": {++ "$ref": "#/components/schemas/network.operator-alerts-result.v1"++ }++ }++ }++ },++ "default": {++ "description": "An error (RFC 9457 problem details)",++ "content": {++ "application/problem+json": {++ "schema": {++ "$ref": "#/components/schemas/errors.problem.v1"++ }++ }++ }++ }++ }++ }}},"components": {@@@ -1511,6 +1567,116 @@}]},++ "network.operator-alerts-request.v1": {++ "title": "NetworkOperatorAlertsRequest",++ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",++ "type": "object",++ "required": [++ "source",++ "alerts"++ ],++ "additionalProperties": false,++ "properties": {++ "source": {++ "enum": [++ "prometheus"++ ],++ "description": "Where the alerts are evaluated. Resolution is per source."++ },++ "sent_at": {++ "type": "string",++ "format": "date-time"++ },++ "alerts": {++ "type": "array",++ "maxItems": 200,++ "items": {++ "type": "object",++ "required": [++ "fingerprint",++ "name",++ "severity",++ "summary",++ "started_at"++ ],++ "additionalProperties": false,++ "properties": {++ "fingerprint": {++ "type": "string",++ "pattern": "^[0-9a-f]{16,64}$"++ },++ "name": {++ "type": "string",++ "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$"++ },++ "severity": {++ "enum": [++ "critical",++ "warning",++ "info"++ ]++ },++ "summary": {++ "type": "string",++ "minLength": 1,++ "maxLength": 300++ },++ "description": {++ "type": "string",++ "maxLength": 1000++ },++ "service": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]{1,39}$"++ },++ "started_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ }++ }++ },++ "network.operator-alerts-result.v1": {++ "title": "NetworkOperatorAlertsResult",++ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",++ "type": "object",++ "required": [++ "ok",++ "firing",++ "opened",++ "reminded",++ "resolved",++ "notified"++ ],++ "additionalProperties": false,++ "properties": {++ "ok": {++ "const": true++ },++ "firing": {++ "type": "integer",++ "minimum": 0++ },++ "opened": {++ "type": "integer",++ "minimum": 0++ },++ "reminded": {++ "type": "integer",++ "minimum": 0++ },++ "resolved": {++ "type": "integer",++ "minimum": 0++ },++ "notified": {++ "type": "integer",++ "minimum": 0++ }++ }++ },"network.staff-list-result.v1": {"title": "NetworkStaffListResult","description": "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 }.",@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.News API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenRe.Stream API",-- "version": "0.61.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Search API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Sources API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tips API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Trade API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.VIP API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.61.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.62.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"@@@ -26111,6 +26111,43 @@ export type NetworkNotificationPushResult =total: number;};++/** [email protected] (owner: network) */++/**++ * network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.++ */++export interface NetworkOperatorAlertsRequest {++ /**++ * Where the alerts are evaluated. Resolution is per source.++ */++ source: "prometheus";++ sent_at?: string;++ /**++ * @maxItems 200++ */++ alerts: {++ fingerprint: string;++ name: string;++ severity: "critical" | "warning" | "info";++ summary: string;++ description?: string;++ service?: string;++ started_at: string;++ }[];++}++++/** [email protected] (owner: network) */++/**++ * network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).++ */++export interface NetworkOperatorAlertsResult {++ ok: true;++ firing: number;++ opened: number;++ reminded: number;++ resolved: number;++ notified: number;++}++/** [email protected] (owner: network) *//*** What POST /api/v1/realtime/ticket answers (OpenVibe.Network; ADR-005 amendment 2): a realtime ticket (identity.realtime-ticket-claims@1) for the signed-in person, and where to use it. The caller is the person's own session (Bearer Network JWT, or the ov_token cookie on openvibe.network); guests are refused (403 realtime.guest), and 503 realtime.disabled means the operator turned browser realtime off (REALTIME_TICKETS=off): the client stays on polling. The client opens `${stream_url}?topics=${topics}&ticket=${ticket}` (plus last_event_id when it resumes) at once, and asks for a fresh ticket for every reconnect: a ticket opens one stream.nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "id": "network.operator.alert",++ "version": "1.0",++ "owner": "network",++ "status": "active",++ "visibility": "internal",++ "description": "Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",++ "permissions": [++ "notifications:write"++ ],++ "resourceConstraints": [++ "none"++ ],++ "quotaClass": "notify",++ "events": [],++ "implementedBy": [++ "POST /internal/operator/alerts"++ ],++ "inputSchema": "network.operator-alerts-request@1",++ "outputSchema": "network.operator-alerts-result@1"++}@@@ -42,6 +42,7 @@"network.modules.read","network.modules.write","network.notifications.push",++ "network.operator.alert","network.project.manage","network.project.read","network.staff.read"@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.61.0",++ "version": "0.62.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",
@@ -6,6 +6,12 @@ the notes were in the tag and commit messages (`git tag -n1`).
@@ -6,6 +6,12 @@ the notes were in the tag and commit messages (`git tag -n1`).
## Unreleased
## Unreleased
+## 0.62.0 — 2026-09-26
+
+**Operator alerts** (roadmap WS-H task 11; the delivery path that Host's Prometheus alerts lacked).
+- **New capability `network.operator.alert`** (internal, owner network), implemented by `POST /internal/operator/alerts` on OpenVibe.Network and granted to the Host principal. The request is the complete set of alerts firing now at one source (`prometheus`). Network pages the operator (the owner account) as a critical or high `admin` notification when an alert opens, reminds once a day while it stays open, and sends a resolved notice when it drops out of the set. Being an `admin` notification, it reaches the bell, web push and the realtime topic, and no block hides it.
+- **New schemas** `network.operator-alerts-request@1` (source, sent_at, up to 200 alerts: fingerprint, name, severity, summary, description, service, started_at; no free-form labels) and `network.operator-alerts-result@1` (firing, opened, reminded, resolved, notified).
+
## 0.61.0 — 2026-09-26
## 0.61.0 — 2026-09-26
**A person's realtime topic and realtime tickets** (roadmap WS-E task 3, WS-F task 1; ADR-005 amendment 2).
**A person's realtime topic and realtime tickets** (roadmap WS-E task 3, WS-F task 1; ADR-005 amendment 2).
@@ -2485,6 +2485,24 @@
@@ -2485,6 +2485,24 @@
"compatibility": "backward",
"compatibility": "backward",
"status": "active"
"status": "active"
},
},
+ {
+ "id": "network.operator-alerts-request",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/operator-alerts-request.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active"
+ },
+ {
+ "id": "network.operator-alerts-result",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/operator-alerts-result.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active"
+ },
{
{
"id": "network.realtime-ticket-result",
"id": "network.realtime-ticket-result",
"version": "1.0.0",
"version": "1.0.0",
new file mode 100644
new file mode 100644
@@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/operator-alerts-request.v1.json",
+ "title": "NetworkOperatorAlertsRequest",
+ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",
+ "type": "object",
+ "required": ["source", "alerts"],
+ "additionalProperties": false,
+ "properties": {
+ "source": { "enum": ["prometheus"], "description": "Where the alerts are evaluated. Resolution is per source." },
+ "sent_at": { "type": "string", "format": "date-time" },
+ "alerts": {
+ "type": "array",
+ "maxItems": 200,
+ "items": {
+ "type": "object",
+ "required": ["fingerprint", "name", "severity", "summary", "started_at"],
+ "additionalProperties": false,
+ "properties": {
+ "fingerprint": { "type": "string", "pattern": "^[0-9a-f]{16,64}$" },
+ "name": { "type": "string", "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$" },
+ "severity": { "enum": ["critical", "warning", "info"] },
+ "summary": { "type": "string", "minLength": 1, "maxLength": 300 },
+ "description": { "type": "string", "maxLength": 1000 },
+ "service": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" },
+ "started_at": { "type": "string", "format": "date-time" }
+ }
+ }
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/operator-alerts-result.v1.json",
+ "title": "NetworkOperatorAlertsResult",
+ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",
+ "type": "object",
+ "required": ["ok", "firing", "opened", "reminded", "resolved", "notified"],
+ "additionalProperties": false,
+ "properties": {
+ "ok": { "const": true },
+ "firing": { "type": "integer", "minimum": 0 },
+ "opened": { "type": "integer", "minimum": 0 },
+ "reminded": { "type": "integer", "minimum": 0 },
+ "resolved": { "type": "integer", "minimum": 0 },
+ "notified": { "type": "integer", "minimum": 0 }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z", "labels": { "instance": "127.0.0.1:9100" } } ] }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "started_at": "2026-09-26T05:35:00Z" } ] }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "prometheus", "alerts": [ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "page", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z" } ] }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "grafana", "alerts": [] }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "prometheus", "alerts": [ { "fingerprint": "3F1C2A9B7D4E6F80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No backup", "started_at": "2026-09-26T05:35:00Z" } ] }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "source": "prometheus", "alerts": [] }
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "source": "prometheus",
+ "sent_at": "2026-09-26T14:10:00Z",
+ "alerts": [
+ { "fingerprint": "3f1c2a9b7d4e6f80", "name": "OpenVibeBackupMissed", "severity": "critical", "summary": "No successful backup in 26 hours", "description": "ovhost backup --all has not succeeded since 2026-09-25 03:35 UTC.", "service": "host", "started_at": "2026-09-26T05:35:00Z" },
+ { "fingerprint": "9a8b7c6d5e4f3a2b1c0d", "name": "OpenVibeBrowserCheckFailed", "severity": "warning", "summary": "The browser check of live failed after release 8caa540", "service": "live", "started_at": "2026-09-26T14:05:00Z" }
+ ]
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "ok": true, "firing": -1, "opened": 0, "reminded": 0, "resolved": 0, "notified": 0 }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "ok": true, "firing": 1, "opened": 1, "reminded": 0, "resolved": 0 }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "ok": true, "firing": 2, "opened": 1, "reminded": 0, "resolved": 1, "notified": 2 }
new file mode 100644
new file mode 100644
@@ -0,0 +1 @@
@@ -0,0 +1 @@
+{ "ok": true, "firing": 0, "opened": 0, "reminded": 0, "resolved": 0, "notified": 0 }
@@ -26010,6 +26010,130 @@
@@ -26010,6 +26010,130 @@
]
]
}
}
},
},
+ "network.operator-alerts-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/operator-alerts-request.v1.json",
+ "title": "NetworkOperatorAlertsRequest",
+ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",
+ "type": "object",
+ "required": [
+ "source",
+ "alerts"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "source": {
+ "enum": [
+ "prometheus"
+ ],
+ "description": "Where the alerts are evaluated. Resolution is per source."
+ },
+ "sent_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "alerts": {
+ "type": "array",
+ "maxItems": 200,
+ "items": {
+ "type": "object",
+ "required": [
+ "fingerprint",
+ "name",
+ "severity",
+ "summary",
+ "started_at"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "fingerprint": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{16,64}$"
+ },
+ "name": {
+ "type": "string",
+ "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$"
+ },
+ "severity": {
+ "enum": [
+ "critical",
+ "warning",
+ "info"
+ ]
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 300
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1000
+ },
+ "service": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,39}$"
+ },
+ "started_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "network.operator-alerts-result": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/operator-alerts-result.v1.json",
+ "title": "NetworkOperatorAlertsResult",
+ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",
+ "type": "object",
+ "required": [
+ "ok",
+ "firing",
+ "opened",
+ "reminded",
+ "resolved",
+ "notified"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "ok": {
+ "const": true
+ },
+ "firing": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "opened": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "reminded": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "resolved": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "notified": {
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ }
+ },
"network.realtime-ticket-result": {
"network.realtime-ticket-result": {
"version": "1.0.0",
"version": "1.0.0",
"owner": "network",
"owner": "network",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.AI API",
"title": "OpenVibe.AI API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Billing API",
"title": "OpenVibe.Billing API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Blog API",
"title": "OpenVibe.Blog API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Chat API",
"title": "OpenVibe.Chat API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Codes API",
"title": "OpenVibe.Codes API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Community API",
"title": "OpenVibe.Community API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Coupons API",
"title": "OpenVibe.Coupons API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Deals API",
"title": "OpenVibe.Deals API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Events API",
"title": "OpenVibe.Events API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Games API",
"title": "OpenVibe.Games API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Host API",
"title": "OpenVibe.Host API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -96,8 +96,8 @@
@@ -96,8 +96,8 @@
"service": "network",
"service": "network",
"name": "OpenVibe.Network",
"name": "OpenVibe.Network",
"origin": "https://openvibe.network",
"origin": "https://openvibe.network",
- "operations": 11,
- "capabilities": 10
+ "operations": 12,
+ "capabilities": 11
},
},
{
{
"service": "news",
"service": "news",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Live API",
"title": "OpenVibe.Live API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Media API",
"title": "OpenVibe.Media API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Network API",
"title": "OpenVibe.Network API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -618,6 +618,62 @@
@@ -618,6 +618,62 @@
}
}
}
}
}
}
+ },
+ "/internal/operator/alerts": {
+ "post": {
+ "operationId": "post_internal_operator_alerts",
+ "summary": "Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",
+ "description": "**network.operator.alert** (internal): Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",
+ "tags": [
+ "network.operator"
+ ],
+ "x-openvibe-capabilities": [
+ "network.operator.alert"
+ ],
+ "x-openvibe-visibility": [
+ "internal"
+ ],
+ "x-openvibe-quota-class": "notify",
+ "security": [
+ {
+ "openvibeToken": [
+ "network.operator.alert"
+ ]
+ }
+ ],
+ "requestBody": {
+ "required": false,
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.operator-alerts-request.v1"
+ }
+ }
+ }
+ },
+ "responses": {
+ "2XX": {
+ "description": "Success",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/network.operator-alerts-result.v1"
+ }
+ }
+ }
+ },
+ "default": {
+ "description": "An error (RFC 9457 problem details)",
+ "content": {
+ "application/problem+json": {
+ "schema": {
+ "$ref": "#/components/schemas/errors.problem.v1"
+ }
+ }
+ }
+ }
+ }
+ }
}
}
},
},
"components": {
"components": {
@@ -1511,6 +1567,116 @@
@@ -1511,6 +1567,116 @@
}
}
]
]
},
},
+ "network.operator-alerts-request.v1": {
+ "title": "NetworkOperatorAlertsRequest",
+ "description": "network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.",
+ "type": "object",
+ "required": [
+ "source",
+ "alerts"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "source": {
+ "enum": [
+ "prometheus"
+ ],
+ "description": "Where the alerts are evaluated. Resolution is per source."
+ },
+ "sent_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "alerts": {
+ "type": "array",
+ "maxItems": 200,
+ "items": {
+ "type": "object",
+ "required": [
+ "fingerprint",
+ "name",
+ "severity",
+ "summary",
+ "started_at"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "fingerprint": {
+ "type": "string",
+ "pattern": "^[0-9a-f]{16,64}$"
+ },
+ "name": {
+ "type": "string",
+ "pattern": "^[A-Za-z][A-Za-z0-9_:]{0,99}$"
+ },
+ "severity": {
+ "enum": [
+ "critical",
+ "warning",
+ "info"
+ ]
+ },
+ "summary": {
+ "type": "string",
+ "minLength": 1,
+ "maxLength": 300
+ },
+ "description": {
+ "type": "string",
+ "maxLength": 1000
+ },
+ "service": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]{1,39}$"
+ },
+ "started_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ }
+ }
+ },
+ "network.operator-alerts-result.v1": {
+ "title": "NetworkOperatorAlertsResult",
+ "description": "network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).",
+ "type": "object",
+ "required": [
+ "ok",
+ "firing",
+ "opened",
+ "reminded",
+ "resolved",
+ "notified"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "ok": {
+ "const": true
+ },
+ "firing": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "opened": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "reminded": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "resolved": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "notified": {
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ },
"network.staff-list-result.v1": {
"network.staff-list-result.v1": {
"title": "NetworkStaffListResult",
"title": "NetworkStaffListResult",
"description": "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 }.",
"description": "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 }.",
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.News API",
"title": "OpenVibe.News API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenRe.Stream API",
"title": "OpenRe.Stream API",
- "version": "0.61.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Reviews API",
"title": "OpenVibe.Reviews API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Search API",
"title": "OpenVibe.Search API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Sources API",
"title": "OpenVibe.Sources API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tips API",
"title": "OpenVibe.Tips API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Tools API",
"title": "OpenVibe.Tools API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Trade API",
"title": "OpenVibe.Trade API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.VIP API",
"title": "OpenVibe.VIP API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -3,8 +3,8 @@
@@ -3,8 +3,8 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"info": {
"title": "OpenVibe.Wiki API",
"title": "OpenVibe.Wiki API",
- "version": "0.61.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.61.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.62.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.62.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": {
"license": {
"name": "MIT",
"name": "MIT",
"identifier": "MIT"
"identifier": "MIT"
@@ -26111,6 +26111,43 @@ export type NetworkNotificationPushResult =
@@ -26111,6 +26111,43 @@ export type NetworkNotificationPushResult =
total: number;
total: number;
};
};
+/** [email protected] (owner: network) */
+/**
+ * network.operator-alerts-request@1: POST /internal/operator/alerts on OpenVibe.Network (capability network.operator.alert, held by the Host principal). The complete set of alerts firing now at one source: an alert Network has not seen firing opens and pages the operator; one still firing is reminded once a day; one that was firing and is absent from the set is resolved and says so. An empty list resolves everything from that source. Fingerprints are stable per alert (name and labels), never secrets; summaries and descriptions are the alert rule's annotations.
+ */
+export interface NetworkOperatorAlertsRequest {
+ /**
+ * Where the alerts are evaluated. Resolution is per source.
+ */
+ source: "prometheus";
+ sent_at?: string;
+ /**
+ * @maxItems 200
+ */
+ alerts: {
+ fingerprint: string;
+ name: string;
+ severity: "critical" | "warning" | "info";
+ summary: string;
+ description?: string;
+ service?: string;
+ started_at: string;
+ }[];
+}
+
+/** [email protected] (owner: network) */
+/**
+ * network.operator-alerts-result@1: the answer of POST /internal/operator/alerts. firing: alerts firing after this report; opened: newly firing (paged); reminded: still firing and paged again (once a day); resolved: no longer firing (a resolved notice sent); notified: notifications created across all recipients (0 when no operator account is found or they switched admin notices off). Errors are { error } bodies (400 for a body that breaks the request contract).
+ */
+export interface NetworkOperatorAlertsResult {
+ ok: true;
+ firing: number;
+ opened: number;
+ reminded: number;
+ resolved: number;
+ notified: number;
+}
+
/** [email protected] (owner: network) */
/** [email protected] (owner: network) */
/**
/**
* What POST /api/v1/realtime/ticket answers (OpenVibe.Network; ADR-005 amendment 2): a realtime ticket (identity.realtime-ticket-claims@1) for the signed-in person, and where to use it. The caller is the person's own session (Bearer Network JWT, or the ov_token cookie on openvibe.network); guests are refused (403 realtime.guest), and 503 realtime.disabled means the operator turned browser realtime off (REALTIME_TICKETS=off): the client stays on polling. The client opens `${stream_url}?topics=${topics}&ticket=${ticket}` (plus last_event_id when it resumes) at once, and asks for a fresh ticket for every reconnect: a ticket opens one stream.
* What POST /api/v1/realtime/ticket answers (OpenVibe.Network; ADR-005 amendment 2): a realtime ticket (identity.realtime-ticket-claims@1) for the signed-in person, and where to use it. The caller is the person's own session (Bearer Network JWT, or the ov_token cookie on openvibe.network); guests are refused (403 realtime.guest), and 503 realtime.disabled means the operator turned browser realtime off (REALTIME_TICKETS=off): the client stays on polling. The client opens `${stream_url}?topics=${topics}&ticket=${ticket}` (plus last_event_id when it resumes) at once, and asks for a fresh ticket for every reconnect: a ticket opens one stream.
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "id": "network.operator.alert",
+ "version": "1.0",
+ "owner": "network",
+ "status": "active",
+ "visibility": "internal",
+ "description": "Report the complete set of alerts firing on the production host, so Network pages the operator (the owner account) when an alert opens, once a day while it stays open, and when it resolves.",
+ "permissions": [
+ "notifications:write"
+ ],
+ "resourceConstraints": [
+ "none"
+ ],
+ "quotaClass": "notify",
+ "events": [],
+ "implementedBy": [
+ "POST /internal/operator/alerts"
+ ],
+ "inputSchema": "network.operator-alerts-request@1",
+ "outputSchema": "network.operator-alerts-result@1"
+}
@@ -42,6 +42,7 @@
@@ -42,6 +42,7 @@
"network.modules.read",
"network.modules.read",
"network.modules.write",
"network.modules.write",
"network.notifications.push",
"network.notifications.push",
+ "network.operator.alert",
"network.project.manage",
"network.project.manage",
"network.project.read",
"network.project.read",
"network.staff.read"
"network.staff.read"
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.61.0",
+ "version": "0.62.0",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"description": "Machine-readable contracts for the OpenVibe network: schemas, manifests, ids, error envelope, capability checks.",
"main": "index.js",
"main": "index.js",
"types": "generated/typescript/index.d.ts",
"types": "generated/typescript/index.d.ts",