openvibers/openvibe.contracts Commits
Contracts 0.77.0: agents, confirmations, the adaptive fabric and the resource index (roadmap section 4C). identity.subject-ref@1 gains the agent subject (agt_<ULID>); ids knows agt and cnf; principalSub accepts agents. events.event-envelope@1 gains optional on_behalf_of. capabilities.capability@1 gains optional sensitive, set on sixteen capabilities with external side effects. New: network.confirmation-request@1, events.delivery-policy@1 (delivery classes, per-key ordering, latency, retention tiers, routing objective, batching, residency, 64 KB ceiling), the first-party platform.* fabric contracts (resource-offer, workload-requirements, placement-result, placement-plan, rate-card, provider-state, cost-snapshot, capacity-snapshot), common.resource-summary@1, common.resource-list-result@1 and common.resource-cost@1. Fixtures and the regenerated bundle. npm test: 14065 checks passed; compat vs v0.76.0 without breaking changes.
Changes
@@@ -6,6 +6,18 @@ the notes were in the tag and commit messages (`git tag -n1`).## Unreleased++## 0.77.0 — 2026-09-28++++**Agents, confirmations, the adaptive fabric and the resource index** (roadmap section 4C: WS-Z1, WS-Z2, WS-Z3, WS-Z7, WS-Z9).++- `identity.subject-ref@1` gains the **agent** subject (`agt_<ULID>`): an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated. `ids` knows the `agt` and `cnf` prefixes; `principalSub` accepts agents (`agent:agt_…`).++- `events.event-envelope@1`: optional `on_behalf_of`, the person or project an agent or app acted for.++- `capabilities.capability@1`: optional `sensitive`. Sixteen capabilities with external side effects are marked (money movement, publishing, sending messages, deleting): an agent needs its owner's confirmation for them unless a standing rule covers it.++- `network.confirmation-request@1`: a sensitive action waiting for its owner (pending, approved, denied, expired, cancelled; once, session, until, always).++- `events.delivery-policy@1`: an event type's delivery class (realtime_ephemeral … webhook), durability, per-key ordering, latency targets, retention tiers, routing objective, batching, residency and a payload ceiling of 64 KB.++- The fabric (`platform.*`, first-party): `resource-offer@1` (a node's or provider's capabilities, multidimensional capacity, latency, health, pricing), `workload-requirements@1`, `placement-result@1` (the explain answer), `placement-plan@1` (signed, expiring route plans), `rate-card@1` (a provider price in its real unit, with its free allowance, source and verification date), `provider-state@1` (usage, forecast, reserve), `cost-snapshot@1` (with counterfactuals), `capacity-snapshot@1`.++- The resource index: `common.resource-summary@1` and `common.resource-list-result@1` (GET /api/v1/resources in every service); `common.resource-cost@1` (a charge in weighted cost units with an idempotency key).++- Fixtures for each, and the regenerated OpenAPI and JSON Schema bundle.++## 0.76.0 — 2026-09-28**The node registry** (ADR-034 section 12; roadmap WS-X1).@@@ -19,6 +19,7 @@"resourceConstraints": { "type": "array", "items": { "enum": ["namespace", "owner", "room_member", "space_member", "project", "none"] } },"quotaClass": { "type": "string" },"events": { "type": "array", "items": { "type": "string" } },-- "implementedBy": { "type": "array", "items": { "type": "string" }, "description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'." }++ "implementedBy": { "type": "array", "items": { "type": "string" }, "description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'." },++ "sensitive": { "type": "boolean", "description": "The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2)." }}}@@@ -5003,6 +5003,136 @@"compatibility": "backward","status": "active","adr": "ADR-034"++ },++ {++ "id": "platform.resource-offer",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/resource-offer.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.workload-requirements",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/workload-requirements.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.placement-result",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/placement-result.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.placement-plan",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/placement-plan.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.rate-card",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/rate-card.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.provider-state",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/provider-state.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.cost-snapshot",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/cost-snapshot.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "platform.capacity-snapshot",++ "version": "1.0.0",++ "owner": "network",++ "schema": "platform/capacity-snapshot.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "events.delivery-policy",++ "version": "1.0.0",++ "owner": "events",++ "schema": "events/delivery-policy.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "common.resource-summary",++ "version": "1.0.0",++ "owner": "contracts",++ "schema": "common/resource-summary.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "common.resource-list-result",++ "version": "1.0.0",++ "owner": "contracts",++ "schema": "common/resource-list-result.v1.json",++ "visibility": "public",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "common.resource-cost",++ "version": "1.0.0",++ "owner": "contracts",++ "schema": "common/resource-cost.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"++ },++ {++ "id": "network.confirmation-request",++ "version": "1.0.0",++ "owner": "network",++ "schema": "network/confirmation-request.v1.json",++ "visibility": "first-party",++ "compatibility": "backward",++ "status": "active",++ "adr": "ADR-034"}]}nnew file mode 100644@@@ -0,0 +1,68 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-cost.v1.json",++ "title": "ResourceCost",++ "description": "One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "subject",++ "unit",++ "amount",++ "state",++ "idempotency_key",++ "service",++ "at"++ ],++ "properties": {++ "subject": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "unit": {++ "type": "string",++ "enum": [++ "browser-second",++ "ai-token",++ "ai-usd",++ "gpu-second",++ "video-minute",++ "bandwidth-byte",++ "storage-byte-day",++ "event",++ "watch-check",++ "bot-control-second",++ "job-run",++ "upload-byte",++ "download-byte"++ ]++ },++ "amount": {++ "type": "number",++ "minimum": 0++ },++ "state": {++ "type": "string",++ "enum": [++ "reserved",++ "committed",++ "released"++ ]++ },++ "idempotency_key": {++ "type": "string",++ "minLength": 8,++ "maxLength": 200++ },++ "service": {++ "type": "string"++ },++ "at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,26 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-list-result.v1.json",++ "title": "ResourceListResult",++ "description": "A page of the resource index (roadmap WS-Z7).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "resources",++ "next_cursor"++ ],++ "properties": {++ "resources": {++ "type": "array",++ "items": {++ "$ref": "resource-summary.v1.json"++ }++ },++ "next_cursor": {++ "type": [++ "string",++ "null"++ ]++ }++ }++}nnew file mode 100644@@@ -0,0 +1,75 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-summary.v1.json",++ "title": "ResourceSummary",++ "description": "One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "kind",++ "service",++ "state",++ "created_at"++ ],++ "properties": {++ "id": {++ "type": "string"++ },++ "kind": {++ "type": "string",++ "description": "service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription"++ },++ "service": {++ "type": "string"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "name": {++ "type": "string"++ },++ "state": {++ "type": "string"++ },++ "created_at": {++ "type": "string",++ "format": "date-time"++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ },++ "usage": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "cost units by name (WS-Z1)"++ },++ "links": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "self": {++ "type": "string",++ "format": "uri"++ },++ "console": {++ "type": "string",++ "format": "uri"++ },++ "docs": {++ "type": "string",++ "format": "uri"++ }++ }++ }++ }++}nnew file mode 100644@@@ -0,0 +1,140 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/delivery-policy.v1.json",++ "title": "DeliveryPolicy",++ "description": "How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "class",++ "durability",++ "delivery_semantics"++ ],++ "properties": {++ "class": {++ "type": "string",++ "enum": [++ "realtime_ephemeral",++ "interactive",++ "interactive_durable",++ "domain",++ "critical",++ "background",++ "bulk",++ "webhook"++ ]++ },++ "durability": {++ "type": "string",++ "enum": [++ "none",++ "optional",++ "required"++ ]++ },++ "delivery_semantics": {++ "type": "string",++ "enum": [++ "at_most_once",++ "at_least_once"++ ]++ },++ "ordering": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "scope": {++ "type": "string"++ },++ "key": {++ "type": "string"++ }++ },++ "required": [++ "scope",++ "key"++ ]++ },++ "latency": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "target_p95_ms": {++ "type": "number",++ "minimum": 0++ },++ "maximum_p95_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "retention": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "hot": {++ "type": "string",++ "pattern": "^[0-9]+[hdm]$"++ },++ "replay": {++ "type": "string",++ "pattern": "^[0-9]+[hdm]$"++ },++ "archive": {++ "type": "string",++ "pattern": "^[0-9]+[hdmy]$"++ }++ }++ },++ "routing": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "objective": {++ "type": "string",++ "enum": [++ "latency_first",++ "cheapest",++ "balanced",++ "correctness"++ ]++ },++ "multi_provider": {++ "type": "boolean"++ }++ }++ },++ "batching": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "max_messages": {++ "type": "integer",++ "minimum": 1++ },++ "max_delay_ms": {++ "type": "integer",++ "minimum": 0++ }++ }++ },++ "residency": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "inherit_project_region": {++ "type": "boolean"++ },++ "region": {++ "type": "string"++ }++ }++ },++ "max_payload_bytes": {++ "type": "integer",++ "minimum": 1,++ "maximum": 65536++ }++ }++}@@@ -13,6 +13,7 @@"version": { "type": "integer", "minimum": 1 },"source": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" },"actor": { "$ref": "../identity/subject-ref.v1.json" },++ "on_behalf_of": { "$ref": "../identity/subject-ref.v1.json" },"timestamp": { "type": "string", "format": "date-time" },"priority": { "enum": ["critical", "important", "low"], "default": "important" },"visibility": { "enum": ["public", "subject", "internal"], "default": "internal" },@@@ -96,6 +96,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]}nnew file mode 100644@@@ -0,0 +1,80 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/network/confirmation-request.v1.json",++ "title": "ConfirmationRequest",++ "description": "A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "owner",++ "requested_by",++ "capability",++ "summary",++ "state",++ "expires_at",++ "created_at"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^cnf_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "requested_by": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]*\\.[a-z0-9-]+\\.[a-z0-9-]+$"++ },++ "summary": {++ "type": "string",++ "maxLength": 500++ },++ "details": {++ "type": "object",++ "additionalProperties": true,++ "properties": {}++ },++ "resources": {++ "type": "array",++ "items": {++ "$ref": "../common/entity-ref.v1.json"++ }++ },++ "state": {++ "type": "string",++ "enum": [++ "pending",++ "approved",++ "denied",++ "expired",++ "cancelled"++ ]++ },++ "standing_rule": {++ "type": "string",++ "enum": [++ "once",++ "session",++ "until",++ "always"++ ]++ },++ "expires_at": {++ "type": "string",++ "format": "date-time"++ },++ "decided_at": {++ "type": "string",++ "format": "date-time"++ },++ "created_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,179 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/capacity-snapshot.v1.json",++ "title": "CapacitySnapshot",++ "description": "A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "node_id",++ "capacity",++ "reported_at"++ ],++ "properties": {++ "node_id": {++ "type": "string"++ },++ "cell": {++ "type": "string"++ },++ "capacity": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_cores": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "memory": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_mb": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "network": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "ingress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "egress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "available_mbps": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "disk": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "iops_available": {++ "type": "number",++ "minimum": 0++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "gpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "type": {++ "type": "string"++ },++ "vram_free_mb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "workers": {++ "type": "object",++ "additionalProperties": {++ "type": "integer",++ "minimum": 0++ },++ "properties": {},++ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"++ },++ "queues": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "depth": {++ "type": "integer",++ "minimum": 0++ },++ "oldest_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "properties": {},++ "description": "queue depth and age by name"++ },++ "event_loop_lag_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "services": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "instances": {++ "type": "integer",++ "minimum": 0++ },++ "active_requests": {++ "type": "integer",++ "minimum": 0++ },++ "p50_ms": {++ "type": "number",++ "minimum": 0++ },++ "p95_ms": {++ "type": "number",++ "minimum": 0++ },++ "error_rate": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "properties": {}++ },++ "reported_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,79 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/cost-snapshot.v1.json",++ "title": "CostSnapshot",++ "description": "Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "window_start",++ "window_end",++ "scope",++ "by_target",++ "actual_usd"++ ],++ "properties": {++ "window_start": {++ "type": "string",++ "format": "date-time"++ },++ "window_end": {++ "type": "string",++ "format": "date-time"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "scope": {++ "type": "string",++ "description": "events, jobs, ai, media, …"++ },++ "by_target": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "units": {++ "type": "number",++ "minimum": 0++ },++ "cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "p50_ms": {++ "type": "number",++ "minimum": 0++ },++ "p95_ms": {++ "type": "number",++ "minimum": 0++ }++ },++ "required": [++ "id",++ "units",++ "cost_usd"++ ]++ }++ },++ "actual_usd": {++ "type": "number",++ "minimum": 0++ },++ "counterfactual_usd": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "e.g. all_local, all_provider, lowest_latency"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,89 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/placement-plan.v1.json",++ "title": "PlacementPlan",++ "description": "A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "epoch",++ "issued_at",++ "expires_at",++ "issuer",++ "key_id",++ "routes",++ "signature"++ ],++ "properties": {++ "epoch": {++ "type": "integer",++ "minimum": 1++ },++ "issued_at": {++ "type": "string",++ "format": "date-time"++ },++ "expires_at": {++ "type": "string",++ "format": "date-time"++ },++ "issuer": {++ "type": "string"++ },++ "key_id": {++ "type": "string"++ },++ "routes": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "route": {++ "type": "string",++ "description": "a route name: an event delivery class and scope, a workload kind, a service"++ },++ "targets": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "weight": {++ "type": "number",++ "minimum": 0++ }++ },++ "required": [++ "id",++ "weight"++ ]++ },++ "minItems": 1++ },++ "draining": {++ "type": "array",++ "items": {++ "type": "string"++ }++ },++ "since_epoch": {++ "type": "integer",++ "minimum": 1++ }++ },++ "required": [++ "route",++ "targets"++ ]++ }++ },++ "signature": {++ "type": "string",++ "description": "Ed25519 over the canonical JSON of every other field, base64url"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,85 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/placement-result.v1.json",++ "title": "PlacementResult",++ "description": "Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "selected",++ "objective",++ "candidates",++ "decided_at"++ ],++ "properties": {++ "selected": {++ "type": "string"++ },++ "objective": {++ "type": "string",++ "enum": [++ "cheapest",++ "lowest-latency",++ "balanced",++ "private",++ "local-only",++ "first-party-only",++ "high-reliability",++ "correctness"++ ]++ },++ "reasons": {++ "type": "array",++ "items": {++ "type": "string"++ }++ },++ "candidates": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "eligible": {++ "type": "boolean"++ },++ "excluded_because": {++ "type": "string"++ },++ "estimated_cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "estimated_latency_ms": {++ "type": "number",++ "minimum": 0++ },++ "score": {++ "type": "number"++ },++ "reasons": {++ "type": "array",++ "items": {++ "type": "string"++ }++ }++ },++ "required": [++ "id",++ "eligible"++ ]++ }++ },++ "plan_epoch": {++ "type": "integer",++ "minimum": 0++ },++ "decided_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,68 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/provider-state.v1.json",++ "title": "ProviderState",++ "description": "A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "provider",++ "period_start",++ "period_end",++ "usage",++ "updated_at"++ ],++ "properties": {++ "provider": {++ "type": "string"++ },++ "period_start": {++ "type": "string",++ "format": "date-time"++ },++ "period_end": {++ "type": "string",++ "format": "date-time"++ },++ "usage": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "used units per rate-card metric"++ },++ "forecast": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "projected units at period end"++ },++ "reserve": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "properties": {},++ "description": "share of each free allowance kept for higher-priority classes"++ },++ "health": {++ "type": "string",++ "enum": [++ "up",++ "degraded",++ "down"++ ]++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,74 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/rate-card.v1.json",++ "title": "RateCard",++ "description": "One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "provider",++ "metric",++ "unit_size",++ "unit_price_usd",++ "free_allowance",++ "reset_period",++ "effective_from",++ "source",++ "verified_at"++ ],++ "properties": {++ "id": {++ "type": "string"++ },++ "provider": {++ "type": "string"++ },++ "adapter": {++ "type": "string"++ },++ "metric": {++ "type": "string",++ "description": "e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op"++ },++ "unit_size": {++ "type": "number",++ "minimum": 0++ },++ "unit_price_usd": {++ "type": "number",++ "minimum": 0++ },++ "free_allowance": {++ "type": "number",++ "minimum": 0++ },++ "reset_period": {++ "type": "string",++ "enum": [++ "day",++ "month",++ "none"++ ]++ },++ "region": {++ "type": "string"++ },++ "effective_from": {++ "type": "string",++ "format": "date"++ },++ "effective_until": {++ "type": "string",++ "format": "date"++ },++ "source": {++ "type": "string",++ "format": "uri"++ },++ "verified_at": {++ "type": "string",++ "format": "date"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,260 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/resource-offer.v1.json",++ "title": "ResourceOffer",++ "description": "What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "offer_id",++ "kind",++ "region",++ "trust",++ "capabilities",++ "health",++ "pricing",++ "updated_at"++ ],++ "properties": {++ "offer_id": {++ "type": "string"++ },++ "kind": {++ "type": "string",++ "enum": [++ "node",++ "provider"++ ]++ },++ "node_id": {++ "type": "string",++ "description": "network.node@1 id, for kind node"++ },++ "provider": {++ "type": "string",++ "description": "provider or hosting company"++ },++ "adapter": {++ "type": "string",++ "description": "carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)"++ },++ "region": {++ "type": "string"++ },++ "cell": {++ "type": "string"++ },++ "trust": {++ "type": "string",++ "enum": [++ "first-party",++ "partner",++ "community",++ "external"++ ]++ },++ "capabilities": {++ "type": "array",++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"++ },++ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2"++ },++ "capacity": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_cores": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "memory": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_mb": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "network": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "ingress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "egress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "available_mbps": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "disk": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "iops_available": {++ "type": "number",++ "minimum": 0++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "gpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "type": {++ "type": "string"++ },++ "vram_free_mb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "workers": {++ "type": "object",++ "additionalProperties": {++ "type": "integer",++ "minimum": 0++ },++ "properties": {},++ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"++ },++ "queues": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "depth": {++ "type": "integer",++ "minimum": 0++ },++ "oldest_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "properties": {},++ "description": "queue depth and age by name"++ },++ "event_loop_lag_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "latency_ms": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "measured p50/p95 by operation, e.g. publish_p95, ack_p95"++ },++ "health": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "status": {++ "type": "string",++ "enum": [++ "up",++ "degraded",++ "down",++ "draining"++ ]++ },++ "error_rate": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "checked_at": {++ "type": "string",++ "format": "date-time"++ }++ },++ "required": [++ "status"++ ]++ },++ "pricing": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "model": {++ "type": "string",++ "enum": [++ "prepaid",++ "per-request",++ "per-byte",++ "per-operation",++ "per-second",++ "free-allowance",++ "mixed"++ ]++ },++ "marginal_usd_per_unit": {++ "type": "number",++ "minimum": 0++ },++ "unit": {++ "type": "string"++ },++ "rate_card": {++ "type": "string",++ "description": "platform.rate-card id when the price comes from one"++ }++ },++ "required": [++ "model"++ ]++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,138 @@++{++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/workload-requirements.v1.json",++ "title": "WorkloadRequirements",++ "description": "What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "kind",++ "mobility",++ "latency_class",++ "objective"++ ],++ "properties": {++ "kind": {++ "type": "string",++ "description": "what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver"++ },++ "mobility": {++ "type": "string",++ "enum": [++ "request",++ "job",++ "session",++ "stateful-partition"++ ]++ },++ "latency_class": {++ "type": "string",++ "enum": [++ "realtime",++ "interactive",++ "background",++ "bulk",++ "critical"++ ]++ },++ "objective": {++ "type": "string",++ "enum": [++ "cheapest",++ "lowest-latency",++ "balanced",++ "private",++ "local-only",++ "first-party-only",++ "high-reliability",++ "correctness"++ ]++ },++ "max_latency_ms": {++ "type": "number",++ "minimum": 0++ },++ "deadline_ms": {++ "type": "number",++ "minimum": 0++ },++ "max_cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "durability": {++ "type": "string",++ "enum": [++ "none",++ "at-least-once",++ "authoritative"++ ]++ },++ "residency": {++ "type": "string",++ "description": "region or jurisdiction the work and its data must stay in"++ },++ "trust": {++ "type": "array",++ "items": {++ "type": "string",++ "enum": [++ "first-party",++ "partner",++ "community",++ "external"++ ]++ },++ "minItems": 1,++ "description": "trust levels allowed to run it"++ },++ "region": {++ "type": "string",++ "description": "a region, or 'nearest'"++ },++ "capabilities": {++ "type": "array",++ "items": {++ "type": "string"++ },++ "description": "capabilities a candidate must offer (worker:browser, …)"++ },++ "resources": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "number",++ "minimum": 0++ },++ "memory_mb": {++ "type": "number",++ "minimum": 0++ },++ "gpu": {++ "type": "boolean"++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "egress": {++ "type": "string",++ "enum": [++ "none",++ "public",++ "openvibe-only"++ ]++ }++ }++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "partition_key": {++ "type": "string",++ "description": "stable key for rendezvous placement (room, stream, session)"++ }++ }++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "subject": {++ "type": "user",++ "id": "usr_01J0000000000000000000000A"++ },++ "unit": "job-run",++ "amount": 1,++ "state": "reserved",++ "idempotency_key": "k",++ "service": "x",++ "at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "subject": {++ "type": "user",++ "id": "usr_01J0000000000000000000000A"++ },++ "unit": "coins",++ "amount": 1,++ "state": "committed",++ "idempotency_key": "abcdefgh",++ "service": "x",++ "at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,13 @@++{++ "subject": {++ "type": "agent",++ "id": "agt_01J0000000000000000000000A"++ },++ "project_id": "prj_01J0000000000000000000000A",++ "unit": "browser-second",++ "amount": 12.5,++ "state": "committed",++ "idempotency_key": "run_01J-step-4",++ "service": "actor",++ "at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,3 @@++{++ "resources": []++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "resources": [++ {++ "id": "sub_1",++ "kind": "events.subscription",++ "service": "events",++ "state": "enabled",++ "created_at": "2026-09-28T23:00:00Z"++ }++ ],++ "next_cursor": null++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "id": "x",++ "kind": "watch.watch",++ "service": "watch",++ "created_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,19 @@++{++ "id": "wch_01J0000000000000000000000A",++ "kind": "watch.watch",++ "service": "watch",++ "project_id": "prj_01J0000000000000000000000A",++ "owner": {++ "type": "user",++ "id": "usr_01J0000000000000000000000A"++ },++ "name": "Price of a camera",++ "state": "active",++ "created_at": "2026-09-28T23:00:00Z",++ "usage": {++ "watch-check": 120++ },++ "links": {++ "self": "https://openvibe.watch/api/v1/watches/wch_01J0000000000000000000000A"++ }++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "class": "domain",++ "durability": "required",++ "delivery_semantics": "at_least_once",++ "max_payload_bytes": 1048576++}nnew file mode 100644@@@ -0,0 +1,5 @@++{++ "class": "fast",++ "durability": "required",++ "delivery_semantics": "at_least_once"++}nnew file mode 100644@@@ -0,0 +1,25 @@++{++ "class": "interactive_durable",++ "durability": "required",++ "delivery_semantics": "at_least_once",++ "ordering": {++ "scope": "room",++ "key": "room_id"++ },++ "latency": {++ "target_p95_ms": 50,++ "maximum_p95_ms": 100++ },++ "retention": {++ "hot": "7d",++ "replay": "30d",++ "archive": "365d"++ },++ "routing": {++ "objective": "latency_first",++ "multi_provider": true++ },++ "residency": {++ "inherit_project_region": true++ }++}nnew file mode 100644@@@ -0,0 +1,15 @@++{++ "class": "bulk",++ "durability": "optional",++ "delivery_semantics": "at_least_once",++ "latency": {++ "maximum_p95_ms": 30000++ },++ "routing": {++ "objective": "cheapest"++ },++ "batching": {++ "max_messages": 1000,++ "max_delay_ms": 5000++ }++}nnew file mode 100644@@@ -0,0 +1,4 @@++{++ "type": "agent",++ "id": "agt_01J0000000000000000000000A"++}nnew file mode 100644@@@ -0,0 +1,16 @@++{++ "id": "cnf_x",++ "owner": {++ "type": "user",++ "id": "usr_01J0000000000000000000000A"++ },++ "requested_by": {++ "type": "agent",++ "id": "agt_01J0000000000000000000000A"++ },++ "capability": "a.b.c",++ "summary": "s",++ "state": "pending",++ "expires_at": "2026-09-28T23:00:00Z",++ "created_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,17 @@++{++ "id": "cnf_01J0000000000000000000000A",++ "owner": {++ "type": "user",++ "id": "usr_01J0000000000000000000000A"++ },++ "requested_by": {++ "type": "agent",++ "id": "agt_01J0000000000000000000000A"++ },++ "capability": "work.application.submit",++ "summary": "Submit your application to Example Co for Backend Engineer",++ "state": "pending",++ "standing_rule": "once",++ "expires_at": "2026-09-29T23:00:00Z",++ "created_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,9 @@++{++ "node_id": "n",++ "capacity": {++ "cpu": {++ "utilization": 1.5++ }++ },++ "reported_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,22 @@++{++ "node_id": "ovh-oregon-1",++ "cell": "wnam-1",++ "capacity": {++ "cpu": {++ "utilization": 0.37++ },++ "memory": {++ "utilization": 0.51++ },++ "event_loop_lag_ms": 4++ },++ "services": {++ "chat": {++ "instances": 1,++ "active_requests": 12,++ "p95_ms": 12.8,++ "error_rate": 0.0003++ }++ },++ "reported_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "window_start": "2026-09-28T23:00:00Z",++ "window_end": "2026-09-28T23:00:00Z",++ "scope": "events",++ "actual_usd": 0++}nnew file mode 100644@@@ -0,0 +1,18 @@++{++ "window_start": "2026-09-28T00:00:00Z",++ "window_end": "2026-09-29T00:00:00Z",++ "scope": "events",++ "by_target": [++ {++ "id": "pg-delivery",++ "units": 18294,++ "cost_usd": 0,++ "p50_ms": 11,++ "p95_ms": 37++ }++ ],++ "actual_usd": 0,++ "counterfactual_usd": {++ "all_provider": 0.02++ }++}nnew file mode 100644@@@ -0,0 +1,14 @@++{++ "epoch": 1,++ "issued_at": "2026-09-28T23:00:00Z",++ "expires_at": "2026-09-28T23:00:00Z",++ "issuer": "network",++ "key_id": "k",++ "routes": [++ {++ "route": "r",++ "targets": []++ }++ ],++ "signature": "s"++}nnew file mode 100644@@@ -0,0 +1,8 @@++{++ "epoch": 43,++ "issued_at": "2026-09-28T23:00:00Z",++ "expires_at": "2026-09-28T23:00:00Z",++ "issuer": "network",++ "key_id": "k",++ "routes": []++}nnew file mode 100644@@@ -0,0 +1,23 @@++{++ "epoch": 43,++ "issued_at": "2026-09-28T23:00:00Z",++ "expires_at": "2026-09-29T00:00:00Z",++ "issuer": "network",++ "key_id": "route-2026-09",++ "routes": [++ {++ "route": "events:background",++ "targets": [++ {++ "id": "valkey-streams",++ "weight": 1++ }++ ],++ "draining": [++ "pg-delivery"++ ],++ "since_epoch": 43++ }++ ],++ "signature": "c2lnbmF0dXJl"++}nnew file mode 100644@@@ -0,0 +1,5 @@++{++ "selected": "a",++ "objective": "balanced",++ "decided_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,25 @@++{++ "selected": "off_oregon_1",++ "objective": "balanced",++ "reasons": [++ "meets the latency target",++ "already-paid capacity available",++ "estimated marginal cost 0"++ ],++ "candidates": [++ {++ "id": "off_oregon_1",++ "eligible": true,++ "estimated_cost_usd": 0,++ "estimated_latency_ms": 31,++ "score": 0.041++ },++ {++ "id": "off_community_331",++ "eligible": false,++ "excluded_because": "workload requires first-party trust"++ }++ ],++ "plan_epoch": 42,++ "decided_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "provider": "p",++ "period_start": "2026-09-28T23:00:00Z",++ "period_end": "2026-09-28T23:00:00Z",++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,16 @@++{++ "provider": "example-queues",++ "period_start": "2026-09-01T00:00:00Z",++ "period_end": "2026-10-01T00:00:00Z",++ "usage": {++ "queue-operation-64kb": 430000++ },++ "forecast": {++ "queue-operation-64kb": 1930000++ },++ "reserve": {++ "queue-operation-64kb": 0.2++ },++ "health": "up",++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,12 @@++{++ "id": "rc",++ "provider": "p",++ "metric": "m",++ "unit_size": 1,++ "unit_price_usd": -1,++ "free_allowance": 0,++ "reset_period": "month",++ "effective_from": "2026-09-01",++ "source": "https://example.com",++ "verified_at": "2026-09-28"++}nnew file mode 100644@@@ -0,0 +1,11 @@++{++ "id": "rc",++ "provider": "p",++ "metric": "m",++ "unit_size": 1,++ "unit_price_usd": 1,++ "free_allowance": 0,++ "reset_period": "month",++ "effective_from": "2026-09-01",++ "verified_at": "2026-09-28"++}nnew file mode 100644@@@ -0,0 +1,13 @@++{++ "id": "rc_example_queue_ops",++ "provider": "example-queues",++ "adapter": "example-queue-v1",++ "metric": "queue-operation-64kb",++ "unit_size": 1000000,++ "unit_price_usd": 0.4,++ "free_allowance": 1000000,++ "reset_period": "month",++ "effective_from": "2026-09-01",++ "source": "https://example.com/pricing",++ "verified_at": "2026-09-28"++}nnew file mode 100644@@@ -0,0 +1,16 @@++{++ "offer_id": "x",++ "kind": "node",++ "region": "us-west",++ "trust": "first-party",++ "capabilities": [++ "Browser"++ ],++ "health": {++ "status": "up"++ },++ "pricing": {++ "model": "prepaid"++ },++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,13 @@++{++ "offer_id": "x",++ "kind": "node",++ "region": "us-west",++ "trust": "first-party",++ "capabilities": [++ "node:http"++ ],++ "pricing": {++ "model": "prepaid"++ },++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,46 @@++{++ "offer_id": "off_oregon_1",++ "kind": "node",++ "node_id": "ovh-oregon-1",++ "provider": "ovh",++ "region": "us-west",++ "cell": "wnam-1",++ "trust": "first-party",++ "capabilities": [++ "node:http",++ "worker:browser",++ "worker:ffmpeg",++ "events:durable"++ ],++ "capacity": {++ "cpu": {++ "utilization": 0.31,++ "available_cores": 5.5++ },++ "memory": {++ "available_mb": 18300++ },++ "workers": {++ "browser": 6,++ "ffmpeg": 3++ },++ "queues": {++ "media-jobs": {++ "depth": 2,++ "oldest_ms": 40++ }++ }++ },++ "latency_ms": {++ "publish_p95": 3.1++ },++ "health": {++ "status": "up"++ },++ "pricing": {++ "model": "prepaid",++ "marginal_usd_per_unit": 0,++ "unit": "job"++ },++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,21 @@++{++ "offer_id": "off_cf_queue",++ "kind": "provider",++ "provider": "cloudflare",++ "adapter": "cf-queue-v1",++ "region": "global",++ "trust": "external",++ "capabilities": [++ "events:queue",++ "events:durable"++ ],++ "health": {++ "status": "up",++ "error_rate": 0.0001++ },++ "pricing": {++ "model": "per-operation",++ "rate_card": "rc_cf_queue_ops"++ },++ "updated_at": "2026-09-28T23:00:00Z"++}nnew file mode 100644@@@ -0,0 +1,5 @@++{++ "kind": "x",++ "latency_class": "background",++ "objective": "cheapest"++}nnew file mode 100644@@@ -0,0 +1,6 @@++{++ "kind": "x",++ "mobility": "job",++ "latency_class": "background",++ "objective": "free"++}nnew file mode 100644@@@ -0,0 +1,22 @@++{++ "kind": "watch.browser",++ "mobility": "job",++ "latency_class": "interactive",++ "objective": "balanced",++ "max_latency_ms": 1000,++ "max_cost_usd": 0.002,++ "durability": "at-least-once",++ "trust": [++ "first-party",++ "partner"++ ],++ "region": "nearest",++ "capabilities": [++ "worker:browser"++ ],++ "resources": {++ "cpu": 2,++ "memory_mb": 1024,++ "egress": "public"++ }++}nnew file mode 100644@@@ -0,0 +1,7 @@++{++ "kind": "billing.post",++ "mobility": "stateful-partition",++ "latency_class": "critical",++ "objective": "correctness",++ "durability": "authoritative"++}@@@ -103,6 +103,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]}@@@ -1312,6 +1330,10 @@"type": "string"},"description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'."++ },++ "sensitive": {++ "type": "boolean",++ "description": "The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2)."}}}@@@ -1361,6 +1383,9 @@"actor": {"$ref": "../identity/subject-ref.v1.json"},++ "on_behalf_of": {++ "$ref": "../identity/subject-ref.v1.json"++ },"timestamp": {"type": "string","format": "date-time"@@@ -55204,6 +55229,1432 @@}}}++ },++ "platform.resource-offer": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/resource-offer.v1.json",++ "title": "ResourceOffer",++ "description": "What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "offer_id",++ "kind",++ "region",++ "trust",++ "capabilities",++ "health",++ "pricing",++ "updated_at"++ ],++ "properties": {++ "offer_id": {++ "type": "string"++ },++ "kind": {++ "type": "string",++ "enum": [++ "node",++ "provider"++ ]++ },++ "node_id": {++ "type": "string",++ "description": "network.node@1 id, for kind node"++ },++ "provider": {++ "type": "string",++ "description": "provider or hosting company"++ },++ "adapter": {++ "type": "string",++ "description": "carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)"++ },++ "region": {++ "type": "string"++ },++ "cell": {++ "type": "string"++ },++ "trust": {++ "type": "string",++ "enum": [++ "first-party",++ "partner",++ "community",++ "external"++ ]++ },++ "capabilities": {++ "type": "array",++ "items": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"++ },++ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2"++ },++ "capacity": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_cores": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "memory": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_mb": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "network": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "ingress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "egress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "available_mbps": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "disk": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "iops_available": {++ "type": "number",++ "minimum": 0++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "gpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "type": {++ "type": "string"++ },++ "vram_free_mb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "workers": {++ "type": "object",++ "additionalProperties": {++ "type": "integer",++ "minimum": 0++ },++ "properties": {},++ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"++ },++ "queues": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "depth": {++ "type": "integer",++ "minimum": 0++ },++ "oldest_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "properties": {},++ "description": "queue depth and age by name"++ },++ "event_loop_lag_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "latency_ms": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "measured p50/p95 by operation, e.g. publish_p95, ack_p95"++ },++ "health": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "status": {++ "type": "string",++ "enum": [++ "up",++ "degraded",++ "down",++ "draining"++ ]++ },++ "error_rate": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "checked_at": {++ "type": "string",++ "format": "date-time"++ }++ },++ "required": [++ "status"++ ]++ },++ "pricing": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "model": {++ "type": "string",++ "enum": [++ "prepaid",++ "per-request",++ "per-byte",++ "per-operation",++ "per-second",++ "free-allowance",++ "mixed"++ ]++ },++ "marginal_usd_per_unit": {++ "type": "number",++ "minimum": 0++ },++ "unit": {++ "type": "string"++ },++ "rate_card": {++ "type": "string",++ "description": "platform.rate-card id when the price comes from one"++ }++ },++ "required": [++ "model"++ ]++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "platform.workload-requirements": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/workload-requirements.v1.json",++ "title": "WorkloadRequirements",++ "description": "What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "kind",++ "mobility",++ "latency_class",++ "objective"++ ],++ "properties": {++ "kind": {++ "type": "string",++ "description": "what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver"++ },++ "mobility": {++ "type": "string",++ "enum": [++ "request",++ "job",++ "session",++ "stateful-partition"++ ]++ },++ "latency_class": {++ "type": "string",++ "enum": [++ "realtime",++ "interactive",++ "background",++ "bulk",++ "critical"++ ]++ },++ "objective": {++ "type": "string",++ "enum": [++ "cheapest",++ "lowest-latency",++ "balanced",++ "private",++ "local-only",++ "first-party-only",++ "high-reliability",++ "correctness"++ ]++ },++ "max_latency_ms": {++ "type": "number",++ "minimum": 0++ },++ "deadline_ms": {++ "type": "number",++ "minimum": 0++ },++ "max_cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "durability": {++ "type": "string",++ "enum": [++ "none",++ "at-least-once",++ "authoritative"++ ]++ },++ "residency": {++ "type": "string",++ "description": "region or jurisdiction the work and its data must stay in"++ },++ "trust": {++ "type": "array",++ "items": {++ "type": "string",++ "enum": [++ "first-party",++ "partner",++ "community",++ "external"++ ]++ },++ "minItems": 1,++ "description": "trust levels allowed to run it"++ },++ "region": {++ "type": "string",++ "description": "a region, or 'nearest'"++ },++ "capabilities": {++ "type": "array",++ "items": {++ "type": "string"++ },++ "description": "capabilities a candidate must offer (worker:browser, …)"++ },++ "resources": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "number",++ "minimum": 0++ },++ "memory_mb": {++ "type": "number",++ "minimum": 0++ },++ "gpu": {++ "type": "boolean"++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "egress": {++ "type": "string",++ "enum": [++ "none",++ "public",++ "openvibe-only"++ ]++ }++ }++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "partition_key": {++ "type": "string",++ "description": "stable key for rendezvous placement (room, stream, session)"++ }++ }++ }++ },++ "platform.placement-result": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/placement-result.v1.json",++ "title": "PlacementResult",++ "description": "Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "selected",++ "objective",++ "candidates",++ "decided_at"++ ],++ "properties": {++ "selected": {++ "type": "string"++ },++ "objective": {++ "type": "string",++ "enum": [++ "cheapest",++ "lowest-latency",++ "balanced",++ "private",++ "local-only",++ "first-party-only",++ "high-reliability",++ "correctness"++ ]++ },++ "reasons": {++ "type": "array",++ "items": {++ "type": "string"++ }++ },++ "candidates": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "eligible": {++ "type": "boolean"++ },++ "excluded_because": {++ "type": "string"++ },++ "estimated_cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "estimated_latency_ms": {++ "type": "number",++ "minimum": 0++ },++ "score": {++ "type": "number"++ },++ "reasons": {++ "type": "array",++ "items": {++ "type": "string"++ }++ }++ },++ "required": [++ "id",++ "eligible"++ ]++ }++ },++ "plan_epoch": {++ "type": "integer",++ "minimum": 0++ },++ "decided_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "platform.placement-plan": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/placement-plan.v1.json",++ "title": "PlacementPlan",++ "description": "A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "epoch",++ "issued_at",++ "expires_at",++ "issuer",++ "key_id",++ "routes",++ "signature"++ ],++ "properties": {++ "epoch": {++ "type": "integer",++ "minimum": 1++ },++ "issued_at": {++ "type": "string",++ "format": "date-time"++ },++ "expires_at": {++ "type": "string",++ "format": "date-time"++ },++ "issuer": {++ "type": "string"++ },++ "key_id": {++ "type": "string"++ },++ "routes": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "route": {++ "type": "string",++ "description": "a route name: an event delivery class and scope, a workload kind, a service"++ },++ "targets": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "weight": {++ "type": "number",++ "minimum": 0++ }++ },++ "required": [++ "id",++ "weight"++ ]++ },++ "minItems": 1++ },++ "draining": {++ "type": "array",++ "items": {++ "type": "string"++ }++ },++ "since_epoch": {++ "type": "integer",++ "minimum": 1++ }++ },++ "required": [++ "route",++ "targets"++ ]++ }++ },++ "signature": {++ "type": "string",++ "description": "Ed25519 over the canonical JSON of every other field, base64url"++ }++ }++ }++ },++ "platform.rate-card": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/rate-card.v1.json",++ "title": "RateCard",++ "description": "One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "provider",++ "metric",++ "unit_size",++ "unit_price_usd",++ "free_allowance",++ "reset_period",++ "effective_from",++ "source",++ "verified_at"++ ],++ "properties": {++ "id": {++ "type": "string"++ },++ "provider": {++ "type": "string"++ },++ "adapter": {++ "type": "string"++ },++ "metric": {++ "type": "string",++ "description": "e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op"++ },++ "unit_size": {++ "type": "number",++ "minimum": 0++ },++ "unit_price_usd": {++ "type": "number",++ "minimum": 0++ },++ "free_allowance": {++ "type": "number",++ "minimum": 0++ },++ "reset_period": {++ "type": "string",++ "enum": [++ "day",++ "month",++ "none"++ ]++ },++ "region": {++ "type": "string"++ },++ "effective_from": {++ "type": "string",++ "format": "date"++ },++ "effective_until": {++ "type": "string",++ "format": "date"++ },++ "source": {++ "type": "string",++ "format": "uri"++ },++ "verified_at": {++ "type": "string",++ "format": "date"++ }++ }++ }++ },++ "platform.provider-state": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/provider-state.v1.json",++ "title": "ProviderState",++ "description": "A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "provider",++ "period_start",++ "period_end",++ "usage",++ "updated_at"++ ],++ "properties": {++ "provider": {++ "type": "string"++ },++ "period_start": {++ "type": "string",++ "format": "date-time"++ },++ "period_end": {++ "type": "string",++ "format": "date-time"++ },++ "usage": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "used units per rate-card metric"++ },++ "forecast": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "projected units at period end"++ },++ "reserve": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "properties": {},++ "description": "share of each free allowance kept for higher-priority classes"++ },++ "health": {++ "type": "string",++ "enum": [++ "up",++ "degraded",++ "down"++ ]++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "platform.cost-snapshot": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/cost-snapshot.v1.json",++ "title": "CostSnapshot",++ "description": "Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "window_start",++ "window_end",++ "scope",++ "by_target",++ "actual_usd"++ ],++ "properties": {++ "window_start": {++ "type": "string",++ "format": "date-time"++ },++ "window_end": {++ "type": "string",++ "format": "date-time"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "scope": {++ "type": "string",++ "description": "events, jobs, ai, media, …"++ },++ "by_target": {++ "type": "array",++ "items": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "id": {++ "type": "string"++ },++ "units": {++ "type": "number",++ "minimum": 0++ },++ "cost_usd": {++ "type": "number",++ "minimum": 0++ },++ "p50_ms": {++ "type": "number",++ "minimum": 0++ },++ "p95_ms": {++ "type": "number",++ "minimum": 0++ }++ },++ "required": [++ "id",++ "units",++ "cost_usd"++ ]++ }++ },++ "actual_usd": {++ "type": "number",++ "minimum": 0++ },++ "counterfactual_usd": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "e.g. all_local, all_provider, lowest_latency"++ }++ }++ }++ },++ "platform.capacity-snapshot": {++ "version": "1.0.0",++ "owner": "network",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/platform/capacity-snapshot.v1.json",++ "title": "CapacitySnapshot",++ "description": "A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "node_id",++ "capacity",++ "reported_at"++ ],++ "properties": {++ "node_id": {++ "type": "string"++ },++ "cell": {++ "type": "string"++ },++ "capacity": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "cpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_cores": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "memory": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ },++ "available_mb": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "network": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "ingress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "egress_mbps": {++ "type": "number",++ "minimum": 0++ },++ "available_mbps": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "disk": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "iops_available": {++ "type": "number",++ "minimum": 0++ },++ "scratch_gb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "gpu": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "type": {++ "type": "string"++ },++ "vram_free_mb": {++ "type": "number",++ "minimum": 0++ },++ "utilization": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "workers": {++ "type": "object",++ "additionalProperties": {++ "type": "integer",++ "minimum": 0++ },++ "properties": {},++ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"++ },++ "queues": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "depth": {++ "type": "integer",++ "minimum": 0++ },++ "oldest_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "properties": {},++ "description": "queue depth and age by name"++ },++ "event_loop_lag_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "services": {++ "type": "object",++ "additionalProperties": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "instances": {++ "type": "integer",++ "minimum": 0++ },++ "active_requests": {++ "type": "integer",++ "minimum": 0++ },++ "p50_ms": {++ "type": "number",++ "minimum": 0++ },++ "p95_ms": {++ "type": "number",++ "minimum": 0++ },++ "error_rate": {++ "type": "number",++ "minimum": 0,++ "maximum": 1++ }++ }++ },++ "properties": {}++ },++ "reported_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "events.delivery-policy": {++ "version": "1.0.0",++ "owner": "events",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/events/delivery-policy.v1.json",++ "title": "DeliveryPolicy",++ "description": "How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "class",++ "durability",++ "delivery_semantics"++ ],++ "properties": {++ "class": {++ "type": "string",++ "enum": [++ "realtime_ephemeral",++ "interactive",++ "interactive_durable",++ "domain",++ "critical",++ "background",++ "bulk",++ "webhook"++ ]++ },++ "durability": {++ "type": "string",++ "enum": [++ "none",++ "optional",++ "required"++ ]++ },++ "delivery_semantics": {++ "type": "string",++ "enum": [++ "at_most_once",++ "at_least_once"++ ]++ },++ "ordering": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "scope": {++ "type": "string"++ },++ "key": {++ "type": "string"++ }++ },++ "required": [++ "scope",++ "key"++ ]++ },++ "latency": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "target_p95_ms": {++ "type": "number",++ "minimum": 0++ },++ "maximum_p95_ms": {++ "type": "number",++ "minimum": 0++ }++ }++ },++ "retention": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "hot": {++ "type": "string",++ "pattern": "^[0-9]+[hdm]$"++ },++ "replay": {++ "type": "string",++ "pattern": "^[0-9]+[hdm]$"++ },++ "archive": {++ "type": "string",++ "pattern": "^[0-9]+[hdmy]$"++ }++ }++ },++ "routing": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "objective": {++ "type": "string",++ "enum": [++ "latency_first",++ "cheapest",++ "balanced",++ "correctness"++ ]++ },++ "multi_provider": {++ "type": "boolean"++ }++ }++ },++ "batching": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "max_messages": {++ "type": "integer",++ "minimum": 1++ },++ "max_delay_ms": {++ "type": "integer",++ "minimum": 0++ }++ }++ },++ "residency": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "inherit_project_region": {++ "type": "boolean"++ },++ "region": {++ "type": "string"++ }++ }++ },++ "max_payload_bytes": {++ "type": "integer",++ "minimum": 1,++ "maximum": 65536++ }++ }++ }++ },++ "common.resource-summary": {++ "version": "1.0.0",++ "owner": "contracts",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-summary.v1.json",++ "title": "ResourceSummary",++ "description": "One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "kind",++ "service",++ "state",++ "created_at"++ ],++ "properties": {++ "id": {++ "type": "string"++ },++ "kind": {++ "type": "string",++ "description": "service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription"++ },++ "service": {++ "type": "string"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "name": {++ "type": "string"++ },++ "state": {++ "type": "string"++ },++ "created_at": {++ "type": "string",++ "format": "date-time"++ },++ "updated_at": {++ "type": "string",++ "format": "date-time"++ },++ "usage": {++ "type": "object",++ "additionalProperties": {++ "type": "number",++ "minimum": 0++ },++ "properties": {},++ "description": "cost units by name (WS-Z1)"++ },++ "links": {++ "type": "object",++ "additionalProperties": false,++ "properties": {++ "self": {++ "type": "string",++ "format": "uri"++ },++ "console": {++ "type": "string",++ "format": "uri"++ },++ "docs": {++ "type": "string",++ "format": "uri"++ }++ }++ }++ }++ }++ },++ "common.resource-list-result": {++ "version": "1.0.0",++ "owner": "contracts",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-list-result.v1.json",++ "title": "ResourceListResult",++ "description": "A page of the resource index (roadmap WS-Z7).",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "resources",++ "next_cursor"++ ],++ "properties": {++ "resources": {++ "type": "array",++ "items": {++ "$ref": "resource-summary.v1.json"++ }++ },++ "next_cursor": {++ "type": [++ "string",++ "null"++ ]++ }++ }++ }++ },++ "common.resource-cost": {++ "version": "1.0.0",++ "owner": "contracts",++ "status": "active",++ "schema": {++ "$schema": "https://json-schema.org/draft/2020-12/schema",++ "$id": "https://openvibe.network/contracts/common/resource-cost.v1.json",++ "title": "ResourceCost",++ "description": "One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "subject",++ "unit",++ "amount",++ "state",++ "idempotency_key",++ "service",++ "at"++ ],++ "properties": {++ "subject": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "project_id": {++ "type": "string",++ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "unit": {++ "type": "string",++ "enum": [++ "browser-second",++ "ai-token",++ "ai-usd",++ "gpu-second",++ "video-minute",++ "bandwidth-byte",++ "storage-byte-day",++ "event",++ "watch-check",++ "bot-control-second",++ "job-run",++ "upload-byte",++ "download-byte"++ ]++ },++ "amount": {++ "type": "number",++ "minimum": 0++ },++ "state": {++ "type": "string",++ "enum": [++ "reserved",++ "committed",++ "released"++ ]++ },++ "idempotency_key": {++ "type": "string",++ "minLength": 8,++ "maxLength": 200++ },++ "service": {++ "type": "string"++ },++ "at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }++ },++ "network.confirmation-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/confirmation-request.v1.json",++ "title": "ConfirmationRequest",++ "description": "A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.",++ "type": "object",++ "additionalProperties": false,++ "required": [++ "id",++ "owner",++ "requested_by",++ "capability",++ "summary",++ "state",++ "expires_at",++ "created_at"++ ],++ "properties": {++ "id": {++ "type": "string",++ "pattern": "^cnf_[0-9A-HJKMNP-TV-Z]{26}$"++ },++ "owner": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "requested_by": {++ "$ref": "../identity/subject-ref.v1.json"++ },++ "capability": {++ "type": "string",++ "pattern": "^[a-z][a-z0-9-]*\\.[a-z0-9-]+\\.[a-z0-9-]+$"++ },++ "summary": {++ "type": "string",++ "maxLength": 500++ },++ "details": {++ "type": "object",++ "additionalProperties": true,++ "properties": {}++ },++ "resources": {++ "type": "array",++ "items": {++ "$ref": "../common/entity-ref.v1.json"++ }++ },++ "state": {++ "type": "string",++ "enum": [++ "pending",++ "approved",++ "denied",++ "expired",++ "cancelled"++ ]++ },++ "standing_rule": {++ "type": "string",++ "enum": [++ "once",++ "session",++ "until",++ "always"++ ]++ },++ "expires_at": {++ "type": "string",++ "format": "date-time"++ },++ "decided_at": {++ "type": "string",++ "format": "date-time"++ },++ "created_at": {++ "type": "string",++ "format": "date-time"++ }++ }++ }}}}@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.AI API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -5066,6 +5066,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]}@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Billing API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -3362,6 +3362,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]}@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Blog API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1091,6 +1091,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Community API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1082,6 +1082,9 @@"actor": {"$ref": "#/components/schemas/identity.subject-ref.v1"},++ "on_behalf_of": {++ "$ref": "#/components/schemas/identity.subject-ref.v1"++ },"timestamp": {"type": "string","format": "date-time"@@@ -1614,6 +1617,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]}@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Games API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1033,6 +1033,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Host API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.Live API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1953,6 +1953,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.News API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1455,6 +1455,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Reviews API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1680,6 +1680,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Tools API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",-- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -1382,6 +1382,24 @@}},"description": "PrincipalSubject"++ },++ {++ "type": "object",++ "required": [++ "type",++ "id"++ ],++ "additionalProperties": false,++ "properties": {++ "type": {++ "const": "agent"++ },++ "id": {++ "type": "string",++ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"++ }++ },++ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."}]},@@@ -3,8 +3,8 @@"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema","info": {"title": "OpenVibe.Wiki API",-- "version": "0.76.0",-- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",++ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"@@@ -25,6 +25,10 @@ export type SubjectRef =| {type: "service" | "system";id: string;++ }++ | {++ type: "agent";++ id: string;};/** [email protected] (owner: network) */@@@ -529,6 +533,10 @@ export interface Capability {* Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'.*/implementedBy?: string[];++ /**++ * The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2).++ */++ sensitive?: boolean;}/** [email protected] (owner: events) */@@@ -542,6 +550,7 @@ export interface EventEnvelope {version: number;source: string;actor: SubjectRef;++ on_behalf_of?: SubjectRef;timestamp: string;priority?: "critical" | "important" | "low";visibility?: "public" | "subject" | "internal";@@@ -46278,3 +46287,497 @@ export interface NetworkNodeListResult {nodes: NetworkNode[];generated_at: string;}++++/** [email protected] (owner: network) */++/**++ * What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.++ */++export interface ResourceOffer {++ offer_id: string;++ kind: "node" | "provider";++ /**++ * network.node@1 id, for kind node++ */++ node_id?: string;++ /**++ * provider or hosting company++ */++ provider?: string;++ /**++ * carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)++ */++ adapter?: string;++ region: string;++ cell?: string;++ trust: "first-party" | "partner" | "community" | "external";++ /**++ * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2++ */++ capabilities: string[];++ capacity?: {++ cpu?: {++ utilization?: number;++ available_cores?: number;++ };++ memory?: {++ utilization?: number;++ available_mb?: number;++ };++ network?: {++ ingress_mbps?: number;++ egress_mbps?: number;++ available_mbps?: number;++ };++ disk?: {++ iops_available?: number;++ scratch_gb?: number;++ utilization?: number;++ };++ gpu?: {++ type?: string;++ vram_free_mb?: number;++ utilization?: number;++ };++ /**++ * free worker slots by kind (browser, ffmpeg, ai, …)++ */++ workers?: {++ [k: string]: number | undefined;++ };++ /**++ * queue depth and age by name++ */++ queues?: {++ [k: string]:++ | {++ depth?: number;++ oldest_ms?: number;++ }++ | undefined;++ };++ event_loop_lag_ms?: number;++ };++ /**++ * measured p50/p95 by operation, e.g. publish_p95, ack_p95++ */++ latency_ms?: {++ [k: string]: number | undefined;++ };++ health: {++ status: "up" | "degraded" | "down" | "draining";++ error_rate?: number;++ checked_at?: string;++ };++ pricing: {++ model: "prepaid" | "per-request" | "per-byte" | "per-operation" | "per-second" | "free-allowance" | "mixed";++ marginal_usd_per_unit?: number;++ unit?: string;++ /**++ * platform.rate-card id when the price comes from one++ */++ rate_card?: string;++ };++ updated_at: string;++}++++/** [email protected] (owner: network) */++/**++ * What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.++ */++export interface WorkloadRequirements {++ /**++ * what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver++ */++ kind: string;++ mobility: "request" | "job" | "session" | "stateful-partition";++ latency_class: "realtime" | "interactive" | "background" | "bulk" | "critical";++ objective:++ | "cheapest"++ | "lowest-latency"++ | "balanced"++ | "private"++ | "local-only"++ | "first-party-only"++ | "high-reliability"++ | "correctness";++ max_latency_ms?: number;++ deadline_ms?: number;++ max_cost_usd?: number;++ durability?: "none" | "at-least-once" | "authoritative";++ /**++ * region or jurisdiction the work and its data must stay in++ */++ residency?: string;++ /**++ * trust levels allowed to run it++ *++ * @minItems 1++ */++ trust?: [++ "first-party" | "partner" | "community" | "external",++ ...("first-party" | "partner" | "community" | "external")[]++ ];++ /**++ * a region, or 'nearest'++ */++ region?: string;++ /**++ * capabilities a candidate must offer (worker:browser, …)++ */++ capabilities?: string[];++ resources?: {++ cpu?: number;++ memory_mb?: number;++ gpu?: boolean;++ scratch_gb?: number;++ egress?: "none" | "public" | "openvibe-only";++ };++ project_id?: string;++ /**++ * stable key for rendezvous placement (room, stream, session)++ */++ partition_key?: string;++}++++/** [email protected] (owner: network) */++/**++ * Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).++ */++export interface PlacementResult {++ selected: string;++ objective:++ | "cheapest"++ | "lowest-latency"++ | "balanced"++ | "private"++ | "local-only"++ | "first-party-only"++ | "high-reliability"++ | "correctness";++ reasons?: string[];++ candidates: {++ id: string;++ eligible: boolean;++ excluded_because?: string;++ estimated_cost_usd?: number;++ estimated_latency_ms?: number;++ score?: number;++ reasons?: string[];++ }[];++ plan_epoch?: number;++ decided_at: string;++}++++/** [email protected] (owner: network) */++/**++ * A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.++ */++export interface PlacementPlan {++ epoch: number;++ issued_at: string;++ expires_at: string;++ issuer: string;++ key_id: string;++ routes: {++ /**++ * a route name: an event delivery class and scope, a workload kind, a service++ */++ route: string;++ /**++ * @minItems 1++ */++ targets: [++ {++ id: string;++ weight: number;++ },++ ...{++ id: string;++ weight: number;++ }[]++ ];++ draining?: string[];++ since_epoch?: number;++ }[];++ /**++ * Ed25519 over the canonical JSON of every other field, base64url++ */++ signature: string;++}++++/** [email protected] (owner: network) */++/**++ * One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.++ */++export interface RateCard {++ id: string;++ provider: string;++ adapter?: string;++ /**++ * e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op++ */++ metric: string;++ unit_size: number;++ unit_price_usd: number;++ free_allowance: number;++ reset_period: "day" | "month" | "none";++ region?: string;++ effective_from: string;++ effective_until?: string;++ source: string;++ verified_at: string;++}++++/** [email protected] (owner: network) */++/**++ * A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).++ */++export interface ProviderState {++ provider: string;++ period_start: string;++ period_end: string;++ /**++ * used units per rate-card metric++ */++ usage: {++ [k: string]: number | undefined;++ };++ /**++ * projected units at period end++ */++ forecast?: {++ [k: string]: number | undefined;++ };++ /**++ * share of each free allowance kept for higher-priority classes++ */++ reserve?: {++ [k: string]: number | undefined;++ };++ health?: "up" | "degraded" | "down";++ updated_at: string;++}++++/** [email protected] (owner: network) */++/**++ * Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).++ */++export interface CostSnapshot {++ window_start: string;++ window_end: string;++ project_id?: string;++ /**++ * events, jobs, ai, media, …++ */++ scope: string;++ by_target: {++ id: string;++ units: number;++ cost_usd: number;++ p50_ms?: number;++ p95_ms?: number;++ }[];++ actual_usd: number;++ /**++ * e.g. all_local, all_provider, lowest_latency++ */++ counterfactual_usd?: {++ [k: string]: number | undefined;++ };++}++++/** [email protected] (owner: network) */++/**++ * A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).++ */++export interface CapacitySnapshot {++ node_id: string;++ cell?: string;++ capacity: {++ cpu?: {++ utilization?: number;++ available_cores?: number;++ };++ memory?: {++ utilization?: number;++ available_mb?: number;++ };++ network?: {++ ingress_mbps?: number;++ egress_mbps?: number;++ available_mbps?: number;++ };++ disk?: {++ iops_available?: number;++ scratch_gb?: number;++ utilization?: number;++ };++ gpu?: {++ type?: string;++ vram_free_mb?: number;++ utilization?: number;++ };++ /**++ * free worker slots by kind (browser, ffmpeg, ai, …)++ */++ workers?: {++ [k: string]: number | undefined;++ };++ /**++ * queue depth and age by name++ */++ queues?: {++ [k: string]:++ | {++ depth?: number;++ oldest_ms?: number;++ }++ | undefined;++ };++ event_loop_lag_ms?: number;++ };++ services?: {++ [k: string]:++ | {++ instances?: number;++ active_requests?: number;++ p50_ms?: number;++ p95_ms?: number;++ error_rate?: number;++ }++ | undefined;++ };++ reported_at: string;++}++++/** [email protected] (owner: events) */++/**++ * How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.++ */++export interface DeliveryPolicy {++ class:++ | "realtime_ephemeral"++ | "interactive"++ | "interactive_durable"++ | "domain"++ | "critical"++ | "background"++ | "bulk"++ | "webhook";++ durability: "none" | "optional" | "required";++ delivery_semantics: "at_most_once" | "at_least_once";++ ordering?: {++ scope: string;++ key: string;++ };++ latency?: {++ target_p95_ms?: number;++ maximum_p95_ms?: number;++ };++ retention?: {++ hot?: string;++ replay?: string;++ archive?: string;++ };++ routing?: {++ objective?: "latency_first" | "cheapest" | "balanced" | "correctness";++ multi_provider?: boolean;++ };++ batching?: {++ max_messages?: number;++ max_delay_ms?: number;++ };++ residency?: {++ inherit_project_region?: boolean;++ region?: string;++ };++ max_payload_bytes?: number;++}++++/** [email protected] (owner: contracts) */++/**++ * One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.++ */++export interface ResourceSummary {++ id: string;++ /**++ * service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription++ */++ kind: string;++ service: string;++ project_id?: string;++ owner?: SubjectRef;++ name?: string;++ state: string;++ created_at: string;++ updated_at?: string;++ /**++ * cost units by name (WS-Z1)++ */++ usage?: {++ [k: string]: number | undefined;++ };++ links?: {++ self?: string;++ console?: string;++ docs?: string;++ };++}++++/** [email protected] (owner: contracts) */++/**++ * A page of the resource index (roadmap WS-Z7).++ */++export interface ResourceListResult {++ resources: ResourceSummary[];++ next_cursor: string | null;++}++++/** [email protected] (owner: contracts) */++/**++ * One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.++ */++export interface ResourceCost {++ subject: SubjectRef;++ project_id?: string;++ unit:++ | "browser-second"++ | "ai-token"++ | "ai-usd"++ | "gpu-second"++ | "video-minute"++ | "bandwidth-byte"++ | "storage-byte-day"++ | "event"++ | "watch-check"++ | "bot-control-second"++ | "job-run"++ | "upload-byte"++ | "download-byte";++ amount: number;++ state: "reserved" | "committed" | "released";++ idempotency_key: string;++ service: string;++ at: string;++}++++/** [email protected] (owner: network) */++/**++ * A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.++ */++export interface ConfirmationRequest {++ id: string;++ owner: SubjectRef;++ requested_by: SubjectRef;++ capability: string;++ summary: string;++ details?: {++ [k: string]: unknown | undefined;++ };++ resources?: EntityRef[];++ state: "pending" | "approved" | "denied" | "expired" | "cancelled";++ standing_rule?: "once" | "session" | "until" | "always";++ expires_at: string;++ decided_at?: string;++ created_at: string;++}@@@ -6,11 +6,11 @@const crypto = require('crypto');const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';--const PREFIX = { user: 'usr', guest: 'gst', app: 'app', mod: 'mod', event: 'evt', media: 'med', project: 'prj' };++const PREFIX = { user: 'usr', guest: 'gst', app: 'app', mod: 'mod', agent: 'agt', event: 'evt', media: 'med', project: 'prj', confirmation: 'cnf' };const SLUG_TYPES = new Set(['service', 'system']);const ULID_RE = /^[0-9A-HJKMNP-TV-Z]{26}$/;const SLUG_RE = /^[a-z][a-z0-9-]{1,39}$/;--const SUBJECT_TYPES = ['user', 'guest', 'service', 'app', 'mod', 'system'];++const SUBJECT_TYPES = ['user', 'guest', 'service', 'app', 'mod', 'agent', 'system'];function ulid(now = Date.now()) {let time = '';@@@ -50,11 +50,11 @@ function formatSubject(ref) {return `${ref.type}:${ref.id}`;}--/** Service-token `sub` claim: svc:<slug> | app:app_<ULID> | mod:mod_<ULID>. */++/** Service-token `sub` claim: svc:<slug> | app:app_<ULID> | mod:mod_<ULID> | agent:agt_<ULID>. */function principalSub(ref) {if (ref.type === 'service' && SLUG_RE.test(ref.id)) return `svc:${ref.id}`;-- if ((ref.type === 'app' || ref.type === 'mod') && isSubjectId(ref.type, ref.id)) return `${ref.type}:${ref.id}`;-- throw new TypeError('principals are service, app or mod subjects');++ if ((ref.type === 'app' || ref.type === 'mod' || ref.type === 'agent') && isSubjectId(ref.type, ref.id)) return `${ref.type}:${ref.id}`;++ throw new TypeError('principals are service, app, mod or agent subjects');}/** Transitional Media reference for today's rows (Wave 4 introduces med_ ids). */@@@ -4,6 +4,7 @@"owner": "billing","status": "active","visibility": "internal",++ "sensitive": true,"description": "Request a cashout of creator payable into escrow (minimum and escrow period enforced by Billing), or recycle creator payable into the subject's own spendable credit. Bought credit is never withdrawable.","permissions": ["billing:cashout"@@@ -4,6 +4,7 @@"owner": "billing","status": "active","visibility": "internal",++ "sensitive": true,"description": "Start a checkout: create a payment intent priced by Billing (never by the client) for a Vibes purchase or a channel subscription, and get the provider checkout URL or PowerChat app_ref. Also reads intents and captures approved PayPal orders.","permissions": ["billing:intents"@@@ -4,6 +4,7 @@"owner": "billing","status": "active","visibility": "internal",++ "sensitive": true,"description": "Start or renew a channel subscription paid from credit (the streamer share is credited on every period), and cancel at period end (Stripe subscriptions are cancelled at Stripe). Receipt-paid subscriptions through the API additionally need billing.ledger.admin.","permissions": ["billing:subscriptions"@@@ -4,6 +4,7 @@"owner": "billing","status": "active","visibility": "internal",++ "sensitive": true,"description": "Give CREDIT to someone (tip, donation, paid interaction): user_credit of the giver to creator_payable of the recipient. Self-dealing is refused by subject. Also refunds a credit-funded transfer back to its giver (e.g. a media request that never played). Idempotent by Idempotency-Key.","permissions": ["billing:transfer"@@@ -4,6 +4,7 @@"owner": "blog","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Delete a post: readers get 410, Search a tombstone, the Community thread is hidden; immutable revisions are kept. Editors, owners, the author, and staff (moderation).","permissions": ["blog:write"@@@ -4,6 +4,7 @@"owner": "blog","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Make a revision the published one (idempotent). AI-generated revisions are refused (409 post.review_required) until a person has recorded an approving review.","permissions": ["blog:write"@@@ -4,6 +4,7 @@"owner": "chat","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Send a chat message to a room the actor is a member of (browsers over the chat socket; first-party services over Chat's service API).","permissions": ["chat:write"@@@ -4,6 +4,7 @@"owner": "community","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Typed comment threads as a service: resolve the thread of any EntityRef (browsers are limited to an allowlist of types), and comment, vote and delete one's own comments as the acting subject (X-OV-Subject), or comment as origin \"ai\" (never attributed to a person, roadmap 33). Ownership and limits are checked by Community.","inputSchema": "community.comment-write-request@1","outputSchema": "community.comment-write-result@1",@@@ -4,6 +4,7 @@"owner": "community","status": "active","visibility": "public",++ "sensitive": true,"description": "Forum writes as a service: create threads and replies in a space, vote on threads, and edit or delete one's own posts, as the acting subject (X-OV-Subject) or as origin \"ai\" (no author, labelled as AI). Space visibility (public, members, staff), locks and limits are checked by Community.","outputSchema": "community.post-write-result@1","permissions": [@@@ -4,6 +4,7 @@"owner": "media","status": "active","visibility": "public",++ "sensitive": true,"description": "Delete an object in a namespace (the delete verb of Media's namespace grants, WS-G task 2): a soft delete that keeps the bytes for the retention period, and the restore that undoes it within that period (checked against the namespace's quotas); refused while the object is under a retention hold. The same verb guards the v1 file delete (DELETE /api/v1/:app/files/:key). media.object.upload also grants it, for tokens issued before the verbs were split, unless the namespace's policy is strict_verbs.","inputSchema": "common.no-body@1","outputSchema": "media.object@1",@@@ -4,6 +4,7 @@"owner": "network","status": "active","visibility": "internal",++ "sensitive": true,"description": "Atomically move OpenCoins between two Network users. A token may only act for its own app_id.","permissions": ["coins:write"@@@ -4,6 +4,7 @@"owner": "news","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Publish a revision (refused while it cites no source, rests on a source removed upstream or detached, or is AI-generated/AI-assisted without a person's approval), or unpublish a story. Publishing resolves the upstream flags the revision answers and publishes pending correction/update notes.","permissions": ["news:write"@@@ -4,6 +4,7 @@"owner": "reviews","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Write, review (approve or reject), publish and unpublish summary revisions as the editor named in X-OV-Subject. Publishing refuses AI or system-prepared revisions without a person's approval and any revision with a point that cites no live signal of the entity.","permissions": ["reviews:summary:publish"@@@ -4,6 +4,7 @@"owner": "tips","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Start a tip for a supporter (on_behalf SubjectRef): paid from the supporter's Billing credit (billing.transfer.create) or through a Billing checkout intent (billing.intent.create). Tips never prices money; Billing does. Idempotent by Idempotency-Key.","permissions": ["tips:checkout"@@@ -4,6 +4,7 @@"owner": "tips","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Start a paid (highlighted) chat message for a supporter; the paid_messages row exists only after Billing settles it.","permissions": ["tips:checkout"@@@ -4,6 +4,7 @@"owner": "wiki","status": "active","visibility": "first-party",++ "sensitive": true,"description": "Publish a revision now or at a scheduled time (idempotent), unpublish a page, and record a person's review (approved or rejected) of an AI proposal or of an existing AI-assisted revision, on behalf of the editor named in X-OV-Subject. AI-generated revisions cannot be published without an approving review by a person.","permissions": ["wiki:revision:publish"@@@ -1,6 +1,6 @@{"name": "openvibe-contracts",-- "version": "0.76.0",++ "version": "0.77.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,18 @@ the notes were in the tag and commit messages (`git tag -n1`).
@@ -6,6 +6,18 @@ the notes were in the tag and commit messages (`git tag -n1`).
## Unreleased
## Unreleased
+## 0.77.0 — 2026-09-28
+
+**Agents, confirmations, the adaptive fabric and the resource index** (roadmap section 4C: WS-Z1, WS-Z2, WS-Z3, WS-Z7, WS-Z9).
+- `identity.subject-ref@1` gains the **agent** subject (`agt_<ULID>`): an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated. `ids` knows the `agt` and `cnf` prefixes; `principalSub` accepts agents (`agent:agt_…`).
+- `events.event-envelope@1`: optional `on_behalf_of`, the person or project an agent or app acted for.
+- `capabilities.capability@1`: optional `sensitive`. Sixteen capabilities with external side effects are marked (money movement, publishing, sending messages, deleting): an agent needs its owner's confirmation for them unless a standing rule covers it.
+- `network.confirmation-request@1`: a sensitive action waiting for its owner (pending, approved, denied, expired, cancelled; once, session, until, always).
+- `events.delivery-policy@1`: an event type's delivery class (realtime_ephemeral … webhook), durability, per-key ordering, latency targets, retention tiers, routing objective, batching, residency and a payload ceiling of 64 KB.
+- The fabric (`platform.*`, first-party): `resource-offer@1` (a node's or provider's capabilities, multidimensional capacity, latency, health, pricing), `workload-requirements@1`, `placement-result@1` (the explain answer), `placement-plan@1` (signed, expiring route plans), `rate-card@1` (a provider price in its real unit, with its free allowance, source and verification date), `provider-state@1` (usage, forecast, reserve), `cost-snapshot@1` (with counterfactuals), `capacity-snapshot@1`.
+- The resource index: `common.resource-summary@1` and `common.resource-list-result@1` (GET /api/v1/resources in every service); `common.resource-cost@1` (a charge in weighted cost units with an idempotency key).
+- Fixtures for each, and the regenerated OpenAPI and JSON Schema bundle.
+
## 0.76.0 — 2026-09-28
## 0.76.0 — 2026-09-28
**The node registry** (ADR-034 section 12; roadmap WS-X1).
**The node registry** (ADR-034 section 12; roadmap WS-X1).
@@ -19,6 +19,7 @@
@@ -19,6 +19,7 @@
"resourceConstraints": { "type": "array", "items": { "enum": ["namespace", "owner", "room_member", "space_member", "project", "none"] } },
"resourceConstraints": { "type": "array", "items": { "enum": ["namespace", "owner", "room_member", "space_member", "project", "none"] } },
"quotaClass": { "type": "string" },
"quotaClass": { "type": "string" },
"events": { "type": "array", "items": { "type": "string" } },
"events": { "type": "array", "items": { "type": "string" } },
- "implementedBy": { "type": "array", "items": { "type": "string" }, "description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'." }
+ "implementedBy": { "type": "array", "items": { "type": "string" }, "description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'." },
+ "sensitive": { "type": "boolean", "description": "The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2)." }
}
}
}
}
@@ -5003,6 +5003,136 @@
@@ -5003,6 +5003,136 @@
"compatibility": "backward",
"compatibility": "backward",
"status": "active",
"status": "active",
"adr": "ADR-034"
"adr": "ADR-034"
+ },
+ {
+ "id": "platform.resource-offer",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/resource-offer.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.workload-requirements",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/workload-requirements.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.placement-result",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/placement-result.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.placement-plan",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/placement-plan.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.rate-card",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/rate-card.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.provider-state",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/provider-state.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.cost-snapshot",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/cost-snapshot.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "platform.capacity-snapshot",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "platform/capacity-snapshot.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "events.delivery-policy",
+ "version": "1.0.0",
+ "owner": "events",
+ "schema": "events/delivery-policy.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "common.resource-summary",
+ "version": "1.0.0",
+ "owner": "contracts",
+ "schema": "common/resource-summary.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "common.resource-list-result",
+ "version": "1.0.0",
+ "owner": "contracts",
+ "schema": "common/resource-list-result.v1.json",
+ "visibility": "public",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "common.resource-cost",
+ "version": "1.0.0",
+ "owner": "contracts",
+ "schema": "common/resource-cost.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
+ },
+ {
+ "id": "network.confirmation-request",
+ "version": "1.0.0",
+ "owner": "network",
+ "schema": "network/confirmation-request.v1.json",
+ "visibility": "first-party",
+ "compatibility": "backward",
+ "status": "active",
+ "adr": "ADR-034"
}
}
]
]
}
}
new file mode 100644
new file mode 100644
@@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-cost.v1.json",
+ "title": "ResourceCost",
+ "description": "One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "subject",
+ "unit",
+ "amount",
+ "state",
+ "idempotency_key",
+ "service",
+ "at"
+ ],
+ "properties": {
+ "subject": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "unit": {
+ "type": "string",
+ "enum": [
+ "browser-second",
+ "ai-token",
+ "ai-usd",
+ "gpu-second",
+ "video-minute",
+ "bandwidth-byte",
+ "storage-byte-day",
+ "event",
+ "watch-check",
+ "bot-control-second",
+ "job-run",
+ "upload-byte",
+ "download-byte"
+ ]
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0
+ },
+ "state": {
+ "type": "string",
+ "enum": [
+ "reserved",
+ "committed",
+ "released"
+ ]
+ },
+ "idempotency_key": {
+ "type": "string",
+ "minLength": 8,
+ "maxLength": 200
+ },
+ "service": {
+ "type": "string"
+ },
+ "at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-list-result.v1.json",
+ "title": "ResourceListResult",
+ "description": "A page of the resource index (roadmap WS-Z7).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "resources",
+ "next_cursor"
+ ],
+ "properties": {
+ "resources": {
+ "type": "array",
+ "items": {
+ "$ref": "resource-summary.v1.json"
+ }
+ },
+ "next_cursor": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-summary.v1.json",
+ "title": "ResourceSummary",
+ "description": "One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "kind",
+ "service",
+ "state",
+ "created_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string",
+ "description": "service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription"
+ },
+ "service": {
+ "type": "string"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "name": {
+ "type": "string"
+ },
+ "state": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usage": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "cost units by name (WS-Z1)"
+ },
+ "links": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "self": {
+ "type": "string",
+ "format": "uri"
+ },
+ "console": {
+ "type": "string",
+ "format": "uri"
+ },
+ "docs": {
+ "type": "string",
+ "format": "uri"
+ }
+ }
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,140 @@
@@ -0,0 +1,140 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/delivery-policy.v1.json",
+ "title": "DeliveryPolicy",
+ "description": "How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "class",
+ "durability",
+ "delivery_semantics"
+ ],
+ "properties": {
+ "class": {
+ "type": "string",
+ "enum": [
+ "realtime_ephemeral",
+ "interactive",
+ "interactive_durable",
+ "domain",
+ "critical",
+ "background",
+ "bulk",
+ "webhook"
+ ]
+ },
+ "durability": {
+ "type": "string",
+ "enum": [
+ "none",
+ "optional",
+ "required"
+ ]
+ },
+ "delivery_semantics": {
+ "type": "string",
+ "enum": [
+ "at_most_once",
+ "at_least_once"
+ ]
+ },
+ "ordering": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "type": "string"
+ },
+ "key": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "scope",
+ "key"
+ ]
+ },
+ "latency": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "target_p95_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "maximum_p95_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "retention": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "hot": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdm]$"
+ },
+ "replay": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdm]$"
+ },
+ "archive": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdmy]$"
+ }
+ }
+ },
+ "routing": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "objective": {
+ "type": "string",
+ "enum": [
+ "latency_first",
+ "cheapest",
+ "balanced",
+ "correctness"
+ ]
+ },
+ "multi_provider": {
+ "type": "boolean"
+ }
+ }
+ },
+ "batching": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max_messages": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "max_delay_ms": {
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ },
+ "residency": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "inherit_project_region": {
+ "type": "boolean"
+ },
+ "region": {
+ "type": "string"
+ }
+ }
+ },
+ "max_payload_bytes": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 65536
+ }
+ }
+}
@@ -13,6 +13,7 @@
@@ -13,6 +13,7 @@
"version": { "type": "integer", "minimum": 1 },
"version": { "type": "integer", "minimum": 1 },
"source": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" },
"source": { "type": "string", "pattern": "^[a-z][a-z0-9-]{1,39}$" },
"actor": { "$ref": "../identity/subject-ref.v1.json" },
"actor": { "$ref": "../identity/subject-ref.v1.json" },
+ "on_behalf_of": { "$ref": "../identity/subject-ref.v1.json" },
"timestamp": { "type": "string", "format": "date-time" },
"timestamp": { "type": "string", "format": "date-time" },
"priority": { "enum": ["critical", "important", "low"], "default": "important" },
"priority": { "enum": ["critical", "important", "low"], "default": "important" },
"visibility": { "enum": ["public", "subject", "internal"], "default": "internal" },
"visibility": { "enum": ["public", "subject", "internal"], "default": "internal" },
@@ -96,6 +96,24 @@
@@ -96,6 +96,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
}
}
new file mode 100644
new file mode 100644
@@ -0,0 +1,80 @@
@@ -0,0 +1,80 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/network/confirmation-request.v1.json",
+ "title": "ConfirmationRequest",
+ "description": "A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "owner",
+ "requested_by",
+ "capability",
+ "summary",
+ "state",
+ "expires_at",
+ "created_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^cnf_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "requested_by": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]*\\.[a-z0-9-]+\\.[a-z0-9-]+$"
+ },
+ "summary": {
+ "type": "string",
+ "maxLength": 500
+ },
+ "details": {
+ "type": "object",
+ "additionalProperties": true,
+ "properties": {}
+ },
+ "resources": {
+ "type": "array",
+ "items": {
+ "$ref": "../common/entity-ref.v1.json"
+ }
+ },
+ "state": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "approved",
+ "denied",
+ "expired",
+ "cancelled"
+ ]
+ },
+ "standing_rule": {
+ "type": "string",
+ "enum": [
+ "once",
+ "session",
+ "until",
+ "always"
+ ]
+ },
+ "expires_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "decided_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,179 @@
@@ -0,0 +1,179 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/capacity-snapshot.v1.json",
+ "title": "CapacitySnapshot",
+ "description": "A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "node_id",
+ "capacity",
+ "reported_at"
+ ],
+ "properties": {
+ "node_id": {
+ "type": "string"
+ },
+ "cell": {
+ "type": "string"
+ },
+ "capacity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_cores": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "memory": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_mb": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "network": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ingress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "available_mbps": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "disk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "iops_available": {
+ "type": "number",
+ "minimum": 0
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "gpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "vram_free_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "workers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"
+ },
+ "queues": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "depth": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "oldest_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "properties": {},
+ "description": "queue depth and age by name"
+ },
+ "event_loop_lag_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "services": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "instances": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "active_requests": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "p50_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p95_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "error_rate": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "properties": {}
+ },
+ "reported_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/cost-snapshot.v1.json",
+ "title": "CostSnapshot",
+ "description": "Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "window_start",
+ "window_end",
+ "scope",
+ "by_target",
+ "actual_usd"
+ ],
+ "properties": {
+ "window_start": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "window_end": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "scope": {
+ "type": "string",
+ "description": "events, jobs, ai, media, …"
+ },
+ "by_target": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "units": {
+ "type": "number",
+ "minimum": 0
+ },
+ "cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p50_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p95_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ },
+ "required": [
+ "id",
+ "units",
+ "cost_usd"
+ ]
+ }
+ },
+ "actual_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "counterfactual_usd": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "e.g. all_local, all_provider, lowest_latency"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,89 @@
@@ -0,0 +1,89 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/placement-plan.v1.json",
+ "title": "PlacementPlan",
+ "description": "A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "epoch",
+ "issued_at",
+ "expires_at",
+ "issuer",
+ "key_id",
+ "routes",
+ "signature"
+ ],
+ "properties": {
+ "epoch": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "issued_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "expires_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "issuer": {
+ "type": "string"
+ },
+ "key_id": {
+ "type": "string"
+ },
+ "routes": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "route": {
+ "type": "string",
+ "description": "a route name: an event delivery class and scope, a workload kind, a service"
+ },
+ "targets": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "weight": {
+ "type": "number",
+ "minimum": 0
+ }
+ },
+ "required": [
+ "id",
+ "weight"
+ ]
+ },
+ "minItems": 1
+ },
+ "draining": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "since_epoch": {
+ "type": "integer",
+ "minimum": 1
+ }
+ },
+ "required": [
+ "route",
+ "targets"
+ ]
+ }
+ },
+ "signature": {
+ "type": "string",
+ "description": "Ed25519 over the canonical JSON of every other field, base64url"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/placement-result.v1.json",
+ "title": "PlacementResult",
+ "description": "Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "selected",
+ "objective",
+ "candidates",
+ "decided_at"
+ ],
+ "properties": {
+ "selected": {
+ "type": "string"
+ },
+ "objective": {
+ "type": "string",
+ "enum": [
+ "cheapest",
+ "lowest-latency",
+ "balanced",
+ "private",
+ "local-only",
+ "first-party-only",
+ "high-reliability",
+ "correctness"
+ ]
+ },
+ "reasons": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "candidates": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "eligible": {
+ "type": "boolean"
+ },
+ "excluded_because": {
+ "type": "string"
+ },
+ "estimated_cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "estimated_latency_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "score": {
+ "type": "number"
+ },
+ "reasons": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [
+ "id",
+ "eligible"
+ ]
+ }
+ },
+ "plan_epoch": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "decided_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/provider-state.v1.json",
+ "title": "ProviderState",
+ "description": "A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "provider",
+ "period_start",
+ "period_end",
+ "usage",
+ "updated_at"
+ ],
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "period_start": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "period_end": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usage": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "used units per rate-card metric"
+ },
+ "forecast": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "projected units at period end"
+ },
+ "reserve": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "properties": {},
+ "description": "share of each free allowance kept for higher-priority classes"
+ },
+ "health": {
+ "type": "string",
+ "enum": [
+ "up",
+ "degraded",
+ "down"
+ ]
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,74 @@
@@ -0,0 +1,74 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/rate-card.v1.json",
+ "title": "RateCard",
+ "description": "One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "provider",
+ "metric",
+ "unit_size",
+ "unit_price_usd",
+ "free_allowance",
+ "reset_period",
+ "effective_from",
+ "source",
+ "verified_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "adapter": {
+ "type": "string"
+ },
+ "metric": {
+ "type": "string",
+ "description": "e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op"
+ },
+ "unit_size": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unit_price_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "free_allowance": {
+ "type": "number",
+ "minimum": 0
+ },
+ "reset_period": {
+ "type": "string",
+ "enum": [
+ "day",
+ "month",
+ "none"
+ ]
+ },
+ "region": {
+ "type": "string"
+ },
+ "effective_from": {
+ "type": "string",
+ "format": "date"
+ },
+ "effective_until": {
+ "type": "string",
+ "format": "date"
+ },
+ "source": {
+ "type": "string",
+ "format": "uri"
+ },
+ "verified_at": {
+ "type": "string",
+ "format": "date"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,260 @@
@@ -0,0 +1,260 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/resource-offer.v1.json",
+ "title": "ResourceOffer",
+ "description": "What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "offer_id",
+ "kind",
+ "region",
+ "trust",
+ "capabilities",
+ "health",
+ "pricing",
+ "updated_at"
+ ],
+ "properties": {
+ "offer_id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string",
+ "enum": [
+ "node",
+ "provider"
+ ]
+ },
+ "node_id": {
+ "type": "string",
+ "description": "network.node@1 id, for kind node"
+ },
+ "provider": {
+ "type": "string",
+ "description": "provider or hosting company"
+ },
+ "adapter": {
+ "type": "string",
+ "description": "carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)"
+ },
+ "region": {
+ "type": "string"
+ },
+ "cell": {
+ "type": "string"
+ },
+ "trust": {
+ "type": "string",
+ "enum": [
+ "first-party",
+ "partner",
+ "community",
+ "external"
+ ]
+ },
+ "capabilities": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"
+ },
+ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2"
+ },
+ "capacity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_cores": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "memory": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_mb": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "network": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ingress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "available_mbps": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "disk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "iops_available": {
+ "type": "number",
+ "minimum": 0
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "gpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "vram_free_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "workers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"
+ },
+ "queues": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "depth": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "oldest_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "properties": {},
+ "description": "queue depth and age by name"
+ },
+ "event_loop_lag_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "latency_ms": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "measured p50/p95 by operation, e.g. publish_p95, ack_p95"
+ },
+ "health": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "status": {
+ "type": "string",
+ "enum": [
+ "up",
+ "degraded",
+ "down",
+ "draining"
+ ]
+ },
+ "error_rate": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "checked_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "required": [
+ "status"
+ ]
+ },
+ "pricing": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "model": {
+ "type": "string",
+ "enum": [
+ "prepaid",
+ "per-request",
+ "per-byte",
+ "per-operation",
+ "per-second",
+ "free-allowance",
+ "mixed"
+ ]
+ },
+ "marginal_usd_per_unit": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unit": {
+ "type": "string"
+ },
+ "rate_card": {
+ "type": "string",
+ "description": "platform.rate-card id when the price comes from one"
+ }
+ },
+ "required": [
+ "model"
+ ]
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,138 @@
@@ -0,0 +1,138 @@
+{
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/workload-requirements.v1.json",
+ "title": "WorkloadRequirements",
+ "description": "What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "kind",
+ "mobility",
+ "latency_class",
+ "objective"
+ ],
+ "properties": {
+ "kind": {
+ "type": "string",
+ "description": "what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver"
+ },
+ "mobility": {
+ "type": "string",
+ "enum": [
+ "request",
+ "job",
+ "session",
+ "stateful-partition"
+ ]
+ },
+ "latency_class": {
+ "type": "string",
+ "enum": [
+ "realtime",
+ "interactive",
+ "background",
+ "bulk",
+ "critical"
+ ]
+ },
+ "objective": {
+ "type": "string",
+ "enum": [
+ "cheapest",
+ "lowest-latency",
+ "balanced",
+ "private",
+ "local-only",
+ "first-party-only",
+ "high-reliability",
+ "correctness"
+ ]
+ },
+ "max_latency_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "deadline_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "max_cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "durability": {
+ "type": "string",
+ "enum": [
+ "none",
+ "at-least-once",
+ "authoritative"
+ ]
+ },
+ "residency": {
+ "type": "string",
+ "description": "region or jurisdiction the work and its data must stay in"
+ },
+ "trust": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "first-party",
+ "partner",
+ "community",
+ "external"
+ ]
+ },
+ "minItems": 1,
+ "description": "trust levels allowed to run it"
+ },
+ "region": {
+ "type": "string",
+ "description": "a region, or 'nearest'"
+ },
+ "capabilities": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "capabilities a candidate must offer (worker:browser, …)"
+ },
+ "resources": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "number",
+ "minimum": 0
+ },
+ "memory_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "gpu": {
+ "type": "boolean"
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress": {
+ "type": "string",
+ "enum": [
+ "none",
+ "public",
+ "openvibe-only"
+ ]
+ }
+ }
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "partition_key": {
+ "type": "string",
+ "description": "stable key for rendezvous placement (room, stream, session)"
+ }
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "subject": {
+ "type": "user",
+ "id": "usr_01J0000000000000000000000A"
+ },
+ "unit": "job-run",
+ "amount": 1,
+ "state": "reserved",
+ "idempotency_key": "k",
+ "service": "x",
+ "at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "subject": {
+ "type": "user",
+ "id": "usr_01J0000000000000000000000A"
+ },
+ "unit": "coins",
+ "amount": 1,
+ "state": "committed",
+ "idempotency_key": "abcdefgh",
+ "service": "x",
+ "at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
+{
+ "subject": {
+ "type": "agent",
+ "id": "agt_01J0000000000000000000000A"
+ },
+ "project_id": "prj_01J0000000000000000000000A",
+ "unit": "browser-second",
+ "amount": 12.5,
+ "state": "committed",
+ "idempotency_key": "run_01J-step-4",
+ "service": "actor",
+ "at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,3 @@
@@ -0,0 +1,3 @@
+{
+ "resources": []
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "resources": [
+ {
+ "id": "sub_1",
+ "kind": "events.subscription",
+ "service": "events",
+ "state": "enabled",
+ "created_at": "2026-09-28T23:00:00Z"
+ }
+ ],
+ "next_cursor": null
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "id": "x",
+ "kind": "watch.watch",
+ "service": "watch",
+ "created_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,19 @@
@@ -0,0 +1,19 @@
+{
+ "id": "wch_01J0000000000000000000000A",
+ "kind": "watch.watch",
+ "service": "watch",
+ "project_id": "prj_01J0000000000000000000000A",
+ "owner": {
+ "type": "user",
+ "id": "usr_01J0000000000000000000000A"
+ },
+ "name": "Price of a camera",
+ "state": "active",
+ "created_at": "2026-09-28T23:00:00Z",
+ "usage": {
+ "watch-check": 120
+ },
+ "links": {
+ "self": "https://openvibe.watch/api/v1/watches/wch_01J0000000000000000000000A"
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "class": "domain",
+ "durability": "required",
+ "delivery_semantics": "at_least_once",
+ "max_payload_bytes": 1048576
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
+{
+ "class": "fast",
+ "durability": "required",
+ "delivery_semantics": "at_least_once"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+{
+ "class": "interactive_durable",
+ "durability": "required",
+ "delivery_semantics": "at_least_once",
+ "ordering": {
+ "scope": "room",
+ "key": "room_id"
+ },
+ "latency": {
+ "target_p95_ms": 50,
+ "maximum_p95_ms": 100
+ },
+ "retention": {
+ "hot": "7d",
+ "replay": "30d",
+ "archive": "365d"
+ },
+ "routing": {
+ "objective": "latency_first",
+ "multi_provider": true
+ },
+ "residency": {
+ "inherit_project_region": true
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
+{
+ "class": "bulk",
+ "durability": "optional",
+ "delivery_semantics": "at_least_once",
+ "latency": {
+ "maximum_p95_ms": 30000
+ },
+ "routing": {
+ "objective": "cheapest"
+ },
+ "batching": {
+ "max_messages": 1000,
+ "max_delay_ms": 5000
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,4 @@
@@ -0,0 +1,4 @@
+{
+ "type": "agent",
+ "id": "agt_01J0000000000000000000000A"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
+{
+ "id": "cnf_x",
+ "owner": {
+ "type": "user",
+ "id": "usr_01J0000000000000000000000A"
+ },
+ "requested_by": {
+ "type": "agent",
+ "id": "agt_01J0000000000000000000000A"
+ },
+ "capability": "a.b.c",
+ "summary": "s",
+ "state": "pending",
+ "expires_at": "2026-09-28T23:00:00Z",
+ "created_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,17 @@
@@ -0,0 +1,17 @@
+{
+ "id": "cnf_01J0000000000000000000000A",
+ "owner": {
+ "type": "user",
+ "id": "usr_01J0000000000000000000000A"
+ },
+ "requested_by": {
+ "type": "agent",
+ "id": "agt_01J0000000000000000000000A"
+ },
+ "capability": "work.application.submit",
+ "summary": "Submit your application to Example Co for Backend Engineer",
+ "state": "pending",
+ "standing_rule": "once",
+ "expires_at": "2026-09-29T23:00:00Z",
+ "created_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,9 @@
@@ -0,0 +1,9 @@
+{
+ "node_id": "n",
+ "capacity": {
+ "cpu": {
+ "utilization": 1.5
+ }
+ },
+ "reported_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
+{
+ "node_id": "ovh-oregon-1",
+ "cell": "wnam-1",
+ "capacity": {
+ "cpu": {
+ "utilization": 0.37
+ },
+ "memory": {
+ "utilization": 0.51
+ },
+ "event_loop_lag_ms": 4
+ },
+ "services": {
+ "chat": {
+ "instances": 1,
+ "active_requests": 12,
+ "p95_ms": 12.8,
+ "error_rate": 0.0003
+ }
+ },
+ "reported_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "window_start": "2026-09-28T23:00:00Z",
+ "window_end": "2026-09-28T23:00:00Z",
+ "scope": "events",
+ "actual_usd": 0
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
+{
+ "window_start": "2026-09-28T00:00:00Z",
+ "window_end": "2026-09-29T00:00:00Z",
+ "scope": "events",
+ "by_target": [
+ {
+ "id": "pg-delivery",
+ "units": 18294,
+ "cost_usd": 0,
+ "p50_ms": 11,
+ "p95_ms": 37
+ }
+ ],
+ "actual_usd": 0,
+ "counterfactual_usd": {
+ "all_provider": 0.02
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,14 @@
@@ -0,0 +1,14 @@
+{
+ "epoch": 1,
+ "issued_at": "2026-09-28T23:00:00Z",
+ "expires_at": "2026-09-28T23:00:00Z",
+ "issuer": "network",
+ "key_id": "k",
+ "routes": [
+ {
+ "route": "r",
+ "targets": []
+ }
+ ],
+ "signature": "s"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,8 @@
@@ -0,0 +1,8 @@
+{
+ "epoch": 43,
+ "issued_at": "2026-09-28T23:00:00Z",
+ "expires_at": "2026-09-28T23:00:00Z",
+ "issuer": "network",
+ "key_id": "k",
+ "routes": []
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,23 @@
@@ -0,0 +1,23 @@
+{
+ "epoch": 43,
+ "issued_at": "2026-09-28T23:00:00Z",
+ "expires_at": "2026-09-29T00:00:00Z",
+ "issuer": "network",
+ "key_id": "route-2026-09",
+ "routes": [
+ {
+ "route": "events:background",
+ "targets": [
+ {
+ "id": "valkey-streams",
+ "weight": 1
+ }
+ ],
+ "draining": [
+ "pg-delivery"
+ ],
+ "since_epoch": 43
+ }
+ ],
+ "signature": "c2lnbmF0dXJl"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
+{
+ "selected": "a",
+ "objective": "balanced",
+ "decided_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
+{
+ "selected": "off_oregon_1",
+ "objective": "balanced",
+ "reasons": [
+ "meets the latency target",
+ "already-paid capacity available",
+ "estimated marginal cost 0"
+ ],
+ "candidates": [
+ {
+ "id": "off_oregon_1",
+ "eligible": true,
+ "estimated_cost_usd": 0,
+ "estimated_latency_ms": 31,
+ "score": 0.041
+ },
+ {
+ "id": "off_community_331",
+ "eligible": false,
+ "excluded_because": "workload requires first-party trust"
+ }
+ ],
+ "plan_epoch": 42,
+ "decided_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "provider": "p",
+ "period_start": "2026-09-28T23:00:00Z",
+ "period_end": "2026-09-28T23:00:00Z",
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
+{
+ "provider": "example-queues",
+ "period_start": "2026-09-01T00:00:00Z",
+ "period_end": "2026-10-01T00:00:00Z",
+ "usage": {
+ "queue-operation-64kb": 430000
+ },
+ "forecast": {
+ "queue-operation-64kb": 1930000
+ },
+ "reserve": {
+ "queue-operation-64kb": 0.2
+ },
+ "health": "up",
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,12 @@
@@ -0,0 +1,12 @@
+{
+ "id": "rc",
+ "provider": "p",
+ "metric": "m",
+ "unit_size": 1,
+ "unit_price_usd": -1,
+ "free_allowance": 0,
+ "reset_period": "month",
+ "effective_from": "2026-09-01",
+ "source": "https://example.com",
+ "verified_at": "2026-09-28"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
+{
+ "id": "rc",
+ "provider": "p",
+ "metric": "m",
+ "unit_size": 1,
+ "unit_price_usd": 1,
+ "free_allowance": 0,
+ "reset_period": "month",
+ "effective_from": "2026-09-01",
+ "verified_at": "2026-09-28"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
+{
+ "id": "rc_example_queue_ops",
+ "provider": "example-queues",
+ "adapter": "example-queue-v1",
+ "metric": "queue-operation-64kb",
+ "unit_size": 1000000,
+ "unit_price_usd": 0.4,
+ "free_allowance": 1000000,
+ "reset_period": "month",
+ "effective_from": "2026-09-01",
+ "source": "https://example.com/pricing",
+ "verified_at": "2026-09-28"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,16 @@
@@ -0,0 +1,16 @@
+{
+ "offer_id": "x",
+ "kind": "node",
+ "region": "us-west",
+ "trust": "first-party",
+ "capabilities": [
+ "Browser"
+ ],
+ "health": {
+ "status": "up"
+ },
+ "pricing": {
+ "model": "prepaid"
+ },
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,13 @@
@@ -0,0 +1,13 @@
+{
+ "offer_id": "x",
+ "kind": "node",
+ "region": "us-west",
+ "trust": "first-party",
+ "capabilities": [
+ "node:http"
+ ],
+ "pricing": {
+ "model": "prepaid"
+ },
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
+{
+ "offer_id": "off_oregon_1",
+ "kind": "node",
+ "node_id": "ovh-oregon-1",
+ "provider": "ovh",
+ "region": "us-west",
+ "cell": "wnam-1",
+ "trust": "first-party",
+ "capabilities": [
+ "node:http",
+ "worker:browser",
+ "worker:ffmpeg",
+ "events:durable"
+ ],
+ "capacity": {
+ "cpu": {
+ "utilization": 0.31,
+ "available_cores": 5.5
+ },
+ "memory": {
+ "available_mb": 18300
+ },
+ "workers": {
+ "browser": 6,
+ "ffmpeg": 3
+ },
+ "queues": {
+ "media-jobs": {
+ "depth": 2,
+ "oldest_ms": 40
+ }
+ }
+ },
+ "latency_ms": {
+ "publish_p95": 3.1
+ },
+ "health": {
+ "status": "up"
+ },
+ "pricing": {
+ "model": "prepaid",
+ "marginal_usd_per_unit": 0,
+ "unit": "job"
+ },
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,21 @@
@@ -0,0 +1,21 @@
+{
+ "offer_id": "off_cf_queue",
+ "kind": "provider",
+ "provider": "cloudflare",
+ "adapter": "cf-queue-v1",
+ "region": "global",
+ "trust": "external",
+ "capabilities": [
+ "events:queue",
+ "events:durable"
+ ],
+ "health": {
+ "status": "up",
+ "error_rate": 0.0001
+ },
+ "pricing": {
+ "model": "per-operation",
+ "rate_card": "rc_cf_queue_ops"
+ },
+ "updated_at": "2026-09-28T23:00:00Z"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,5 @@
@@ -0,0 +1,5 @@
+{
+ "kind": "x",
+ "latency_class": "background",
+ "objective": "cheapest"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,6 @@
@@ -0,0 +1,6 @@
+{
+ "kind": "x",
+ "mobility": "job",
+ "latency_class": "background",
+ "objective": "free"
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,22 @@
@@ -0,0 +1,22 @@
+{
+ "kind": "watch.browser",
+ "mobility": "job",
+ "latency_class": "interactive",
+ "objective": "balanced",
+ "max_latency_ms": 1000,
+ "max_cost_usd": 0.002,
+ "durability": "at-least-once",
+ "trust": [
+ "first-party",
+ "partner"
+ ],
+ "region": "nearest",
+ "capabilities": [
+ "worker:browser"
+ ],
+ "resources": {
+ "cpu": 2,
+ "memory_mb": 1024,
+ "egress": "public"
+ }
+}
new file mode 100644
new file mode 100644
@@ -0,0 +1,7 @@
@@ -0,0 +1,7 @@
+{
+ "kind": "billing.post",
+ "mobility": "stateful-partition",
+ "latency_class": "critical",
+ "objective": "correctness",
+ "durability": "authoritative"
+}
@@ -103,6 +103,24 @@
@@ -103,6 +103,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
}
}
@@ -1312,6 +1330,10 @@
@@ -1312,6 +1330,10 @@
"type": "string"
"type": "string"
},
},
"description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'."
"description": "Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'."
+ },
+ "sensitive": {
+ "type": "boolean",
+ "description": "The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2)."
}
}
}
}
}
}
@@ -1361,6 +1383,9 @@
@@ -1361,6 +1383,9 @@
"actor": {
"actor": {
"$ref": "../identity/subject-ref.v1.json"
"$ref": "../identity/subject-ref.v1.json"
},
},
+ "on_behalf_of": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
"timestamp": {
"timestamp": {
"type": "string",
"type": "string",
"format": "date-time"
"format": "date-time"
@@ -55204,6 +55229,1432 @@
@@ -55204,6 +55229,1432 @@
}
}
}
}
}
}
+ },
+ "platform.resource-offer": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/resource-offer.v1.json",
+ "title": "ResourceOffer",
+ "description": "What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "offer_id",
+ "kind",
+ "region",
+ "trust",
+ "capabilities",
+ "health",
+ "pricing",
+ "updated_at"
+ ],
+ "properties": {
+ "offer_id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string",
+ "enum": [
+ "node",
+ "provider"
+ ]
+ },
+ "node_id": {
+ "type": "string",
+ "description": "network.node@1 id, for kind node"
+ },
+ "provider": {
+ "type": "string",
+ "description": "provider or hosting company"
+ },
+ "adapter": {
+ "type": "string",
+ "description": "carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)"
+ },
+ "region": {
+ "type": "string"
+ },
+ "cell": {
+ "type": "string"
+ },
+ "trust": {
+ "type": "string",
+ "enum": [
+ "first-party",
+ "partner",
+ "community",
+ "external"
+ ]
+ },
+ "capabilities": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]*:[a-z0-9.-]+$"
+ },
+ "description": "e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2"
+ },
+ "capacity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_cores": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "memory": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_mb": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "network": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ingress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "available_mbps": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "disk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "iops_available": {
+ "type": "number",
+ "minimum": 0
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "gpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "vram_free_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "workers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"
+ },
+ "queues": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "depth": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "oldest_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "properties": {},
+ "description": "queue depth and age by name"
+ },
+ "event_loop_lag_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "latency_ms": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "measured p50/p95 by operation, e.g. publish_p95, ack_p95"
+ },
+ "health": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "status": {
+ "type": "string",
+ "enum": [
+ "up",
+ "degraded",
+ "down",
+ "draining"
+ ]
+ },
+ "error_rate": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "checked_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ },
+ "required": [
+ "status"
+ ]
+ },
+ "pricing": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "model": {
+ "type": "string",
+ "enum": [
+ "prepaid",
+ "per-request",
+ "per-byte",
+ "per-operation",
+ "per-second",
+ "free-allowance",
+ "mixed"
+ ]
+ },
+ "marginal_usd_per_unit": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unit": {
+ "type": "string"
+ },
+ "rate_card": {
+ "type": "string",
+ "description": "platform.rate-card id when the price comes from one"
+ }
+ },
+ "required": [
+ "model"
+ ]
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "platform.workload-requirements": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/workload-requirements.v1.json",
+ "title": "WorkloadRequirements",
+ "description": "What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "kind",
+ "mobility",
+ "latency_class",
+ "objective"
+ ],
+ "properties": {
+ "kind": {
+ "type": "string",
+ "description": "what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver"
+ },
+ "mobility": {
+ "type": "string",
+ "enum": [
+ "request",
+ "job",
+ "session",
+ "stateful-partition"
+ ]
+ },
+ "latency_class": {
+ "type": "string",
+ "enum": [
+ "realtime",
+ "interactive",
+ "background",
+ "bulk",
+ "critical"
+ ]
+ },
+ "objective": {
+ "type": "string",
+ "enum": [
+ "cheapest",
+ "lowest-latency",
+ "balanced",
+ "private",
+ "local-only",
+ "first-party-only",
+ "high-reliability",
+ "correctness"
+ ]
+ },
+ "max_latency_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "deadline_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "max_cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "durability": {
+ "type": "string",
+ "enum": [
+ "none",
+ "at-least-once",
+ "authoritative"
+ ]
+ },
+ "residency": {
+ "type": "string",
+ "description": "region or jurisdiction the work and its data must stay in"
+ },
+ "trust": {
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "first-party",
+ "partner",
+ "community",
+ "external"
+ ]
+ },
+ "minItems": 1,
+ "description": "trust levels allowed to run it"
+ },
+ "region": {
+ "type": "string",
+ "description": "a region, or 'nearest'"
+ },
+ "capabilities": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "description": "capabilities a candidate must offer (worker:browser, …)"
+ },
+ "resources": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "number",
+ "minimum": 0
+ },
+ "memory_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "gpu": {
+ "type": "boolean"
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress": {
+ "type": "string",
+ "enum": [
+ "none",
+ "public",
+ "openvibe-only"
+ ]
+ }
+ }
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "partition_key": {
+ "type": "string",
+ "description": "stable key for rendezvous placement (room, stream, session)"
+ }
+ }
+ }
+ },
+ "platform.placement-result": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/placement-result.v1.json",
+ "title": "PlacementResult",
+ "description": "Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "selected",
+ "objective",
+ "candidates",
+ "decided_at"
+ ],
+ "properties": {
+ "selected": {
+ "type": "string"
+ },
+ "objective": {
+ "type": "string",
+ "enum": [
+ "cheapest",
+ "lowest-latency",
+ "balanced",
+ "private",
+ "local-only",
+ "first-party-only",
+ "high-reliability",
+ "correctness"
+ ]
+ },
+ "reasons": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "candidates": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "eligible": {
+ "type": "boolean"
+ },
+ "excluded_because": {
+ "type": "string"
+ },
+ "estimated_cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "estimated_latency_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "score": {
+ "type": "number"
+ },
+ "reasons": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "required": [
+ "id",
+ "eligible"
+ ]
+ }
+ },
+ "plan_epoch": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "decided_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "platform.placement-plan": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/placement-plan.v1.json",
+ "title": "PlacementPlan",
+ "description": "A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "epoch",
+ "issued_at",
+ "expires_at",
+ "issuer",
+ "key_id",
+ "routes",
+ "signature"
+ ],
+ "properties": {
+ "epoch": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "issued_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "expires_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "issuer": {
+ "type": "string"
+ },
+ "key_id": {
+ "type": "string"
+ },
+ "routes": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "route": {
+ "type": "string",
+ "description": "a route name: an event delivery class and scope, a workload kind, a service"
+ },
+ "targets": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "weight": {
+ "type": "number",
+ "minimum": 0
+ }
+ },
+ "required": [
+ "id",
+ "weight"
+ ]
+ },
+ "minItems": 1
+ },
+ "draining": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "since_epoch": {
+ "type": "integer",
+ "minimum": 1
+ }
+ },
+ "required": [
+ "route",
+ "targets"
+ ]
+ }
+ },
+ "signature": {
+ "type": "string",
+ "description": "Ed25519 over the canonical JSON of every other field, base64url"
+ }
+ }
+ }
+ },
+ "platform.rate-card": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/rate-card.v1.json",
+ "title": "RateCard",
+ "description": "One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "provider",
+ "metric",
+ "unit_size",
+ "unit_price_usd",
+ "free_allowance",
+ "reset_period",
+ "effective_from",
+ "source",
+ "verified_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "provider": {
+ "type": "string"
+ },
+ "adapter": {
+ "type": "string"
+ },
+ "metric": {
+ "type": "string",
+ "description": "e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op"
+ },
+ "unit_size": {
+ "type": "number",
+ "minimum": 0
+ },
+ "unit_price_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "free_allowance": {
+ "type": "number",
+ "minimum": 0
+ },
+ "reset_period": {
+ "type": "string",
+ "enum": [
+ "day",
+ "month",
+ "none"
+ ]
+ },
+ "region": {
+ "type": "string"
+ },
+ "effective_from": {
+ "type": "string",
+ "format": "date"
+ },
+ "effective_until": {
+ "type": "string",
+ "format": "date"
+ },
+ "source": {
+ "type": "string",
+ "format": "uri"
+ },
+ "verified_at": {
+ "type": "string",
+ "format": "date"
+ }
+ }
+ }
+ },
+ "platform.provider-state": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/provider-state.v1.json",
+ "title": "ProviderState",
+ "description": "A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "provider",
+ "period_start",
+ "period_end",
+ "usage",
+ "updated_at"
+ ],
+ "properties": {
+ "provider": {
+ "type": "string"
+ },
+ "period_start": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "period_end": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usage": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "used units per rate-card metric"
+ },
+ "forecast": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "projected units at period end"
+ },
+ "reserve": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "properties": {},
+ "description": "share of each free allowance kept for higher-priority classes"
+ },
+ "health": {
+ "type": "string",
+ "enum": [
+ "up",
+ "degraded",
+ "down"
+ ]
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "platform.cost-snapshot": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/cost-snapshot.v1.json",
+ "title": "CostSnapshot",
+ "description": "Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "window_start",
+ "window_end",
+ "scope",
+ "by_target",
+ "actual_usd"
+ ],
+ "properties": {
+ "window_start": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "window_end": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "scope": {
+ "type": "string",
+ "description": "events, jobs, ai, media, …"
+ },
+ "by_target": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "units": {
+ "type": "number",
+ "minimum": 0
+ },
+ "cost_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p50_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p95_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ },
+ "required": [
+ "id",
+ "units",
+ "cost_usd"
+ ]
+ }
+ },
+ "actual_usd": {
+ "type": "number",
+ "minimum": 0
+ },
+ "counterfactual_usd": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "e.g. all_local, all_provider, lowest_latency"
+ }
+ }
+ }
+ },
+ "platform.capacity-snapshot": {
+ "version": "1.0.0",
+ "owner": "network",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/platform/capacity-snapshot.v1.json",
+ "title": "CapacitySnapshot",
+ "description": "A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "node_id",
+ "capacity",
+ "reported_at"
+ ],
+ "properties": {
+ "node_id": {
+ "type": "string"
+ },
+ "cell": {
+ "type": "string"
+ },
+ "capacity": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_cores": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "memory": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ },
+ "available_mb": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "network": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "ingress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "egress_mbps": {
+ "type": "number",
+ "minimum": 0
+ },
+ "available_mbps": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "disk": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "iops_available": {
+ "type": "number",
+ "minimum": 0
+ },
+ "scratch_gb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "gpu": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "type": "string"
+ },
+ "vram_free_mb": {
+ "type": "number",
+ "minimum": 0
+ },
+ "utilization": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "workers": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "free worker slots by kind (browser, ffmpeg, ai, …)"
+ },
+ "queues": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "depth": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "oldest_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "properties": {},
+ "description": "queue depth and age by name"
+ },
+ "event_loop_lag_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "services": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "instances": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "active_requests": {
+ "type": "integer",
+ "minimum": 0
+ },
+ "p50_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "p95_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "error_rate": {
+ "type": "number",
+ "minimum": 0,
+ "maximum": 1
+ }
+ }
+ },
+ "properties": {}
+ },
+ "reported_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "events.delivery-policy": {
+ "version": "1.0.0",
+ "owner": "events",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/events/delivery-policy.v1.json",
+ "title": "DeliveryPolicy",
+ "description": "How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "class",
+ "durability",
+ "delivery_semantics"
+ ],
+ "properties": {
+ "class": {
+ "type": "string",
+ "enum": [
+ "realtime_ephemeral",
+ "interactive",
+ "interactive_durable",
+ "domain",
+ "critical",
+ "background",
+ "bulk",
+ "webhook"
+ ]
+ },
+ "durability": {
+ "type": "string",
+ "enum": [
+ "none",
+ "optional",
+ "required"
+ ]
+ },
+ "delivery_semantics": {
+ "type": "string",
+ "enum": [
+ "at_most_once",
+ "at_least_once"
+ ]
+ },
+ "ordering": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "scope": {
+ "type": "string"
+ },
+ "key": {
+ "type": "string"
+ }
+ },
+ "required": [
+ "scope",
+ "key"
+ ]
+ },
+ "latency": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "target_p95_ms": {
+ "type": "number",
+ "minimum": 0
+ },
+ "maximum_p95_ms": {
+ "type": "number",
+ "minimum": 0
+ }
+ }
+ },
+ "retention": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "hot": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdm]$"
+ },
+ "replay": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdm]$"
+ },
+ "archive": {
+ "type": "string",
+ "pattern": "^[0-9]+[hdmy]$"
+ }
+ }
+ },
+ "routing": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "objective": {
+ "type": "string",
+ "enum": [
+ "latency_first",
+ "cheapest",
+ "balanced",
+ "correctness"
+ ]
+ },
+ "multi_provider": {
+ "type": "boolean"
+ }
+ }
+ },
+ "batching": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "max_messages": {
+ "type": "integer",
+ "minimum": 1
+ },
+ "max_delay_ms": {
+ "type": "integer",
+ "minimum": 0
+ }
+ }
+ },
+ "residency": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "inherit_project_region": {
+ "type": "boolean"
+ },
+ "region": {
+ "type": "string"
+ }
+ }
+ },
+ "max_payload_bytes": {
+ "type": "integer",
+ "minimum": 1,
+ "maximum": 65536
+ }
+ }
+ }
+ },
+ "common.resource-summary": {
+ "version": "1.0.0",
+ "owner": "contracts",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-summary.v1.json",
+ "title": "ResourceSummary",
+ "description": "One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "kind",
+ "service",
+ "state",
+ "created_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string"
+ },
+ "kind": {
+ "type": "string",
+ "description": "service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription"
+ },
+ "service": {
+ "type": "string"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "name": {
+ "type": "string"
+ },
+ "state": {
+ "type": "string"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "updated_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "usage": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "number",
+ "minimum": 0
+ },
+ "properties": {},
+ "description": "cost units by name (WS-Z1)"
+ },
+ "links": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "self": {
+ "type": "string",
+ "format": "uri"
+ },
+ "console": {
+ "type": "string",
+ "format": "uri"
+ },
+ "docs": {
+ "type": "string",
+ "format": "uri"
+ }
+ }
+ }
+ }
+ }
+ },
+ "common.resource-list-result": {
+ "version": "1.0.0",
+ "owner": "contracts",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-list-result.v1.json",
+ "title": "ResourceListResult",
+ "description": "A page of the resource index (roadmap WS-Z7).",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "resources",
+ "next_cursor"
+ ],
+ "properties": {
+ "resources": {
+ "type": "array",
+ "items": {
+ "$ref": "resource-summary.v1.json"
+ }
+ },
+ "next_cursor": {
+ "type": [
+ "string",
+ "null"
+ ]
+ }
+ }
+ }
+ },
+ "common.resource-cost": {
+ "version": "1.0.0",
+ "owner": "contracts",
+ "status": "active",
+ "schema": {
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
+ "$id": "https://openvibe.network/contracts/common/resource-cost.v1.json",
+ "title": "ResourceCost",
+ "description": "One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "subject",
+ "unit",
+ "amount",
+ "state",
+ "idempotency_key",
+ "service",
+ "at"
+ ],
+ "properties": {
+ "subject": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "project_id": {
+ "type": "string",
+ "pattern": "^prj_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "unit": {
+ "type": "string",
+ "enum": [
+ "browser-second",
+ "ai-token",
+ "ai-usd",
+ "gpu-second",
+ "video-minute",
+ "bandwidth-byte",
+ "storage-byte-day",
+ "event",
+ "watch-check",
+ "bot-control-second",
+ "job-run",
+ "upload-byte",
+ "download-byte"
+ ]
+ },
+ "amount": {
+ "type": "number",
+ "minimum": 0
+ },
+ "state": {
+ "type": "string",
+ "enum": [
+ "reserved",
+ "committed",
+ "released"
+ ]
+ },
+ "idempotency_key": {
+ "type": "string",
+ "minLength": 8,
+ "maxLength": 200
+ },
+ "service": {
+ "type": "string"
+ },
+ "at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
+ },
+ "network.confirmation-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/confirmation-request.v1.json",
+ "title": "ConfirmationRequest",
+ "description": "A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.",
+ "type": "object",
+ "additionalProperties": false,
+ "required": [
+ "id",
+ "owner",
+ "requested_by",
+ "capability",
+ "summary",
+ "state",
+ "expires_at",
+ "created_at"
+ ],
+ "properties": {
+ "id": {
+ "type": "string",
+ "pattern": "^cnf_[0-9A-HJKMNP-TV-Z]{26}$"
+ },
+ "owner": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "requested_by": {
+ "$ref": "../identity/subject-ref.v1.json"
+ },
+ "capability": {
+ "type": "string",
+ "pattern": "^[a-z][a-z0-9-]*\\.[a-z0-9-]+\\.[a-z0-9-]+$"
+ },
+ "summary": {
+ "type": "string",
+ "maxLength": 500
+ },
+ "details": {
+ "type": "object",
+ "additionalProperties": true,
+ "properties": {}
+ },
+ "resources": {
+ "type": "array",
+ "items": {
+ "$ref": "../common/entity-ref.v1.json"
+ }
+ },
+ "state": {
+ "type": "string",
+ "enum": [
+ "pending",
+ "approved",
+ "denied",
+ "expired",
+ "cancelled"
+ ]
+ },
+ "standing_rule": {
+ "type": "string",
+ "enum": [
+ "once",
+ "session",
+ "until",
+ "always"
+ ]
+ },
+ "expires_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "decided_at": {
+ "type": "string",
+ "format": "date-time"
+ },
+ "created_at": {
+ "type": "string",
+ "format": "date-time"
+ }
+ }
+ }
}
}
}
}
}
}
@@ -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.76.0",
- "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.AI as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -5066,6 +5066,24 @@
@@ -5066,6 +5066,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
}
}
@@ -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.76.0",
- "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Billing as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -3362,6 +3362,24 @@
@@ -3362,6 +3362,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
}
}
@@ -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.76.0",
- "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Blog as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Chat as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Codes as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1091,6 +1091,24 @@
@@ -1091,6 +1091,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Community as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Coupons as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Deals as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Events as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1082,6 +1082,9 @@
@@ -1082,6 +1082,9 @@
"actor": {
"actor": {
"$ref": "#/components/schemas/identity.subject-ref.v1"
"$ref": "#/components/schemas/identity.subject-ref.v1"
},
},
+ "on_behalf_of": {
+ "$ref": "#/components/schemas/identity.subject-ref.v1"
+ },
"timestamp": {
"timestamp": {
"type": "string",
"type": "string",
"format": "date-time"
"format": "date-time"
@@ -1614,6 +1617,24 @@
@@ -1614,6 +1617,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
}
}
@@ -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.76.0",
- "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Games as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1033,6 +1033,24 @@
@@ -1033,6 +1033,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Host as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.Live API",
"title": "OpenVibe.Live API",
- "version": "0.76.0",
- "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Live as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Media as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Network as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1953,6 +1953,24 @@
@@ -1953,6 +1953,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.News as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenRe.Stream as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1455,6 +1455,24 @@
@@ -1455,6 +1455,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Reviews as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Search as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Sources as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Tips as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1680,6 +1680,24 @@
@@ -1680,6 +1680,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Tools as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Trade as the OpenVibe contracts describe them (openvibe-contracts 0.77.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.76.0",
- "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.VIP as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -1382,6 +1382,24 @@
@@ -1382,6 +1382,24 @@
}
}
},
},
"description": "PrincipalSubject"
"description": "PrincipalSubject"
+ },
+ {
+ "type": "object",
+ "required": [
+ "type",
+ "id"
+ ],
+ "additionalProperties": false,
+ "properties": {
+ "type": {
+ "const": "agent"
+ },
+ "id": {
+ "type": "string",
+ "pattern": "^agt_[0-9A-HJKMNP-TV-Z]{26}$"
+ }
+ },
+ "description": "AgentSubject: an agent (OpenVibe.Actor, or a developer app's agent) acting under grants its owner delegated (roadmap WS-Z2). In an event envelope, on_behalf_of names the owner."
}
}
]
]
},
},
@@ -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.76.0",
- "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.76.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.77.0",
+ "description": "Routes of OpenVibe.Wiki as the OpenVibe contracts describe them (openvibe-contracts 0.77.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"
@@ -25,6 +25,10 @@ export type SubjectRef =
@@ -25,6 +25,10 @@ export type SubjectRef =
| {
| {
type: "service" | "system";
type: "service" | "system";
id: string;
id: string;
+ }
+ | {
+ type: "agent";
+ id: string;
};
};
/** [email protected] (owner: network) */
/** [email protected] (owner: network) */
@@ -529,6 +533,10 @@ export interface Capability {
@@ -529,6 +533,10 @@ export interface Capability {
* Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'.
* Current route(s) that perform this action today, e.g. 'POST /api/v1/:app/files'.
*/
*/
implementedBy?: string[];
implementedBy?: string[];
+ /**
+ * The action has an external side effect (money, sending as the person, publishing, applying, deleting, physical control): an agent needs its owner's confirmation unless a standing rule covers it (roadmap WS-Z2).
+ */
+ sensitive?: boolean;
}
}
/** [email protected] (owner: events) */
/** [email protected] (owner: events) */
@@ -542,6 +550,7 @@ export interface EventEnvelope {
@@ -542,6 +550,7 @@ export interface EventEnvelope {
version: number;
version: number;
source: string;
source: string;
actor: SubjectRef;
actor: SubjectRef;
+ on_behalf_of?: SubjectRef;
timestamp: string;
timestamp: string;
priority?: "critical" | "important" | "low";
priority?: "critical" | "important" | "low";
visibility?: "public" | "subject" | "internal";
visibility?: "public" | "subject" | "internal";
@@ -46278,3 +46287,497 @@ export interface NetworkNodeListResult {
@@ -46278,3 +46287,497 @@ export interface NetworkNodeListResult {
nodes: NetworkNode[];
nodes: NetworkNode[];
generated_at: string;
generated_at: string;
}
}
+
+/** [email protected] (owner: network) */
+/**
+ * What one node or external provider can run right now (roadmap WS-Z9, decision 43): capabilities, multidimensional capacity, measured latencies, health and pricing. First-party only: it carries capacity the public node registry (network.node@1) deliberately leaves out.
+ */
+export interface ResourceOffer {
+ offer_id: string;
+ kind: "node" | "provider";
+ /**
+ * network.node@1 id, for kind node
+ */
+ node_id?: string;
+ /**
+ * provider or hosting company
+ */
+ provider?: string;
+ /**
+ * carrier or provider adapter id, for kind provider (e.g. nats-v1, cf-queue-v1)
+ */
+ adapter?: string;
+ region: string;
+ cell?: string;
+ trust: "first-party" | "partner" | "community" | "external";
+ /**
+ * e.g. node:http, worker:browser, worker:ffmpeg, worker:ai-gpu, events:gateway, events:durable, object:r2
+ */
+ capabilities: string[];
+ capacity?: {
+ cpu?: {
+ utilization?: number;
+ available_cores?: number;
+ };
+ memory?: {
+ utilization?: number;
+ available_mb?: number;
+ };
+ network?: {
+ ingress_mbps?: number;
+ egress_mbps?: number;
+ available_mbps?: number;
+ };
+ disk?: {
+ iops_available?: number;
+ scratch_gb?: number;
+ utilization?: number;
+ };
+ gpu?: {
+ type?: string;
+ vram_free_mb?: number;
+ utilization?: number;
+ };
+ /**
+ * free worker slots by kind (browser, ffmpeg, ai, …)
+ */
+ workers?: {
+ [k: string]: number | undefined;
+ };
+ /**
+ * queue depth and age by name
+ */
+ queues?: {
+ [k: string]:
+ | {
+ depth?: number;
+ oldest_ms?: number;
+ }
+ | undefined;
+ };
+ event_loop_lag_ms?: number;
+ };
+ /**
+ * measured p50/p95 by operation, e.g. publish_p95, ack_p95
+ */
+ latency_ms?: {
+ [k: string]: number | undefined;
+ };
+ health: {
+ status: "up" | "degraded" | "down" | "draining";
+ error_rate?: number;
+ checked_at?: string;
+ };
+ pricing: {
+ model: "prepaid" | "per-request" | "per-byte" | "per-operation" | "per-second" | "free-allowance" | "mixed";
+ marginal_usd_per_unit?: number;
+ unit?: string;
+ /**
+ * platform.rate-card id when the price comes from one
+ */
+ rate_card?: string;
+ };
+ updated_at: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * What a workload needs, so the platform can place it (roadmap WS-Z9). Hard constraints are filtered before any objective is scored; a cheaper candidate that misses one is never chosen.
+ */
+export interface WorkloadRequirements {
+ /**
+ * what runs, e.g. watch.browser, media.transcode, ai.run, events.deliver
+ */
+ kind: string;
+ mobility: "request" | "job" | "session" | "stateful-partition";
+ latency_class: "realtime" | "interactive" | "background" | "bulk" | "critical";
+ objective:
+ | "cheapest"
+ | "lowest-latency"
+ | "balanced"
+ | "private"
+ | "local-only"
+ | "first-party-only"
+ | "high-reliability"
+ | "correctness";
+ max_latency_ms?: number;
+ deadline_ms?: number;
+ max_cost_usd?: number;
+ durability?: "none" | "at-least-once" | "authoritative";
+ /**
+ * region or jurisdiction the work and its data must stay in
+ */
+ residency?: string;
+ /**
+ * trust levels allowed to run it
+ *
+ * @minItems 1
+ */
+ trust?: [
+ "first-party" | "partner" | "community" | "external",
+ ...("first-party" | "partner" | "community" | "external")[]
+ ];
+ /**
+ * a region, or 'nearest'
+ */
+ region?: string;
+ /**
+ * capabilities a candidate must offer (worker:browser, …)
+ */
+ capabilities?: string[];
+ resources?: {
+ cpu?: number;
+ memory_mb?: number;
+ gpu?: boolean;
+ scratch_gb?: number;
+ egress?: "none" | "public" | "openvibe-only";
+ };
+ project_id?: string;
+ /**
+ * stable key for rendezvous placement (room, stream, session)
+ */
+ partition_key?: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * Where a workload was (or would be) placed and why: the chosen candidate, the reasons, and every candidate with its eligibility, estimated cost and latency (POST /api/v1/placement/explain; roadmap WS-Z9).
+ */
+export interface PlacementResult {
+ selected: string;
+ objective:
+ | "cheapest"
+ | "lowest-latency"
+ | "balanced"
+ | "private"
+ | "local-only"
+ | "first-party-only"
+ | "high-reliability"
+ | "correctness";
+ reasons?: string[];
+ candidates: {
+ id: string;
+ eligible: boolean;
+ excluded_because?: string;
+ estimated_cost_usd?: number;
+ estimated_latency_ms?: number;
+ score?: number;
+ reasons?: string[];
+ }[];
+ plan_epoch?: number;
+ decided_at: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * A signed, expiring route plan (roadmap WS-Z3 and WS-Z9): which carrier or pool serves each route. Every SDK and service caches the last valid plan and keeps working while the control plane is unreachable; unsigned or expired plans are refused.
+ */
+export interface PlacementPlan {
+ epoch: number;
+ issued_at: string;
+ expires_at: string;
+ issuer: string;
+ key_id: string;
+ routes: {
+ /**
+ * a route name: an event delivery class and scope, a workload kind, a service
+ */
+ route: string;
+ /**
+ * @minItems 1
+ */
+ targets: [
+ {
+ id: string;
+ weight: number;
+ },
+ ...{
+ id: string;
+ weight: number;
+ }[]
+ ];
+ draining?: string[];
+ since_epoch?: number;
+ }[];
+ /**
+ * Ed25519 over the canonical JSON of every other field, base64url
+ */
+ signature: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * One provider price with its free allowance, in the provider's real billing unit, with effective dates and where it was checked (roadmap WS-Z3 task 5). Changed only by review; never written by an AI on its own.
+ */
+export interface RateCard {
+ id: string;
+ provider: string;
+ adapter?: string;
+ /**
+ * e.g. queue-operation-64kb, request, gib-delivered, message, gb-month, class-a-op
+ */
+ metric: string;
+ unit_size: number;
+ unit_price_usd: number;
+ free_allowance: number;
+ reset_period: "day" | "month" | "none";
+ region?: string;
+ effective_from: string;
+ effective_until?: string;
+ source: string;
+ verified_at: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * A provider's usage against its allowances this billing period and its forecast, used to compute marginal cost (roadmap WS-Z3 task 5).
+ */
+export interface ProviderState {
+ provider: string;
+ period_start: string;
+ period_end: string;
+ /**
+ * used units per rate-card metric
+ */
+ usage: {
+ [k: string]: number | undefined;
+ };
+ /**
+ * projected units at period end
+ */
+ forecast?: {
+ [k: string]: number | undefined;
+ };
+ /**
+ * share of each free allowance kept for higher-priority classes
+ */
+ reserve?: {
+ [k: string]: number | undefined;
+ };
+ health?: "up" | "degraded" | "down";
+ updated_at: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * Cost and volume for a window, by carrier or provider, with the counterfactuals: what the same work would have cost all-local, all-provider and with the optimiser (roadmap WS-Z9 task 6).
+ */
+export interface CostSnapshot {
+ window_start: string;
+ window_end: string;
+ project_id?: string;
+ /**
+ * events, jobs, ai, media, …
+ */
+ scope: string;
+ by_target: {
+ id: string;
+ units: number;
+ cost_usd: number;
+ p50_ms?: number;
+ p95_ms?: number;
+ }[];
+ actual_usd: number;
+ /**
+ * e.g. all_local, all_provider, lowest_latency
+ */
+ counterfactual_usd?: {
+ [k: string]: number | undefined;
+ };
+}
+
+/** [email protected] (owner: network) */
+/**
+ * A node's reported capacity at one moment, sent by its Host agent (roadmap WS-Z9 task 1).
+ */
+export interface CapacitySnapshot {
+ node_id: string;
+ cell?: string;
+ capacity: {
+ cpu?: {
+ utilization?: number;
+ available_cores?: number;
+ };
+ memory?: {
+ utilization?: number;
+ available_mb?: number;
+ };
+ network?: {
+ ingress_mbps?: number;
+ egress_mbps?: number;
+ available_mbps?: number;
+ };
+ disk?: {
+ iops_available?: number;
+ scratch_gb?: number;
+ utilization?: number;
+ };
+ gpu?: {
+ type?: string;
+ vram_free_mb?: number;
+ utilization?: number;
+ };
+ /**
+ * free worker slots by kind (browser, ffmpeg, ai, …)
+ */
+ workers?: {
+ [k: string]: number | undefined;
+ };
+ /**
+ * queue depth and age by name
+ */
+ queues?: {
+ [k: string]:
+ | {
+ depth?: number;
+ oldest_ms?: number;
+ }
+ | undefined;
+ };
+ event_loop_lag_ms?: number;
+ };
+ services?: {
+ [k: string]:
+ | {
+ instances?: number;
+ active_requests?: number;
+ p50_ms?: number;
+ p95_ms?: number;
+ error_rate?: number;
+ }
+ | undefined;
+ };
+ reported_at: string;
+}
+
+/** [email protected] (owner: events) */
+/**
+ * How an event type is carried (roadmap WS-Z3 task 2): its delivery class sets the minimum semantics, which a publisher's intent may raise and never lower; ordering is per key; the route planner picks the carrier.
+ */
+export interface DeliveryPolicy {
+ class:
+ | "realtime_ephemeral"
+ | "interactive"
+ | "interactive_durable"
+ | "domain"
+ | "critical"
+ | "background"
+ | "bulk"
+ | "webhook";
+ durability: "none" | "optional" | "required";
+ delivery_semantics: "at_most_once" | "at_least_once";
+ ordering?: {
+ scope: string;
+ key: string;
+ };
+ latency?: {
+ target_p95_ms?: number;
+ maximum_p95_ms?: number;
+ };
+ retention?: {
+ hot?: string;
+ replay?: string;
+ archive?: string;
+ };
+ routing?: {
+ objective?: "latency_first" | "cheapest" | "balanced" | "correctness";
+ multi_provider?: boolean;
+ };
+ batching?: {
+ max_messages?: number;
+ max_delay_ms?: number;
+ };
+ residency?: {
+ inherit_project_region?: boolean;
+ region?: string;
+ };
+ max_payload_bytes?: number;
+}
+
+/** [email protected] (owner: contracts) */
+/**
+ * One resource of any service, as the resource index lists it (roadmap WS-Z7): every service answers GET /api/v1/resources with these, so OpenVibe.Services shows any resource without owning its data.
+ */
+export interface ResourceSummary {
+ id: string;
+ /**
+ * service.kind, e.g. watch.watch, actor.actor, media.object, events.subscription
+ */
+ kind: string;
+ service: string;
+ project_id?: string;
+ owner?: SubjectRef;
+ name?: string;
+ state: string;
+ created_at: string;
+ updated_at?: string;
+ /**
+ * cost units by name (WS-Z1)
+ */
+ usage?: {
+ [k: string]: number | undefined;
+ };
+ links?: {
+ self?: string;
+ console?: string;
+ docs?: string;
+ };
+}
+
+/** [email protected] (owner: contracts) */
+/**
+ * A page of the resource index (roadmap WS-Z7).
+ */
+export interface ResourceListResult {
+ resources: ResourceSummary[];
+ next_cursor: string | null;
+}
+
+/** [email protected] (owner: contracts) */
+/**
+ * One charge in weighted cost units (roadmap WS-Z1): which subject used what, reserved and committed or released, with an idempotency key so a retried charge counts once.
+ */
+export interface ResourceCost {
+ subject: SubjectRef;
+ project_id?: string;
+ unit:
+ | "browser-second"
+ | "ai-token"
+ | "ai-usd"
+ | "gpu-second"
+ | "video-minute"
+ | "bandwidth-byte"
+ | "storage-byte-day"
+ | "event"
+ | "watch-check"
+ | "bot-control-second"
+ | "job-run"
+ | "upload-byte"
+ | "download-byte";
+ amount: number;
+ state: "reserved" | "committed" | "released";
+ idempotency_key: string;
+ service: string;
+ at: string;
+}
+
+/** [email protected] (owner: network) */
+/**
+ * A sensitive action waiting for its owner's approval (roadmap WS-Z2): an agent (or app) asks to do something with an external side effect; the owner approves or denies from any OpenVibe site; the decision is an event.
+ */
+export interface ConfirmationRequest {
+ id: string;
+ owner: SubjectRef;
+ requested_by: SubjectRef;
+ capability: string;
+ summary: string;
+ details?: {
+ [k: string]: unknown | undefined;
+ };
+ resources?: EntityRef[];
+ state: "pending" | "approved" | "denied" | "expired" | "cancelled";
+ standing_rule?: "once" | "session" | "until" | "always";
+ expires_at: string;
+ decided_at?: string;
+ created_at: string;
+}
@@ -6,11 +6,11 @@
@@ -6,11 +6,11 @@
const crypto = require('crypto');
const crypto = require('crypto');
const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
const ALPHABET = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';
-const PREFIX = { user: 'usr', guest: 'gst', app: 'app', mod: 'mod', event: 'evt', media: 'med', project: 'prj' };
+const PREFIX = { user: 'usr', guest: 'gst', app: 'app', mod: 'mod', agent: 'agt', event: 'evt', media: 'med', project: 'prj', confirmation: 'cnf' };
const SLUG_TYPES = new Set(['service', 'system']);
const SLUG_TYPES = new Set(['service', 'system']);
const ULID_RE = /^[0-9A-HJKMNP-TV-Z]{26}$/;
const ULID_RE = /^[0-9A-HJKMNP-TV-Z]{26}$/;
const SLUG_RE = /^[a-z][a-z0-9-]{1,39}$/;
const SLUG_RE = /^[a-z][a-z0-9-]{1,39}$/;
-const SUBJECT_TYPES = ['user', 'guest', 'service', 'app', 'mod', 'system'];
+const SUBJECT_TYPES = ['user', 'guest', 'service', 'app', 'mod', 'agent', 'system'];
function ulid(now = Date.now()) {
function ulid(now = Date.now()) {
let time = '';
let time = '';
@@ -50,11 +50,11 @@ function formatSubject(ref) {
@@ -50,11 +50,11 @@ function formatSubject(ref) {
return `${ref.type}:${ref.id}`;
return `${ref.type}:${ref.id}`;
}
}
-/** Service-token `sub` claim: svc:<slug> | app:app_<ULID> | mod:mod_<ULID>. */
+/** Service-token `sub` claim: svc:<slug> | app:app_<ULID> | mod:mod_<ULID> | agent:agt_<ULID>. */
function principalSub(ref) {
function principalSub(ref) {
if (ref.type === 'service' && SLUG_RE.test(ref.id)) return `svc:${ref.id}`;
if (ref.type === 'service' && SLUG_RE.test(ref.id)) return `svc:${ref.id}`;
- if ((ref.type === 'app' || ref.type === 'mod') && isSubjectId(ref.type, ref.id)) return `${ref.type}:${ref.id}`;
- throw new TypeError('principals are service, app or mod subjects');
+ if ((ref.type === 'app' || ref.type === 'mod' || ref.type === 'agent') && isSubjectId(ref.type, ref.id)) return `${ref.type}:${ref.id}`;
+ throw new TypeError('principals are service, app, mod or agent subjects');
}
}
/** Transitional Media reference for today's rows (Wave 4 introduces med_ ids). */
/** Transitional Media reference for today's rows (Wave 4 introduces med_ ids). */
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "billing",
"owner": "billing",
"status": "active",
"status": "active",
"visibility": "internal",
"visibility": "internal",
+ "sensitive": true,
"description": "Request a cashout of creator payable into escrow (minimum and escrow period enforced by Billing), or recycle creator payable into the subject's own spendable credit. Bought credit is never withdrawable.",
"description": "Request a cashout of creator payable into escrow (minimum and escrow period enforced by Billing), or recycle creator payable into the subject's own spendable credit. Bought credit is never withdrawable.",
"permissions": [
"permissions": [
"billing:cashout"
"billing:cashout"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "billing",
"owner": "billing",
"status": "active",
"status": "active",
"visibility": "internal",
"visibility": "internal",
+ "sensitive": true,
"description": "Start a checkout: create a payment intent priced by Billing (never by the client) for a Vibes purchase or a channel subscription, and get the provider checkout URL or PowerChat app_ref. Also reads intents and captures approved PayPal orders.",
"description": "Start a checkout: create a payment intent priced by Billing (never by the client) for a Vibes purchase or a channel subscription, and get the provider checkout URL or PowerChat app_ref. Also reads intents and captures approved PayPal orders.",
"permissions": [
"permissions": [
"billing:intents"
"billing:intents"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "billing",
"owner": "billing",
"status": "active",
"status": "active",
"visibility": "internal",
"visibility": "internal",
+ "sensitive": true,
"description": "Start or renew a channel subscription paid from credit (the streamer share is credited on every period), and cancel at period end (Stripe subscriptions are cancelled at Stripe). Receipt-paid subscriptions through the API additionally need billing.ledger.admin.",
"description": "Start or renew a channel subscription paid from credit (the streamer share is credited on every period), and cancel at period end (Stripe subscriptions are cancelled at Stripe). Receipt-paid subscriptions through the API additionally need billing.ledger.admin.",
"permissions": [
"permissions": [
"billing:subscriptions"
"billing:subscriptions"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "billing",
"owner": "billing",
"status": "active",
"status": "active",
"visibility": "internal",
"visibility": "internal",
+ "sensitive": true,
"description": "Give CREDIT to someone (tip, donation, paid interaction): user_credit of the giver to creator_payable of the recipient. Self-dealing is refused by subject. Also refunds a credit-funded transfer back to its giver (e.g. a media request that never played). Idempotent by Idempotency-Key.",
"description": "Give CREDIT to someone (tip, donation, paid interaction): user_credit of the giver to creator_payable of the recipient. Self-dealing is refused by subject. Also refunds a credit-funded transfer back to its giver (e.g. a media request that never played). Idempotent by Idempotency-Key.",
"permissions": [
"permissions": [
"billing:transfer"
"billing:transfer"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "blog",
"owner": "blog",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Delete a post: readers get 410, Search a tombstone, the Community thread is hidden; immutable revisions are kept. Editors, owners, the author, and staff (moderation).",
"description": "Delete a post: readers get 410, Search a tombstone, the Community thread is hidden; immutable revisions are kept. Editors, owners, the author, and staff (moderation).",
"permissions": [
"permissions": [
"blog:write"
"blog:write"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "blog",
"owner": "blog",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Make a revision the published one (idempotent). AI-generated revisions are refused (409 post.review_required) until a person has recorded an approving review.",
"description": "Make a revision the published one (idempotent). AI-generated revisions are refused (409 post.review_required) until a person has recorded an approving review.",
"permissions": [
"permissions": [
"blog:write"
"blog:write"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "chat",
"owner": "chat",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Send a chat message to a room the actor is a member of (browsers over the chat socket; first-party services over Chat's service API).",
"description": "Send a chat message to a room the actor is a member of (browsers over the chat socket; first-party services over Chat's service API).",
"permissions": [
"permissions": [
"chat:write"
"chat:write"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "community",
"owner": "community",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Typed comment threads as a service: resolve the thread of any EntityRef (browsers are limited to an allowlist of types), and comment, vote and delete one's own comments as the acting subject (X-OV-Subject), or comment as origin \"ai\" (never attributed to a person, roadmap 33). Ownership and limits are checked by Community.",
"description": "Typed comment threads as a service: resolve the thread of any EntityRef (browsers are limited to an allowlist of types), and comment, vote and delete one's own comments as the acting subject (X-OV-Subject), or comment as origin \"ai\" (never attributed to a person, roadmap 33). Ownership and limits are checked by Community.",
"inputSchema": "community.comment-write-request@1",
"inputSchema": "community.comment-write-request@1",
"outputSchema": "community.comment-write-result@1",
"outputSchema": "community.comment-write-result@1",
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "community",
"owner": "community",
"status": "active",
"status": "active",
"visibility": "public",
"visibility": "public",
+ "sensitive": true,
"description": "Forum writes as a service: create threads and replies in a space, vote on threads, and edit or delete one's own posts, as the acting subject (X-OV-Subject) or as origin \"ai\" (no author, labelled as AI). Space visibility (public, members, staff), locks and limits are checked by Community.",
"description": "Forum writes as a service: create threads and replies in a space, vote on threads, and edit or delete one's own posts, as the acting subject (X-OV-Subject) or as origin \"ai\" (no author, labelled as AI). Space visibility (public, members, staff), locks and limits are checked by Community.",
"outputSchema": "community.post-write-result@1",
"outputSchema": "community.post-write-result@1",
"permissions": [
"permissions": [
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "media",
"owner": "media",
"status": "active",
"status": "active",
"visibility": "public",
"visibility": "public",
+ "sensitive": true,
"description": "Delete an object in a namespace (the delete verb of Media's namespace grants, WS-G task 2): a soft delete that keeps the bytes for the retention period, and the restore that undoes it within that period (checked against the namespace's quotas); refused while the object is under a retention hold. The same verb guards the v1 file delete (DELETE /api/v1/:app/files/:key). media.object.upload also grants it, for tokens issued before the verbs were split, unless the namespace's policy is strict_verbs.",
"description": "Delete an object in a namespace (the delete verb of Media's namespace grants, WS-G task 2): a soft delete that keeps the bytes for the retention period, and the restore that undoes it within that period (checked against the namespace's quotas); refused while the object is under a retention hold. The same verb guards the v1 file delete (DELETE /api/v1/:app/files/:key). media.object.upload also grants it, for tokens issued before the verbs were split, unless the namespace's policy is strict_verbs.",
"inputSchema": "common.no-body@1",
"inputSchema": "common.no-body@1",
"outputSchema": "media.object@1",
"outputSchema": "media.object@1",
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "network",
"owner": "network",
"status": "active",
"status": "active",
"visibility": "internal",
"visibility": "internal",
+ "sensitive": true,
"description": "Atomically move OpenCoins between two Network users. A token may only act for its own app_id.",
"description": "Atomically move OpenCoins between two Network users. A token may only act for its own app_id.",
"permissions": [
"permissions": [
"coins:write"
"coins:write"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "news",
"owner": "news",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Publish a revision (refused while it cites no source, rests on a source removed upstream or detached, or is AI-generated/AI-assisted without a person's approval), or unpublish a story. Publishing resolves the upstream flags the revision answers and publishes pending correction/update notes.",
"description": "Publish a revision (refused while it cites no source, rests on a source removed upstream or detached, or is AI-generated/AI-assisted without a person's approval), or unpublish a story. Publishing resolves the upstream flags the revision answers and publishes pending correction/update notes.",
"permissions": [
"permissions": [
"news:write"
"news:write"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "reviews",
"owner": "reviews",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Write, review (approve or reject), publish and unpublish summary revisions as the editor named in X-OV-Subject. Publishing refuses AI or system-prepared revisions without a person's approval and any revision with a point that cites no live signal of the entity.",
"description": "Write, review (approve or reject), publish and unpublish summary revisions as the editor named in X-OV-Subject. Publishing refuses AI or system-prepared revisions without a person's approval and any revision with a point that cites no live signal of the entity.",
"permissions": [
"permissions": [
"reviews:summary:publish"
"reviews:summary:publish"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "tips",
"owner": "tips",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Start a tip for a supporter (on_behalf SubjectRef): paid from the supporter's Billing credit (billing.transfer.create) or through a Billing checkout intent (billing.intent.create). Tips never prices money; Billing does. Idempotent by Idempotency-Key.",
"description": "Start a tip for a supporter (on_behalf SubjectRef): paid from the supporter's Billing credit (billing.transfer.create) or through a Billing checkout intent (billing.intent.create). Tips never prices money; Billing does. Idempotent by Idempotency-Key.",
"permissions": [
"permissions": [
"tips:checkout"
"tips:checkout"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "tips",
"owner": "tips",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Start a paid (highlighted) chat message for a supporter; the paid_messages row exists only after Billing settles it.",
"description": "Start a paid (highlighted) chat message for a supporter; the paid_messages row exists only after Billing settles it.",
"permissions": [
"permissions": [
"tips:checkout"
"tips:checkout"
@@ -4,6 +4,7 @@
@@ -4,6 +4,7 @@
"owner": "wiki",
"owner": "wiki",
"status": "active",
"status": "active",
"visibility": "first-party",
"visibility": "first-party",
+ "sensitive": true,
"description": "Publish a revision now or at a scheduled time (idempotent), unpublish a page, and record a person's review (approved or rejected) of an AI proposal or of an existing AI-assisted revision, on behalf of the editor named in X-OV-Subject. AI-generated revisions cannot be published without an approving review by a person.",
"description": "Publish a revision now or at a scheduled time (idempotent), unpublish a page, and record a person's review (approved or rejected) of an AI proposal or of an existing AI-assisted revision, on behalf of the editor named in X-OV-Subject. AI-generated revisions cannot be published without an approving review by a person.",
"permissions": [
"permissions": [
"wiki:revision:publish"
"wiki:revision:publish"
@@ -1,6 +1,6 @@
@@ -1,6 +1,6 @@
{
{
"name": "openvibe-contracts",
"name": "openvibe-contracts",
- "version": "0.76.0",
+ "version": "0.77.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",